https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127669
Bug ID: 127669
Summary: GCC `__builtin_bitreverseg` returns a wrong value for
an optimizer-visible `_BitInt(129)` operand
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: bic60176 at gmail dot com
Target Milestone: ---
Summary
On the GCC 17.0.0 development snapshot, applying `__builtin_bitreverseg` to an
unsigned `_BitInt(129)` value constructed by an inlinable loop gives a
different result from the expected value. The same value passed through an
opaque noinline function produces the expected result, so the failure depends
on the operand being visible to optimization. This is a deterministic wrong
result for a defined program.
Reproducer
```c
#include <stdio.h>
typedef unsigned _BitInt(129) T;
static volatile int g_zero;
static T __attribute__((noinline))
opaque (T v)
{
if (g_zero)
v = 0;
return v;
}
static T
mkx (void)
{
T v = 0;
for (int i = 0; i < 5; i++)
{
if (i)
{
v = (T) (v << 16);
v = (T) (v << 16);
}
v = (T) (v | (T) (i == 4));
}
return v;
}
static T
mkexp (void)
{
T v = 0;
for (int i = 0; i < 5; i++)
{
if (i)
{
v = (T) (v << 16);
v = (T) (v << 16);
}
v = (T) (v | (T) (i == 0));
}
return v;
}
int
main (void)
{
T x = mkx ();
T expected = mkexp ();
T visible_result = __builtin_bitreverseg (x);
T opaque_result = __builtin_bitreverseg (opaque (x));
printf ("%d%d\n", visible_result == expected,
opaque_result == expected);
return 0;
}
```
Expected behavior
`x` is the value 1 and `expected` is the 129-bit value with only bit 128 set.
Reversing all 129 bits of `x` should therefore produce `expected`. The builtin
result should not change depending on whether the optimizer can see how `x` was
constructed.