Should I worry about test failures in a release?

Hi all,

I checked out everything mentioned in GettingStarted at tags/RELEASE_370/final and ran `make -j4 check-all`.
I got three test failures:

     libc++abi :: catch_array_01.pass.cpp
     libc++abi :: catch_function_01.pass.cpp
     libc++abi :: catch_member_function_pointer_01.pass.cpp

Should I worry?

Here are the failures as reported, with the LLVM source directory replaced with ... for clarity:

catch_array_01.pass.cpp.exe: .../projects/libcxxabi/test/catch_array_01.pass.cpp:25: int main(): Assertion `false' failed.

catch_function_01.pass.cpp.exe: .../projects/libcxxabi/test/catch_function_01.pass.cpp:34: int main(): Assertion `false' failed.

catch_member_function_pointer_01.pass.cpp.exe: .../projects/libcxxabi/test/catch_member_function_pointer_01.pass.cpp:44: void test1(): Assertion `false' failed.

Regards,
Jo

Oh nevermind.
Since I plan to use LLVM as a backend, not hack on it, I'm not going to get much joy out of TRUNK, so I reverted to 3.7.
Which led me to the realization that GettingStarted does not mention libcxxabi.

So, I guess I shouldn't worry about test failures in libcxxabi :slight_smile:
Sorry for the noise.

Regards,
Jo

That depends on what you use. If you use libc++, then you need to
worry about those tests.

Releases are done with the components that are known to work on the
platform. For example, 3.7 was the first that I bundled the sanitizers
for AArch64, since it's the first that we can claim support. I plan to
release libc++ too, once it's stable, even if the example
documentation doesn't explicitly mention it, the test-release.sh
script can build and test it.

Regarding trunk vs release, it depends on what you need. If your
project will use LLVM for a long time (ie. if this is a serious long
term project), then you should follow trunk as closely as possible. If
this is just a trial project, then following a release is better,
because you can focus on your project only and you'll always be able
to build it targeting a specific release in the future, not having to
track which commits off trunk were good.

cheers,
--renato

Since I plan to use LLVM as a backend, not hack on it, I'm not going to get
much joy out of TRUNK, so I reverted to 3.7.
Which led me to the realization that GettingStarted does not mention
libcxxabi.

That depends on what you use. If you use libc++, then you need to
worry about those tests.

Ah. I guess I'll want that once I have a working toolchain.

Regarding trunk vs release, it depends on what you need. If your
project will use LLVM for a long time (ie. if this is a serious long
term project),

It's going to be a compiler project. The usual setup: C++ for scanner/parser/AST/diagnostics, LLVM for the backend. Self-hosting comiler may happen later, and will continue to use LLVM.
So my plans for using LLVM are long-term, and at least mid-term for Clang.

> then you should follow trunk as closely as possible. If

this is just a trial project, then following a release is better,
because you can focus on your project only and you'll always be able
to build it targeting a specific release in the future, not having to
track which commits off trunk were good.

I've been planning to switch to a new release whenever it's out.
What are the advantages of following trunk?

Regards,
Jo

Some people prefer following releases and having a higher cost when
migrating, other people prefer to spread the cost over many months,
but you'll have to resolve conflicts most of the time you re-base your
project regardless of what you choose.

If you stick to a release...

Pros:
* ABI stability
* Known functionality (ie. no experimental stuff)
* Re-base can be done separately, and merged once stable
Cons:
* Known problems are less likely to be fixed upstream (1)
* Larger re-base periods, may invalidate a lot of your bridge code

If you stick to trunk...

Pros:
* Faster re-base periods
* Bugs are more likely to be fixed quickly
* New features, target support will come earlier
* You can influence/propose/submit changes upstream
Cons:
* Unpredictable re-base. Sometimes, a re-base can destroy a lot of stuff.
* You'll have to track buildbots to make sure all targets are green
on the revision you want to pull
* You won't have the additional validation people do on releases
(larger code-bases, benchmarks, etc).
* Re-bases are better done as a "stop the press" moment in the
project history, may delay other tasks

Ultimately, it depends on how you and your team work, and how you
expect the software you're building to evolve. The vast majority of
people stick to trunk.

cheers,
--renato

(1) The community is very focused on trunk, so problems fixed on trunk
may not be easily back-ported. You may want to do the back-port
yourself, but that still doesn't mean people will accept it on the
release branch, for example, due to potential instability concerns.
Releases are more "stable points in time", than proper products.

Oh... why do I need to rebase?
I don't have the manpower or C++ expertise to hack on LLVM itself, I've been planning to just use it. Since I'm just doing a proof of concept, I (hopefully) won't have to use any of the more experimental stuff.

A different but related questons: Are minor releases of LLVM backwards-compatible? Bitcode compatibility would be particularly interesting - can I assume that the LLVM toolchain is able to work with bitcode generated by earlier versions of the toolchain?

Regards,
Jo

Oh... why do I need to rebase?

If your project is a product that wants to benefit from the advances
of LLVM over the years, you'll have to update the code to the newer
versions some time. Moreover, if you do find a bug, and it's in an old
version, you won't have the same response times than if it's in trunk.
Very likely, you'll get no response at all. As I said earlier, our
releases are "stable points in time", not final products that have
support contracts.

I don't have the manpower or C++ expertise to hack on LLVM itself, I've been
planning to just use it. Since I'm just doing a proof of concept, I
(hopefully) won't have to use any of the more experimental stuff.

Right, so sticking to the 3.7.0 release is probably your best bet.
It's feature complete on most targets (x86, ARM, MIPS, PPC), 32-bit
and 64-bit. You should be fine with that for a while.

A different but related questons: Are minor releases of LLVM
backwards-compatible?

Both ABI and API compatible. You should be safe migrating from 3.7.0
to .1 or .2 without a single change on your part. If there are any,
please report as a bug.

Bitcode compatibility would be particularly
interesting - can I assume that the LLVM toolchain is able to work with
bitcode generated by earlier versions of the toolchain?

Not major versions. Those change considerably over the years, and
that's why people keep tracking trunk so closely. Then again, most
people that track trunk have teams big enough to cope with it. Those
that don't, generally prefer to stick to specific versions and hope
that the change log is enough to help them migrate.

cheers,
--renato

Thanks, that answered all questions.

One last detail: What's a major version? 3.8 or 4.0?

Regards,
Jo

Going from 3.6 to 3.7 would almost certainly break binary compatibility between .bc files. You may be able to get away with it for some particular use-cases (but in that case, it’s by luck, not by design).

I’m not enough “part of the community” to say if there are rules about what can and can’t change between certain levels of releases, but my general understanding is that “as long as the change is good, it goes in” [aside from changes for example between 3.7.0 and 3.7.1, where there is a guarantee that, modulo actual bugs or undefined behaviour, the two releases are compatible].

I try to track “trunk” by updating every two-four weeks, and once every few of those updates, I need to make changes to my compiler project. Of course, how many and what kind of changes will depend on what features of LLVM your project is using. There are some parts of LLVM that are very stable, there are others with more changes - but all appear to potentially change from my experience.

The “not guarantee for compatibility between releases” is a good and a bad thing, where the bad part is the obvious extra work when something changes, and the good part is that “things can be changed”. I’ve worked on/with projects that have very strict rules of compatibility, where changes to ABI and API are very difficult to make and everything has to be motivated, debated, change-controlled and finally agreed with “customers” [in quotes as it’s often some group within the overall company, but outside your own group]. This approach makes for slow and often complex changes to “work around” the fact that you can’t actually make the change you want. It’s a right pain to work with such systems too, even if it may seem like a good idea at times. Most importantly, it is often harming innovation and improvements, because of the bureaucracy involved in making changes.

3.8, 3.9, 4.0 are all "major" versions in my previous emails. ie,
that's what I meant. :slight_smile:

I'm not good in keeping track of diverse nomenclatures, so that may
not be canon.

cheers,
-renato

This is more pertinent to low-level *stable* libraries, where
innovation happens elsewhere. :slight_smile:

In LLVM we worry more about some parts (like the C-API) than others
(like the pass manager), depending on how much *external* code is
likely to change.

But IR compatibility is one of the most public APIs we have and that
changes considerably between releases. AFAIK, there isn't any concern
in keeping it backwards compatible between all 3.x releases. That
surprises a lot of people. :slight_smile:

Maybe, by 4.x we'll have more stability and new IR features could be a
reason to move to 5.x. But we've been there before, and have chosen
not to do it that way.

cheers,
--renato

No problem with that, nomenclature varies across projects anyway :slight_smile:

Thanks for the info. I now know what to watch out for.

Regards,
Jo

Going from 3.6 to 3.7 would almost certainly break binary compatibility
between .bc files. You may be able to get away with it for some particular
use-cases (but in that case, it's by luck, not by design).

I'm not enough "part of the community" to say if there are rules about what
can and can't change between certain levels of releases, but my general
understanding is that "as long as the change is good, it goes in" [aside
from changes for example between 3.7.0 and 3.7.1, where there is a
guarantee that, modulo actual bugs or undefined behaviour, the two releases
are compatible].

I try to track "trunk" by updating every two-four weeks, and once every few
of those updates, I need to make changes to my compiler project. Of course,
how many and what kind of changes will depend on what features of LLVM your
project is using. There are some parts of LLVM that are very stable, there
are others with more changes - but all appear to potentially change from my
experience.

Thanks, that's very useful feedback.

The "not guarantee for compatibility between releases" is a good and a bad
thing, where the bad part is the obvious extra work when something changes,
and the good part is that "things can be changed". I've worked on/with
projects that have very strict rules of compatibility, where changes to ABI
and API are very difficult to make and everything has to be motivated,
debated, change-controlled and finally agreed with "customers" [in quotes
as it's often some group within the overall company, but outside your own
group]. This approach makes for slow and often complex changes to "work
around" the fact that you can't actually make the change you want. It's a
right pain to work with such systems too, even if it may seem like a good
idea at times. Most importantly, it is often harming innovation and
improvements, because of the bureaucracy involved in making changes.

Heh, I know. One style is a PITA for the infrastructure devs, the other is a PITA for the infrastructure users, and then we have a spectrum in-between.
I have yet to see a working solution for that.

Regards,
Jo

Bitcode compatibility would be particularly
interesting - can I assume that the LLVM toolchain is able to work with
bitcode generated by earlier versions of the toolchain?

Not major versions.

..

3.8, 3.9, 4.0 are all "major" versions in my previous emails. ie,
that's what I meant. :slight_smile:

According to http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility , "The bitcode format produced by a X.Y release will be readable by all following X.Z releases and the (X+1).0 release."

From this I concluded that bitcode produced for 3.1 should be readable by every 3.x release and by 4.0.

Jonas

And outlook still strips llvm-dev sometimes when replying-to-all (didn’t we already get rid of that problem?)

Argh.

As far as I know, the consensus was that all 3.x versions should retain
backward compatibility for bitcode.

Emphasis on "should". :slight_smile:

I don't think we have enough tests to make sure we don't break that
promise, precisely because it's important, but not crucial.

So, 3.7 should be able to consume bitcode (but not text IR) produced by any
earlier 3.x. When 4.0 rolls around, all bets are off.

And not the other way around, either.

Note that “consume” here is a not as strong a guarantee as it may sound,
since metadata may be stripped off. Debug metadata almost certainly will be.

Yup.

--renato

There's a bunch of tests that make sure at least basic IR constructs from LLVM 3.2 are still handled correctly.
In addition, this is something that we *used* to test internally, rather more thoroughly. I'm not sure whether it's still being tested by anyone, unfortunately.

In any case, if this promise gets broken, it's a bug, not a feature. :slight_smile:

Indeed!

--renato

Sadly not. I’ve sent myself a large number of emails via hand-typed SMTP to figure out the cause of the problem and IIRC it’s a bug in the order changes are made to the recipient list. It seems Outlook builds a recipient list, removes duplicates, and then swaps the From for the Reply-To. One copy of llvm-dev (from the CC) gets lost in the process. Putting llvm-dev in ‘To’ rather than ‘CC’ seems to work around it.