https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122714

--- Comment #3 from Stefan Schulze Frielinghaus <stefansf at gcc dot gnu.org> 
---
[[gnu::noipa]]
void test (unsigned _BitInt(135) *x)
{
  if (*x != 18390507727765446703890200284988625150777uwb)
    __builtin_abort ();
}

int main (void)
{
  unsigned _BitInt(135) x = 18390507727765446703890200284988625150777uwb;
  test (&x);
}

In main() we are writing 24 bytes, i.e., three longs

MEM <unsigned long> [(unsigned _BitInt(135) *)&x + 16B] = 5945456838964175673;
MEM <vector(2) unsigned long> [(unsigned _BitInt(135) *)&x] = { 54,
827241597421966155 };

and in test() we have three loads

_5 = MEM <unsigned long> [(unsigned _BitInt(135) *)x_3(D) + 16B];
...
_6 = MEM <unsigned long> [(unsigned _BitInt(135) *)x_3(D) + 8B];
...
_7 = MEM <<unnamed-unsigned:7>> [(unsigned _BitInt(135) *)x_3(D)];

The last load only loads one byte which is the most significant one of the
first long.  For bitint_big_endian I would have expected something along the
line

_7 = MEM <<unnamed-unsigned:7>> [(unsigned _BitInt(135) *)x_3(D) + 7B];

A quick and dirty patch for bitint_large_huge::limb_access fixes this but
doesn't fix all failing tests.

I was also wondering whether it would make sense to load 8 bytes in case of
bitint_extended and then truncating to 1 byte, hoping that if the value is ever
used in an extended form, that the extend could be optimized away ... though,
maybe this is not worthwhile to consider?

Reply via email to