https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94006
Bug ID: 94006 Summary: Poor codegen for cond ? lval1 : lval2 Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- I noticed that this (compiled with -std=c++2a and any optimization level except -O0): #include <compare> std::strong_ordering f1(int a, int b) { return a == b ? std::strong_ordering::equal : std::strong_ordering::less; } compiles to: _Z2f1ii: cmp edi, esi jne .L3 mov al, BYTE PTR _ZNSt15strong_ordering5equalE[rip] ret .L3: mov al, BYTE PTR _ZNSt15strong_ordering4lessE[rip] ret _ZNSt15strong_ordering5equalE: .zero 1 _ZNSt15strong_ordering4lessE: .byte -1 Whereas this less readable form: #include <compare> std::strong_ordering f2(int a, int b) { return (a == b) <=> true; } produces much smaller code: _Z2f2ii: cmp edi, esi setne al neg eax ret Jason observed that it seems to be because the result of <=> is a prvalue, whereas the ?: version is returning from lvalues. We get similar codegen (but with a less extreme difference in size) for this: struct A { int i; }; constexpr A a1 { 1 }; constexpr A a2 { 0 }; A f1 (int a, int b) { return a == b ? a1 : a2; } A f2 (int a, int b) { return A{a == b ? a1.i : a2.i}; } The first function is obviously easier to read, but the second produces smaller code because the two global variables are not emitted.