我正在研究以下两个小功能:
int foo(int val) {
return val / 2;
}
int bar(int val) {
return val >> 1;
}
我希望编译器为它们生成相同的代码。但是,这是在O3生成的程序集
foo(int): # @foo(int)
mov eax, edi
shr eax, 31
lea eax, [rax + rdi]
sar eax
ret
bar(int): # @bar(int)
sar edi
mov eax, edi
ret
这是godbolt链接:https://godbolt.org/g/XrtdEY
我想知道为什么这两个组件之间存在差异。
答案 0 :(得分:2)
它是不同的汇编,因为除非有符号输入,否则除以2的有符号整数必须给出明确定义的结果(按标准)。集会必须考虑到这一点,并且不能只做一个可能产生“意外”的转变。
当您编写明确的班次时,您承认标准对该运营商施加的宽松合同。所以编译器有更多的余地。