Bug with -O4

I'm not sure what I expect -O4 to do, but clang's response was a surprise.

$ cat test.c
int main( void ) { return 0; }
$ gcc test.c -O4
$ llvm-gcc-4.2 test.c -O4
$ clang test.c -O4
ld warning: in /var/folders/88/88AKX+F62RWmd++8ZOxBkU+++TI/-Tmp-/cc-NuzMfl.o, file is not of required architecture
Undefined symbols:
   "_main", referenced from:
       start in crt1.10.5.o
ld: symbol(s) not found

Robert P.

-O4 implies LTO; it's still somewhat experimental. I'm not sure what
the current status is, though.

-Eli

Hello, Robert

NuzMfl.o, file is not of required architecture
Undefined symbols:
"_main", referenced from:
start in crt1.10.5.o

O4 is for LTO. And you need linker support for it.

There may be rev-locks between the Mac OS X linker and the version of /Developer/usr/lib/libLTO.dylib (which is built out of the llvm source tree). Also you need clang installed in /Developer/usr/bin (not in a local build tree) so that it uses /Developer/usr/bin/ld for linking and doesn't back to /usr/bin/ld, which won't find ../lib/libLTO.dylib

So I'd suggest first installing clang in /Developer/usr/bin and clang-cc in /Developer/usr/libexec, and see if that just works. If not, try installing libLTO.dylib to /Developer/usr/lib (and keep a backup). If that doesn't work, you may need to get more creative...

Shantonu

I'm not sure what I expect -O4 to do, but clang's response was a
surprise.

As others have mentioned, -O4 with clang and llvm-gcc enables link-time-optimization, which GCC doesn't support. With GCC -O3 and -O4 (and -O99) are the same.

What OS are you developing on? If you're on the mac, or if you use the new Binutils "gold" linker for linux, you might have a solution. Otherwise, the fix is "don't do that".

-Chris

Chris Lattner <clattner@...> writes:

What OS are you developing on? If you're on the mac, or if you use
the new Binutils "gold" linker for linux, you might have a solution.
Otherwise, the fix is "don't do that".

Why llvm-ld isn't enough ?

After some basic test caaling llvm-ld (instead of gcc) with the transformation
(sed -e "s/-Wl,/-Xlinker=/g" -e "s/-l/-l=/g") seems to produce working output.

Why clang can't be a wrapper around llvm-ld ?

Matthieu

Shantonu Sen wrote:

$ cat test.c
int main( void ) { return 0; }

$ clang test.c -O4
ld warning: in /var/folders/88/88AKX+F62RWmd++8ZOxBkU+++TI/-Tmp-/cc-
NuzMfl.o, file is not of required architecture
Undefined symbols:
"_main", referenced from:
     start in crt1.10.5.o
ld: symbol(s) not found

There may be rev-locks between the Mac OS X linker and the version of /Developer/usr/lib/libLTO.dylib (which is built out of the llvm source tree). Also you need clang installed in /Developer/usr/bin (not in a local build tree) so that it uses /Developer/usr/bin/ld for linking and doesn't back to /usr/bin/ld, which won't find ../lib/libLTO.dylib

So I'd suggest first installing clang in /Developer/usr/bin and clang-cc in /Developer/usr/libexec, and see if that just works.

No.

If not, try installing libLTO.dylib to /Developer/usr/lib (and keep a backup).

Yes! Thanks.

Robert P.

Chris Lattner <clattner@…> writes:

What OS are you developing on? If you’re on the mac, or if you use
the new Binutils “gold” linker for linux, you might have a solution.
Otherwise, the fix is “don’t do that”.

Why llvm-ld isn’t enough ?

For many uses, it would be…

After some basic test caaling llvm-ld (instead of gcc) with the transformation
(sed -e “s/-Wl,/-Xlinker=/g” -e “s/-l/-l=/g”) seems to produce working output.

Why clang can’t be a wrapper around llvm-ld ?

Primarily because no one has written the code yet. Its also worth pointing out that llvm-ld by itself isn’t enough to emulate the features of full LTO support, for example on Darwin one can mix Mach-O objects and LLVM bit-code files with ar, ld, etc. and things should just work. Using llvm-ld would handle some cases, but not all.

The right long term solution is to find a way to get real LTO support on other platforms, this work is progressing but I have no idea what kind of time frame to expect. In the short term adding llvm-ld support in the clang driver would at least allow some very useful things to work (like passing clang with -emit-llvm to configure, currently this will normally fail because clang with -emit-llvm can’t generate the test executables).

If you would like to see this work, please file a bug with test cases you care about. And or a patch! :slight_smile:

  • Daniel