This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/78947] New: sub-optimal code for (bool)(int ? int : int)
- From: "peter at cordes dot ca" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 29 Dec 2016 02:53:33 +0000
- Subject: [Bug tree-optimization/78947] New: sub-optimal code for (bool)(int ? int : int)
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78947
Bug ID: 78947
Summary: sub-optimal code for (bool)(int ? int : int)
Product: gcc
Version: 6.3.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: peter at cordes dot ca
Target Milestone: ---
Target: x86_64-*-*, i?86-*-*
Full version:
http://stackoverflow.com/questions/41323911/why-the-difference-in-code-generation-for-bool-bool-int-int
bool condSet(int cond, int a, int b) {
return cond ? a : b;
}
clang and icc use a cmov to select a or b, and then booleanize that.
g++6.3 -O3 decides to booleanize b, then check the condition and if necessary
booleanize a into %al. This is pretty obviously sub-optimal, even if a branch
is better than a cmov for a predictable condition. (And it differs from what
gcc does if the return type is int)
condSet(int, int, int):
testl %edx, %edx # b
setne %al #, <retval>
testl %edi, %edi # cond
jne .L6 #,
rep ret
.L6:
testl %esi, %esi # a
setne %al #, <retval>
ret
Writing the function as
int foo = cond ? a : b;
return foo;
gets g++ to select an operand with cmov and then booleanize it, like clang does
in the first place (looks optimal to me):
testl %edi, %edi
cmovel %edx, %esi
testl %esi, %esi
setne %al
retq