gccassemblyclanglto

Getting assember output from GCC/Clang in LTO mode


Normally, one can get GCC's optimized assembler output from a source file using the -S flag in GCC and Clang, as in the following example.

gcc -O3 -S -c -o foo.s foo.c

But suppose I compile all of my source files using -O3 -flto to enable link-time whole-program optimizations and want to see the final compiler-generated optimized assembly for a function, and/or see where/how code gets inlined.

The result of compiling is a bunch of .o files which are really IR files disguised as object files, as expected. In linking an executable or shared library, these are then smushed together, optimized as a whole, and then compiled into the target binary.

But what if I want assembly output from this procedure? That is, the assembly source that results after link-time optimizations, during the compilation of IR to assembly, and before the actual assembly and linkage into the final executable.

I tried simply adding a -S flag to the link step, but that didn't really work.

I know disassembling the executable is possible, even interleaving with source, but sometimes it's nicer to look at actual compiler-generated assembly, especially with -fverbose-asm.


Solution

  • For GCC just add -save-temps to linker command:

    $ gcc -flto -save-temps ... *.o -o bin/libsortcheck.so
    $ ls -1
    ...
    libsortcheck.so.ltrans0.s
    

    For Clang the situation is more complicated. In case you use GNU ld (default or -fuse-ld=ld) or Gold linker (enabled via -fuse-ld=gold), you need to run with -Wl,-plugin-opt=emit-asm:

    $ clang tmp.c -flto -Wl,-plugin-opt=emit-asm -o tmp.s
    

    For newer (11+) versions of LLD linker (enabled via -fuse-ld=lld) you can generate asm with -Wl,--lto-emit-asm.