LLVM IR clang -O1 -S -emit-llvm
define i32 @f(i32 %0, i32 %1) {
%3 = add nsw i32 %1, %0
ret i32 %3
}- Every value carries a type, i32.
- %0, %1 and %3 are virtual registers. There are as many as needed, and each is assigned once.
- nsw means the signed add will not overflow. Optimization passes rely on facts like this.
- Not tied to a CPU. The same IR goes to the x86 backend and the ARM backend.
x86-64 assembly clang -O1 -S -masm=intel
f:
lea eax, [rdi + rsi]
ret
- No types. eax is 32 bits because the width is part of the register name.
- rdi, rsi and eax are real registers, and x86-64 has only a fixed set of them.
- The add became lea. One lea adds two registers into a third, while add would need a mov first. This trick is specific to x86.
- Assembled, it is 8d 04 37 c3, valid only on x86-64.