C++ 仅在两次幂上的叮当声中错过了优化
使用-Ofast编译时,clang正确地推断出以下函数将始终返回0C++ 仅在两次幂上的叮当声中错过了优化,c++,x86,clang,compiler-optimization,C++,X86,Clang,Compiler Optimization,使用-Ofast编译时,clang正确地推断出以下函数将始终返回0 int zero(bool b) { const int x = 5; return (x * b) + (-x * b); } 编译成 zero(bool): # @zero(bool) xor eax, eax ret zero(bool): #
int zero(bool b) {
const int x = 5;
return (x * b) + (-x * b);
}
编译成
zero(bool): # @zero(bool)
xor eax, eax
ret
zero(bool): # @zero(bool)
mov eax, edi
shl eax, 3
xor dil, 1
movzx ecx, dil
lea eax, [rax + 8*rcx]
add eax, -8
ret
但是,如果我将常数更改为2的任意幂(1或0除外),clang将不再进行相同的推导
int zero(bool b) {
const int x = 8;
return (x * b) + (-x * b);
}
编译成
zero(bool): # @zero(bool)
xor eax, eax
ret
zero(bool): # @zero(bool)
mov eax, edi
shl eax, 3
xor dil, 1
movzx ecx, dil
lea eax, [rax + 8*rcx]
add eax, -8
ret
如果我将函数参数更改为更大的值(short、int、long),那么优化就正确进行了
是什么导致这种奇怪的边缘情况?编译器似乎不执行算术求反,即使一元减号运算符是默认的。它没有义务这样做。为它记录一个bug?如果常量被更改为传递给函数的参数,则代码是正确的。“真的很奇怪。”阿莱默里观察得很好,我没注意到。它也可以在2**31时再次工作,甚至可以通过使常量为unsigned来防止溢出。很好的bug报告。不必要的堆栈溢出问题。@WernerHenze我不同意。“为什么会发生这种情况”的问题迄今尚未得到回答。