为什么bool = bool的代码生成有所不同?整数:整数 [英] Why the difference in code generation for bool = bool ? int : int

查看:81
本文介绍了为什么bool = bool的代码生成有所不同?整数:整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码...

bool condSet(int cond, int a, int b) {
    return cond ? a : b;
}

..为gcc 6.3生成...

..Generates for gcc 6.3...

    test    edx, edx
    setne   al 
    test    edi, edi
    jne     .L6
    rep ret
.L6:
    test    esi, esi
    setne   al
    ret

..对于icc 17 ...

.. For icc 17...

    test      edi, edi
    cmovne    edx, esi
    mov       eax, 1
    test      edx, edx
    cmove     eax, edx
    ret       

..对于clang 3.9

..And for clang 3.9

    test    edi, edi
    cmove   esi, edx
    test    esi, esi
    setne   al
    ret

对于代码模式,为什么我们会有这些不同之处,我希望它们是常见的?它们都依赖于条件指令setne,cmovne,cmove,但是gcc也有一个分支,并且它们都使用不同顺序的指令和参数..

编译器中的哪一段代码负责生成此代码?是由于寄存器分配方式不同造成的吗?一般数据流分析是如何完成的;还是在生成代码时编译器模式与此模式相匹配?

What pass in the compiler is responsible for this code generation? Is the difference due to how the register allocation is done; how the general dataflow analysis is done; or do the compiler pattern match against this pattern when generating the code?

代码和asm列表: https://godbolt.org/g/7heVGz

推荐答案

将返回类型更改为int会导致所有三个编译器使用test/cmov策略生成无分支代码.

Changing the return type to int results in branchless code from all three compilers, using the test/cmov strategy.

我猜gcc决定对条件的两边进行布尔化将花费太多工作,并决定使用分支.也许它没有意识到这是 s 的工作,并且实际上可以用另一种方式来完成该表达式(选择正确的输入,然后将其布尔化).

I'd guess that gcc decides that booleanizing both sides of the conditional would be too much work, and decides to use a branch. Maybe it doesn't realize that it's the same work, and the expression can actually be done the other way (select the right input and then booleanize that).

它编写的代码会对b进行布尔化,然后才测试条件并对a进行布尔化.因此,当cond为true时,它实际上同时运行test/setnz对.

The code it makes does booleanize b, and only then tests the condition and booleanizes a. So when cond is true, it actually runs both test / setnz pairs.

这闻起来像是缺少优化的错误. (或者是优化-运行-amok错误,通过将return-type应用于?:的两个输入而不是仅应用于结果,它会自行冒充).

This smells like a missed-optimization bug. (Or an optimization-run-amok bug, where it shoots itself in the foot by applying the return-type to both inputs of the ?: instead of only to the result).

报告为 GCC错误78947 .

在此之前,您可以

Until that's fixed, you can get gcc to make code like clang / icc by splitting it into two steps:

bool condSet(int cond, int a, int b) {
  int tmp = cond ? a : b;       // better asm from gcc this way
  return tmp;
}

这篇关于为什么bool = bool的代码生成有所不同?整数:整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆