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

            Bug ID: 128078
           Summary: wrong code at -O1, -O2 and -Os summing (long long) ((b
                    + i) * s) in a loop with step 3
           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: kyuwoncho18 at gmail dot com
  Target Milestone: ---
            Target: x86_64-pc-linux-gnu

__attribute__((noinline)) unsigned long long f(int b, int s, int n)
{
  unsigned long long z = 0;
  for (int i = 0; i < n; i += 3)
    z += (unsigned long long)(long long)((b + i) * s);
  return z;
}

int main(void)
{
  if (f(-2, 1 << 30, 4) != -(1ULL << 30))
    __builtin_abort();
}

godbolt: https://godbolt.org/z/eWPaWTG6x

The loop runs for i = 0 and i = 3, so (b + i) * s is -2^31 and then 2^30, both
representable in int, and f returns 2^64 - 2^30 (18446744072635809792). With
-O0, -O3 or -O2 -fno-ivopts the program exits normally; with -O1, -O2 or -Os f
returns 2^64 - 5 * 2^30 (18446744068340842496) and the program aborts.

Reply via email to