【发布时间】:2019-10-18 09:10:18
【问题描述】:
使用 -Ofast 编译时,clang 正确推断出以下函数将始终返回 0。
int zero(bool b) {
const int x = 5;
return (x * b) + (-x * b);
}
编译成
zero(bool): # @zero(bool)
xor eax, eax
ret
但是,如果我将常数更改为 2 的任意幂(1 或 0 除外),clang 不再进行相同的扣除
int zero(bool b) {
const int x = 8;
return (x * b) + (-x * b);
}
编译成
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
The code compiled with compiler explorer.
如果我将函数参数更改为更大(short、int、long),则优化正确。
是什么导致了这种奇怪的边缘情况?
【问题讨论】:
-
为它记录一个错误?
-
并且如果把常量改成传递给函数的参数,代码是正确的。确实很奇怪。
-
@AlainMerigot 很好的观察,我没有注意到。它还可以在 2**31 再次工作,甚至通过使常量无符号来防止溢出。
-
很好的错误报告。不必要的 Stack Overflow 问题。
-
@WernerHenze 我不同意。 “为什么会发生这种情况”的问题尚未得到解答。
标签: c++ x86 clang compiler-optimization