Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

x86 addl vs subl

I just notice that Clang compiles this statement (without any optimization, of course):

--x; /* int x; */

into:

addl    $4294967295, %ecx       ## imm = 0xFFFFFFFF

Why? Is there any advantage of using addl instead of the "obvious" subl? Or is it just an implementation fact?

What tricks me is that this one:

x -= 1;

becomes:

subl    $1, %eax

Clang info:

Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.2.0
Thread model: posix
like image 329
sidyll Avatar asked Oct 08 '22 03:10

sidyll


1 Answers

This behavior has to do with the way clang handles pre-decrement as opposed to binary operators like sub-and-assign. Note that I will just try to explain, at the clang level, why you see this behavior. I don't know why it was chosen to implement it this way but I guess it was just for ease of implementation.

All functions I reference here can be found in class ScalarExprEmitter inside lib/CodeGen/CGExprScalar.cpp.

Pre/post decrement/increment are all handled the same way by the function EmitScalarPrePostIncDec: an LLVM add instruction is emitted with either 1 or -1 as second argument, depending on the expression being an increment or a decrement respectively.

Therefore,

--x

will end up, in the LLVM IR, as something like

add i32 %x, -1

which, quite naturally, translates to x86 as something like

add $0xffffffff, %ecx

Binary operators, on the other hand, are all handled differently. In your case,

x -= 1

will be handled by EmitCompoundAssign which in turn calls EmitSub. Something like the following LLVM IR will be emitted:

sub i32 %x, 1
like image 130
mtvec Avatar answered Oct 12 '22 22:10

mtvec