我只是注意到Clang编译了这个语句(当然,没有任何优化):
--x; /* int x; */
到:
addl $4294967295, %ecx ## imm = 0xFFFFFFFF
为什么?使用addl
而不是"明显"subl
有什么好处吗?还是只是一个实施事实?
欺骗我的是这个:
x -= 1;
成为:
subl $1, %eax
叮当信息:
Apple clang version 3.0 (tags/Apple/clang-211.12) (基于 LLVM 3.0svn)目标:x86_64-苹果-达尔文11.2.0螺纹型号:磅
此行为与 clang 处理预递减的方式有关,而不是像 sub-and-assign 这样的二进制运算符。请注意,我将尝试在 clang 级别解释为什么您会看到这种行为。我不知道为什么选择它以这种方式实现它,但我想这只是为了便于实施。
我在这里引用的所有函数都可以在 lib/CodeGen/CGExprScalar.cpp
中的类 ScalarExprEmitter
中找到。
函数EmitScalarPrePostIncDec
以相同的方式处理前/后递减/递增:LLVM add
指令以 1
或 -1
作为第二个参数发出,具体取决于表达式分别是递增或递减。
因此
--x
最终,在 LLVM IR 中,类似于
add i32 %x, -1
很自然地,它转化为 x86 类似
add $0xffffffff, %ecx
另一方面,二元运算符的处理方式都不同。在您的情况下,
x -= 1
将由EmitCompoundAssign
处理,而又调用EmitSub
.将发出类似于以下 LLVM IR 的内容:
sub i32 %x, 1