https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96135
Bug ID: 96135
Summary: [9/10/11 regression] bswap not detected by bswap pass,
unexpected results between optimization levels
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: tobi at gcc dot gnu.org
Target Milestone: ---
This is an odd one, and it seems different from the other bswap bugs that I
could find in bugzilla. This is on x64.
Compiler Explorer link is here: https://godbolt.org/z/arTf5T
Full source code:
==============================================================
constexpr long long bswap64(long long in) // unsigned long long behaves the
same
{
union {
long long v;
char c[8];
} u{in};
union {
char c[8];
long long v;
} v{ u.c[7], u.c[6], u.c[5], u.c[4], u.c[3], u.c[2], u.c[1], u.c[0]};
return v.v;
}
long long f(long long i)
{
return bswap64(i);
}
constexpr long long bswapD(double x)
{
return bswap64(*(long long*)&x);
}
long long g(double x)
{
return bswapD(x);
}
===============================================================
There are three observations / bugs:
1) bswapD is never recognized as byte-swapping
2) bswap64 is optimized to bswap at -O2 but not at -O3
3) 131t.bswap never shows bswap, apparently the pass doesn't detect this way of
writing bswap, leaving it to the RTL optimizers. Hence I classified this as
tree-optimization bug.
Verified at -O2 with 9.3, 10.1 and trunk on the compiler explorer.
I'm flagging this as a regression because at -O2 gcc 8.3 detects bswap in both
cases, but I'm guessing that this is by some accident. In 7.5 neither function
is compiled as bswap.