Getting LLVM IR from clang

How do I get the LLVM IR produced by clang? I know that -emit-llvm
produces IR but it seems to be after processing by LLVM (things are
optimized out, for example). Is there an "official" way to get the IR
coming right out of clang's codegen? I can do a hack with -mllvm
-print-before-all but that's icky.

Thanks!

                          -David

Hi David,

There are at least two robust ways to get the Bitcode/IR:

1. LTO. You can enable link-time optimization by adding -flto compiler flags, in the end all object files (*.o) will in fact be bitcode files. I.e.:

    > file gmock.dir/gmock-gtest-all.cc.o
    gmock.dir/gmock-gtest-all.cc.o: LLVM bitcode, wrapper x86_6

2. Embedded bitcode. Clang 3.9 and higher has an option -fembed-bitcode. When enabled, the resulting executable will contain additional section containing bitcode.
You can use this great tool[1] to extract the bitcode from an executable.

Both approaches produce bitcode (binary format), if you need IR (human-readable format), then you can post-process the bitcode by running llvm-dis against each bitcode file.

I hope it helps.

[1] https://github.com/JDevlieghere/LibEBC

Collecting IR from LTO probably isn’t what’s desired - since that’ll be already optimized in the individual compilation stage (to then be further optimized in the LTO stage).

As others mentioned, -Xclang -disable-llvm-optzns. Also note that changing optimization flags (-O0 versus -O3, etc) will change the IR that’s generated - most notably, at -O0, all the functions in the IR will be attributed with ‘nodebug’, so running this IR through opt -O3 will be basically a no-op. This catches folks by surprise sometimes. So use the -O flag you want, but pass disable-llvm-optzns to get that ‘optimized’ IR (as far as Clang’s codegen is concerned) prior to the LLVM optimizations running on it.

most notably, at -O0, all the functions in the IR will be attributed with ‘nodebug’,

Dave means ‘optnone’ here. This prevents (most) optimization.

–paulr

Yup - thanks for the correction!

Collecting IR from LTO probably isn't what's desired - since that'll be already optimized in the individual compilation stage (to then be further optimized in the LTO stage).

Hm, I'm a bit surprised now. So even if I call "clang -flto -O0 -c main.c" the actual bitcode will be optimized? Then which optimizations will be applied?
Does it also affect -fembed-bitcode?

-O0 -flto would still run the always-inliner, for example (& would skip any frontend (clang IR generation-level) optimizations you might be interested in), and would add the “optnone” attribute to the functions which may not be what you want if you’re trying to investigate the -O3 pipeline