llvm-toolchain-3.8 on lower arm targets

Hi,

peter green wrote:

If you don't need/want the various Sanitizer runtimes (e.g. you don't
support sanitizers or already have versions provided with GCC) then
it's as easy as not downloading compiler-rt or removing it from the
projects/ directory before running CMake. The build should carry on
quite happily without it.

If you do need the sanitizers from compiler-rt, you can disable the
bits that are causing problems right now with "cmake
-DCOMPILER_RT_BUILD_BUILTINS=OFF<other options>". Of course, the
sanitizers themselves may suffer from similar issues -- you just won't
know until you get there.
Thanks, -DCOMPILER_RT_BUILD_BUILTINS=OFF did the trick and I got a
successful build for raspbian that passed my armv7 contamination
checker script (which is not 100% foolproof but it's the best we have)
and uploaded it to raspbian stretch.

-DCOMPILER_RT_BUILD_BUILTINS=OFF didn't work on Debian:

https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-3.8&arch=armel&ver=1%3A3.8.1-12&stamp=1473396917

The build fails with:

cd /«PKGBUILDDIR»/build-llvm/lib/Support && /usr/bin/g++-6 -D_GNU_SOURCE
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-I/«PKGBUILDDIR»/build-llvm/lib/Support -I/«PKGBUILDDIR»/lib/Support
-I/«PKGBUILDDIR»/build-llvm/include -I/«PKGBUILDDIR»/include -std=c++0x
-gsplit-dwarf -fPIC -fvisibility-inlines-hidden -Wall -W -Wno-unused-parameter
-Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic
-Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment
-std=c++11 -ffunction-sections -fdata-sections -O2 -g -DNDEBUG
-fno-exceptions -o CMakeFiles/LLVMSupport.dir/ThreadPool.cpp.o -c
/«PKGBUILDDIR»/lib/Support/ThreadPool.cpp
In file included from /«PKGBUILDDIR»/lib/Support/ThreadPool.cpp:14:0:
/«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h: In member function
'std::shared_future<void> llvm::ThreadPool::async(Function&&, Args&& ...)':
/«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h:78:77: error: return type
'class std::shared_future<void>' is incomplete
   inline std::shared_future<VoidTy> async(Function &&F, Args &&... ArgList) {
                                                                             ^

Any idea about this failure?

For the Debian armel porters, we're switching to LLVM 3.8, so this failure
(which happens on 3.8, 3.9 and llvm-toolchain-snapshot) is likely going to cause
some package removals on armel as we try to get rid of older LLVM versions.
Helping fixing this issue would be appreciated to prevent that.

Thanks,
Emilio

Hi Emilio,

In file included from /«PKGBUILDDIR»/lib/Support/ThreadPool.cpp:14:0:
/«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h: In member function
'std::shared_future<void> llvm::ThreadPool::async(Function&&, Args&& ...)':
/«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h:78:77: error: return type
'class std::shared_future<void>' is incomplete
   inline std::shared_future<VoidTy> async(Function &&F, Args &&... ArgList) {
                                                                             ^

Any idea about this failure?

For the Debian armel porters, we're switching to LLVM 3.8, so this failure
(which happens on 3.8, 3.9 and llvm-toolchain-snapshot) is likely going to cause
some package removals on armel as we try to get rid of older LLVM versions.
Helping fixing this issue would be appreciated to prevent that.

This looks like the kind of failure you get when your host toolchain
doesn't support C++11 properly (specifically lock-free atomics in this
case). When I've seen it before GCC was defaulting to a CPU that's
too old to do atomics properly, and that configuration is very
unlikely to be supported by LLVM ever (any more).

It looks like Debian may only support ARMv7 for armel anyway, in which
case you should add something like "-march=armv7-a" to your C flags
(-DCMAKE_C_FLAGS=-march=armv7-a and possibly
-DCMAKE_CXX_FLAGS=-march=armv7-a too).

The earliest that you could possibly go and hope for it to work would
be "armv6t2".

Cheers.

Tim.

Hi Tim,

Hi Emilio,

In file included from /«PKGBUILDDIR»/lib/Support/ThreadPool.cpp:14:0:
/«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h: In member function
'std::shared_future<void> llvm::ThreadPool::async(Function&&, Args&& ...)':
/«PKGBUILDDIR»/include/llvm/Support/ThreadPool.h:78:77: error: return type
'class std::shared_future<void>' is incomplete
   inline std::shared_future<VoidTy> async(Function &&F, Args &&... ArgList) {
                                                                             ^

Any idea about this failure?

For the Debian armel porters, we're switching to LLVM 3.8, so this failure
(which happens on 3.8, 3.9 and llvm-toolchain-snapshot) is likely going to cause
some package removals on armel as we try to get rid of older LLVM versions.
Helping fixing this issue would be appreciated to prevent that.

This looks like the kind of failure you get when your host toolchain
doesn't support C++11 properly (specifically lock-free atomics in this
case). When I've seen it before GCC was defaulting to a CPU that's
too old to do atomics properly,

Oh, yeah. The std::shared_future reference ringed a bell in that direction. This
is https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=727621 FWIW.

and that configuration is very
unlikely to be supported by LLVM ever (any more).

Understandable.

It looks like Debian may only support ARMv7 for armel anyway, in which
case you should add something like "-march=armv7-a" to your C flags
(-DCMAKE_C_FLAGS=-march=armv7-a and possibly
-DCMAKE_CXX_FLAGS=-march=armv7-a too).

No, unfortunately armel on Debian targets armv4t, so we're out of luck. See the
above bug report. armhf targets armv7 IIRC, so that's why we don't hit this
issue there. Raspbian armel targets armv6, so that's why they are fine.

I guess this means no more LLVM on armel for now. For the next Debian release
(Buster) we'll have to see if we bump the minimum requirements on armel, or if
we drop the architecture entirely (at least as an official port).

Cheers,
Emilio

This seems bogus.

C++11 allows atomic variables to be implemented using mutexes if the CPU
doesn't support atomic operations on a given data type in some other way.

If you don't call atomic_is_lock_free(&var) then everything should work
correctly, albeit perhaps more slowly than you might like.

It seems to me that atomic_is_lock_free() (or precomputed shortcuts such as
ATOMIC_INT_LOCK_FREE) is there to enable you the possibility to use a
different algorithm (if one is available), not to throw up your hands and
say you don't support that architecture at all!

If it's the standard library going out of its way to
check ATOMIC_INT_LOCK_FREE and then throwing up its hands and giving up
then I'd say that's a bug. Simply taking out that check should produce
working, correct code on anything that supports mutexes at all.