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

            Bug ID: 126548
           Summary: Wrong code with Bitint and value ranges
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

/* Entry point: operator_minus::wi_fold -> value_range_with_overflow
   (gcc/range-op.cc:922).  After the _BitInt lowering the top limb of a
   _BitInt(193) is a <unnamed-signed:1>, a type on which the lowering emits
   adds and subtracts that wrap by design, but which is
   TYPE_OVERFLOW_UNDEFINED, so value_range_with_overflow returns UNDEFINED for
   the wrapping half and the union comes out a singleton.

   No undefined behaviour in this program: p - 4 is representable in 193 bits
   for every long p, and the shift count 192 is below the precision 193.  */

int printf (const char *, ...);
typedef _BitInt(193) s193;

__attribute__((noipa)) static long
f (long p)
{
  s193 t = (s193) p - (s193) 4;
  return (long) (t >> 192);             /* sign of t: 0 or -1 */
}

int
main (void)
{
  volatile long v = 81985529216486895L; /* > 4, so f must return 0 */
  long r = f (v);
  printf ("%ld\n", r);
  if (r != 0)
    __builtin_abort ();
  if (f (-1L) != -1)
    __builtin_abort ();
  return 0;
}

on aarch64 at -O2 aborts and passes at -O0

Reply via email to