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

            Bug ID: 128453
           Summary: [14/15/16/17 Regression] wrong code with -ffast-math:
                    reassoc truncates a pow repeat count of 2^32 to 0
                    (operand_entry::count is unsigned int)
           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: lzy20000419 at outlook dot com
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: x86_64-pc-linux-gnu
             Build: x86_64-pc-linux-gnu

Split out from PR128006 (issue 2 of comment 4) at the maintainer's request.
attempt_builtin_powi truncates repeat counts. The testcase is UB-free (x = -1):

```c
#include <math.h>
__attribute__((noipa)) double f (double x, double y)
{
  return x * x * x * y * x * x * x * pow (x, 4294967296.0);
}
int main (void)
{
  if (f (-1.0, 1.0) != 1.0) __builtin_abort ();
  return 0;
}
```

```
$ gcc -O2 -ffast-math t.c -lm && ./a.out
Aborted
$ gcc -O2 -ffast-math -fno-tree-reassoc t.c -lm && ./a.out   # ok
```

The generated code has no pow call left: pow (x, 2^32) contributes 0 to the
repeat count and disappears from the product, so the result is x^6 * y instead
of x^(6+2^32) * y.

Tested on trunk 17.0.0 20261105 (2175b27369e5), 16.2.1 and 14.2.0: all abort.
On Compiler Explorer it aborts from 8.1.0 through trunk (8.5.0, 9.5.0, 10.5.0,
11.4.0, 12.4.0, 13.4.0, 14.2.0, 15.3.0, 16.2.0) and works with 7.5.0 and 6.5.0.
Godbolt (execution on trunk, 16.2, 14.2 and 7.5; 7.5 works):
https://godbolt.org/z/66jhGcKzT

add_repeat_to_ops_vec (tree-ssa-reassoc.cc:629 on trunk) stores a HOST_WIDE_INT
repeat into operand_entry::count, which is unsigned int
(tree-ssa-reassoc.h:29). The accumulated count is later emitted as an int powi
exponent, so sums above INT_MAX would wrap as well.

A possible one-line fix (not tested) is to make acceptable_pow_call
(tree-ssa-reassoc.cc:6109) reject exponents above INT_MAX (and keep the summed
count of a base within INT_MAX in attempt_builtin_powi, or give
operand_entry::count a wider type).

Disclaimer: This test case was found with LLM-assisted targeted testing, and
the report was written with LLM assistance.
  • [Bug tree-optimization/128453]... lzy20000419 at outlook dot com via Gcc-bugs

Reply via email to