https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68000
Bug ID: 68000 Summary: Suboptimal ternary operator codegen Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: thaines.astro at gmail dot com Target Milestone: --- Created attachment 36534 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36534&action=edit Preprocessed C code for "Suboptimal ternary operator codegen" I think this problem is likely related to bug 23286, bug 56096, bug 64524, and possibly bug 67879. struct pair8 { uint8_t x,y; }; uint8_t foo_manual_hoist(struct pair8 *p) { const uint8_t a = p->x + 1; return a == p->y ? 0 : a; } uint8_t foo(struct pair8 *p) { return p->x + 1 == p->y ? 0 : p->x + 1; } uint8_t foo_if(struct pair8 *p) { uint8_t a = p->x + 1; if (a == p->y) a = 0; return a; } int main() {} Under gcc-5.1, gcc -m64 -march=native -O3 -g -S -masm=intel -o test.asm test.c produces foo_manual_hoist: movzx eax, BYTE PTR [rdi+1] mov edx, 0 add eax, 1 cmp al, BYTE PTR [rdi+2] cmove eax, edx ret foo: movzx edx, BYTE PTR [rdi+1] movzx ecx, BYTE PTR [rdi+2] mov eax, edx // weird! add edx, 1 add eax, 1 cmp edx, ecx mov edx, 0 cmove eax, edx ret foo_if: movzx eax, BYTE PTR [rdi+1] mov edx, 0 add eax, 1 cmp al, BYTE PTR [rdi+2] cmove eax, edx ret As expect, the ternary version with the manual hoist of the common subexpression produces identical codegen as the if version with the same hoist. What is unexpected, is the duplication of the common subexpression for the "bare" ternary version (line 3 of the disassembly of foo). It is clear that the compiler sees the expressions to be the same, but treats them separately anyway. As an aside, clang-3.6 produces identical code for all three versions.