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