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.

Reply via email to