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

Davin McCall <davmac at davmac dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |davmac at davmac dot org

--- Comment #15 from Davin McCall <davmac at davmac dot org> ---
Apologies if I'm wrong and just making noise but doesn't the test case involve
a left shift of a value greater than the bit width of the left operand and
therefore invoke UB?

  ll = -5597998501375493990LL;

  ll = (5677365550390624949L - ll) - (ull1 > 0);
  //ull3 = (unsigned int)
  //  (2067854353L <<
  //   (((ll + -2129105131L) ^ 10280750144413668236ULL) -
  //    10280750143997242009ULL)) >> ((2873442921854271231ULL | ull2)
  //                                - 12098357307243495419ULL);

  // Above broken down:

  unsigned long long int t1 = ll + -2129105131L;
  unsigned long long int t2 = t1 ^ 10280750144413668236ULL;
  unsigned long long int t3 = t2 - 10280750143997242009ULL;
  // t3 = 9523455470476460042 !!!
  long t4 = 2067854353L << t3;  // UB!!
  unsigned int t5 = (unsigned int)t4;

  unsigned long long int t6 = 2873442921854271231ULL | ull2;
  unsigned long long int t7 = t6 - 12098357307243495419ULL;
  ull3 = t5 >> t7;

Fixed test case would be:

--- begin ---
unsigned long long int ll = 0;
unsigned long long int ull1 = 1ULL;
unsigned long long int ull2 = 12008284144813806346ULL;
unsigned long long int ull3;

void
foo ()
{
  ll = -5597998501375493990LL;

  ll = (5677365550390624949L - ll) - (ull1 > 0);
  ull3 = (unsigned int)
    (2067854353L <<
     (((ll + -2129105131L) ^ 10280750144413668236ULL) +
      17089282532945401191ULL)) >> ((2873442921854271231ULL | ull2)
                                    - 12098357307243495419ULL);
}

int
main ()
{
  foo ();
  printf ("%llu expected 3998784)\n", ull3);
  printf ("%llx expected 3d0440)\n", ull3);
  return 0;
}
--- end ---

This still demonstrates the bug.

Reply via email to