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
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