Consider the following x86_64 assembly:
cmpl $0x12,%rax
sbb %esi,%esi
and $0xffffffffffffffdf,%esi
add $0x5b,%esi
It contains the SBB instruction. SBB cannot be represented in LLVM_IR
cmpl: if ($0x12 < %rax) set the carry flag.
sbb: if carry flag set: %esi = 0xffffffffffffffff else %esi = 0; // Note: 0xffffffffffffffff = -1
and: if carry flag set: %esi = 0xffffffffffffffdf else %esi = 0; // Note: 0xffffffffffffffdf = -33
add: if carry flag set: %esi = 0x3a else %esi = 0x5b;
This can then be converted into:
if ($0x12 < %rax) {
%esi = 58; // 0x3a
} else {
%esi = 91; // 0x5b
}
So, the SBB is used here to remove the need for a Branch instruction.
WOW, compilers are clever!!!
I am writing a de-compiler “Binary → LLVM IR”. So, I obviously need to treat SBB as a special case and transform it into something that can be represented in LLVM IR.
I wish to obtain a list of all the optimizations done by LLVM that result in assembly that cannot immediately be represented in LLVM IR.
The above being one example.
For example:
- List all optimizations that result in a SBB instruction.
Where in LLVM should I start looking ?
Kind Regards
James