GCC不会优化整数算术表达式

时间:2017-03-31 23:47:49

标签: c++ gcc optimization compilation arithmetic-expressions

doA(const std::string&)

generated code是:

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

1 个答案:

答案 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报告)。