[Bug tree-optimization/94006] New: Poor codegen for cond ? lval1 : lval2
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Mar 2 22:48:00 GMT 2020
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.
More information about the Gcc-bugs
mailing list