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

            Bug ID: 128076
           Summary: wrong code at -O2 and -O3 for a tail-recursive
                    function whose signed additions do not overflow
           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

static int f(int n) {
  if (n == 0) return 0;
  if (n == 1) return f(n - 1) + 2147483647;
  return f(n - 1) - 2147483647;
}
int main(void) {
  volatile int n = 3;
  if (f(n) != -2147483647)
    __builtin_abort();
}

godbolt: https://godbolt.org/z/nv8GrsMso

f(1) = 2147483647, f(2) = 0 and f(3) = -2147483647, so no operation overflows.
With -O0, -O1, -O2 -fwrapv or -O2 -fno-optimize-sibling-calls the program exits
normally; with -O2 or -O3 it aborts, on every release from 5.4 to trunk. The
multiplicative variant below (g(1) = g(2) = 1, again without overflow) is
correct up to 15.3 and aborts at -O2 from 16.1 on:

static int g(int n) {
  if (n == 0) return 1;
  return -2147483646 + 2147483647 * g(n - 1);
}
int main(void) {
  if (g(2) != 1)
    __builtin_abort();
}
  • [Bug tree-optimization/128076] N... kyuwoncho18 at gmail dot com via Gcc-bugs

Reply via email to