LLVM Discussion Forums

How to convert LLVM IR to object code?


With MLIR one can lower a specification to LLVM IR level.

What I would like to do is to convert this code into object files (on various architectures and with various conventions, e.g. PIC), so as to include it into projects.

Is there a piece of documentation on how to do this?
I have found an option in mlir-cpu-runner that outputs object code, but:

  • It still requires the execution of code, which I don’t necessarily want as part of my compilation flow.
  • Generates an object file with options I don’t know how to manage on my MacBook 64-bit machine (trying to include it into projects gives the following error:
cpu-runner-example > gcc main.o externc.c -o main
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _main from main.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie

Thank you in advance,

Ok, I seem to have found a way, I leave it here to other people that may be interested.
Starting from a file main.mlir:

  1. Lower it to LLVM dialect level using mlir-opt mlir-opt --convert-std-to-llvm main.mlir -o main_llvm.mlir
  2. Convert the result to LLVM bytecode mlir-translate --mlir-to-llvmir main_llvm.mlir -o main_llvm.bc
  3. Use the LLVM static compiler to generate assembly code llc main_llvm.bc -o main_llvm.s
  4. Use the assembly file in the regular compilation flow gcc main_llvm.s externc.c -o main

3+4 can also be merged in one step:

llc main_llvm.bc -o main.llvm.o -filetype=obj

In general, I believe it is better to just use clang as a driver: opt and llc are LLVM testing tool.
Note also that the LLVM IR emitted from MLIR isn’t necessarily optimized, you may want to use the usual -O2/-O3 options.

In that case maybe clang should also accept the MLIR LLVM dialect?

That could be an option, but that’s a new dependency for clang and I’m not sure there is a real justification for this at the moment.
clang can emit LLVM IR from C/C++, and so it can resume its processing from LLVM IR. MLIR isn’t really a thing for clang, not more than RustIR or Swift SIL even though both of these can convert to LLVM IR.