Page 2 of 2

Re: clang cross compiler

Posted: Sun Oct 07, 2012 7:37 am
by OSwhatever
One thing I noticed is that architecture specific functions like divisions on ARM (like __aeabi_uidiv) are taken from libgcc and not compiler-rt. __aeabi_uidiv seems to be included in libLLVMARMCodeGen.a but the object files themselves inside that library seems to be of unrecognized type for binutils. -lLLVMARMCodeGen does not make any difference. If you are using the binutils linker "ld", are you then forced to use libgcc or can you in some way get the compiler-rt equivalents to be used instead?

Re: clang cross compiler

Posted: Mon Oct 08, 2012 8:31 am
by JamesM
Hi,
OSwhatever wrote:One thing I noticed is that architecture specific functions like divisions on ARM (like __aeabi_uidiv) are taken from libgcc and not compiler-rt. __aeabi_uidiv seems to be included in libLLVMARMCodeGen.a but the object files themselves inside that library seems to be of unrecognized type for binutils. -lLLVMARMCodeGen does not make any difference. If you are using the binutils linker "ld", are you then forced to use libgcc or can you in some way get the compiler-rt equivalents to be used instead?
I can probably help here. I did a lot of work on the Clang driver, and ensure LLVM works on ARM for a living.

I'm confused as to exactly what your setup is - are you native-compiling LLVM on an ARM board? or are you using LLVM compiled/running on an x86 host to generate binaries for an ARM board?

If the latter, you can't link libLLVMARMCodeGen.a with it because it'll be compiled for x86, not ARM!

Clang defaults to using GCC to assemble and link for ARM. You can make it assemble itself by using the flag "-integrated-as" (this is a feature that is going to be enabled by default on the next release, and is enabled by default for iOS only as of 3.1). Linking is a dark art because it is tightly coupled with GCC's internals and binutils. Both these projects co-ordinate to ensure GCC works, but noone cares about LLVM :( so we have to emulate their behaviour, and that often goes awry because it's just as complex as you imagine.

For that reason Clang on ARM-linux default to delegating linking to GCC's compiler driver, in the hopes that it knows where its libraries and crt* are.

If you could explain your situation a bit more, I could help more :)

James

Re: clang cross compiler

Posted: Mon Oct 08, 2012 12:12 pm
by OSwhatever
JamesM wrote:Hi,

I can probably help here. I did a lot of work on the Clang driver, and ensure LLVM works on ARM for a living.

I'm confused as to exactly what your setup is - are you native-compiling LLVM on an ARM board? or are you using LLVM compiled/running on an x86 host to generate binaries for an ARM board?

If the latter, you can't link libLLVMARMCodeGen.a with it because it'll be compiled for x86, not ARM!

Clang defaults to using GCC to assemble and link for ARM. You can make it assemble itself by using the flag "-integrated-as" (this is a feature that is going to be enabled by default on the next release, and is enabled by default for iOS only as of 3.1). Linking is a dark art because it is tightly coupled with GCC's internals and binutils. Both these projects co-ordinate to ensure GCC works, but noone cares about LLVM :( so we have to emulate their behaviour, and that often goes awry because it's just as complex as you imagine.

For that reason Clang on ARM-linux default to delegating linking to GCC's compiler driver, in the hopes that it knows where its libraries and crt* are.

If you could explain your situation a bit more, I could help more :)

James
I use the Windows binary provided by the LLVM project release download page cross compiling to ARM. Also tried a mingw compiled version from the sources but that was essentially the same that I downloaded, but the downloaded version is faster for some reason, maybe because everything is statically linked in the version from LLVM.

Adding "-integrated-as" had this effect:

Code: Select all

Unimplemented
UNREACHABLE executed at /Users/asl/Projects/llvm/release/3.1/src/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp:167!


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
clang: error: clang frontend command failed with exit code 3 (use -v to see invocation)
cs-make: *** [Obj/KernelStart.o] Error 3
That the linker takes run-time functions from libgcc rather than the LLVM compiler RT is not a catastrophy right now as it doesn't break my build but it puzzled me why it decided to do that. I guess the plan is that ARM run-time functions are supposed to come from compiler RT though, at least in the future.

Re: clang cross compiler

Posted: Mon Oct 08, 2012 1:07 pm
by JamesM
What version of LLVM/Clang were you using to provoke that error? if it's anything older than 3.1 I wouldn't expect it to work - even 3.1 had quite a few issues. Trunk is where it's at for ARM. 3.2 should be much better. If you can provoke that error with trunk, please let me know and I'll get to fixing it! :)

So the linker will use whatever runtime library it is presented with - you need to use a command-line flag to enable compiler-rt. I forget what that is at the moment, but it may well be that compiler-rt isn't stable for ARM yet. I wouldn't be that surprised.

Re: clang cross compiler

Posted: Mon Oct 08, 2012 1:18 pm
by OSwhatever
JamesM wrote:What version of LLVM/Clang were you using to provoke that error? if it's anything older than 3.1 I wouldn't expect it to work - even 3.1 had quite a few issues. Trunk is where it's at for ARM. 3.2 should be much better. If you can provoke that error with trunk, please let me know and I'll get to fixing it! :)

So the linker will use whatever runtime library it is presented with - you need to use a command-line flag to enable compiler-rt. I forget what that is at the moment, but it may well be that compiler-rt isn't stable for ARM yet. I wouldn't be that surprised.

Code: Select all

clang version 3.1 (branches/release_31)
Target: i686-pc-mingw32
Thread model: posix
I'm using LLVM 3.1.

I will try with trunk and come back with the results.

Re: clang cross compiler

Posted: Mon Oct 08, 2012 4:31 pm
by OSwhatever
I compiled the trunk and then compiled my build. Now the error is gone when using "-integrated-as" and it can compile all files as before. However at link stage if I omit -lgcc, the linker will complain "undefined reference to `__aeabi_uidiv'". It makes sense as gcc ld has no idea where to get __aeabi_uidiv when libgcc is gone and there is no replacement. Where is the replacement?

Re: clang cross compiler

Posted: Mon Oct 08, 2012 7:44 pm
by OSwhatever
Further more, the ARM code generation for ARMv7 is kind of strange.

this:

Code: Select all

MyClass::MyClass()
{
	v1 = 0; // v1, v2, v3 are unsigned int.
	v2 = 0;
	v3 = 0;
}
becomes:

Code: Select all

00000000 <_ZN10MyClassC1Ev>:
   0:   f2c00010        vmov.i32        d16, #0 ; 0x00000000
   4:   e3a01000        mov     r1, #0
   8:   e5801008        str     r1, [r0, #8]
   c:   edc00b00        vstr    d16, [r0]
  10:   e12fff1e        bx      lr

Is this come kind of optimization, inserting Neon/Vfp code? Can you turn it off?

Re: clang cross compiler

Posted: Tue Oct 09, 2012 5:18 am
by dozniak
I think you should be able to disable NEON generation by using -arch armv7 instead of (default?) -arch armv7a.

Re: clang cross compiler

Posted: Tue Oct 09, 2012 5:29 am
by Owen
dozniak wrote:I think you should be able to disable NEON generation by using -arch armv7 instead of (default?) -arch armv7a.
There is no arch "armv7". Only armv7a, armv7r and armv7m, all of which refer to different architecture classes.

You disable NEON & VFP use by disabling NEON & VFP use...

Re: clang cross compiler

Posted: Tue Oct 09, 2012 5:59 am
by OSwhatever
dozniak wrote:I think you should be able to disable NEON generation by using -arch armv7 instead of (default?) -arch armv7a.
According to the osdev wiki about llvm, I used this

Code: Select all

-target armv7--eabi -mcpu=cortex-a9 -mthumb
which included neon instructions among the thumb instructions.

Now I tried with this.

Code: Select all

-march=armv7-a -mfloat-abi=soft -mthumb
and it compiled without neon instructions. The flag "-mfloat-abi=soft" was the one that removed this.
I previously tried with

Code: Select all

-mattr=-neon,-vfp3,-vfp2
but that didn't make any difference. A little bit confused in the option jungle.

Re: clang cross compiler

Posted: Tue Oct 09, 2012 12:39 pm
by JamesM
Why do you want to disable NEON instructions?

Re: clang cross compiler

Posted: Tue Oct 09, 2012 1:20 pm
by OSwhatever
JamesM wrote:Why do you want to disable NEON instructions?
A bug in gcc-as prevented me from enable the neon instructions and then I never bothered with it since I didn't need for the time being. Right now there is no support for neon in the task switcher, that will be added later. While neon optimization might be a good thing, there are places where you want be able to control code generation, early boot for example if neon instructions aren't enabled. It's good that this has been brought to my table though so that neon support can be implemented.