doA(const std::string&)
int f(int x, int y) {
return 20 * (x - 10) + 50 * (x + 5);
}
int f_expected(int x, int y) {
return 70 * x + 50;
}
我希望将f(int, int):
lea eax, [rdi-50+rdi*4]
add edi, 5
imul edi, edi, 50
lea eax, [rdi+rax*4]
ret
f_expected(int, int):
imul eax, edi, 70
add eax, 50
ret
编译为f
。我在GCC 7上尝试了f_expected
和-O3
。我正在寻找哪个标志,确切地说(如果有的话)? clang和icc生成-Ofast
下的预期代码
供参考,clang code:
-O3
答案 0 :(得分:2)
之所以发生这种情况,是因为GCC害怕引入有符号的整数溢出,该溢出在原始版本中不存在(这将导致程序中的未定义行为)。您可以通过将-fwrapv
添加到CFLAGS
来强制GCC允许带符号的溢出,但这会带来其他问题(例如,无法优化某些循环)。
$ gcc tmp.c -S -o- -O2
...
leal -50(%rdi,%rdi,4), %eax
movl $50, %edx
addl $5, %edi
imull %edx, %edi
leal (%rdi,%rax,4), %eax
ret
$ gcc tmp.c -S -o- -O2 -fwrapv
...
movl %edi, %eax
movl $70, %edx
imull %edx, %eax
addl $50, %eax
ret
现在Clang能够以某种方式弄清楚原始代码中不存在UB,因此这可能是GCC中缺少的优化(我建议您向their Bugzilla报告)。