为什么bool = bool的代码生成有所不同?整数:整数 [英] Why the difference in code generation for bool = bool ? int : int
问题描述
此代码...
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屋!