https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102126
Bug ID: 102126 Summary: Wrong optimization of multiplication by 1 and -1 with -ftrapping-math when an underflow is possible Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: vincent-gcc at vinc17 dot net Target Milestone: --- Without -fsignaling-nans, GCC optimizes the floating-point multiplication by 1 as a no-op, even when it may generate a trap due to underflow. This is wrong. Testcase: #define _GNU_SOURCE #include <stdio.h> #include <float.h> #include <fenv.h> #pragma STDC FENV_ACCESS ON double f (double x) { return x * 1.0; } double g (double x) { volatile double one = 1.0; return x * one; } int main (void) { volatile double x = DBL_MIN / 2, y; feenableexcept (FE_UNDERFLOW); y = f(x); printf ("f: %d\n", y != 0); y = g(x); printf ("g: %d\n", y != 0); return 0; } Here, x is a subnormal, so that its multiplication by 1 signals an underflow. Note that since the result is exact, the underflow flag is not raised under the default exception handling, so that without -ftrapping-math and -fsignaling-nans, f() may be optimized to no-op. With -fsignaling-nans, GCC disables the optimization as expected. But with -ftrapping-math, it doesn't (the optimization is done at any optimization level, even -O0); this can be seen in the generated asm code, with -S. When executing the code (with -O3 -ftrapping-math -lm): f: 1 Floating point exception (core dumped) showing that f() was incorrectly optimized, and that g(), which is not optimized due to volatile, gives a floating-point exception as expected. Similar issue with the multiplication by -1 (at least on x86_64), where GCC just negates the value. Bug reproducible from at least GCC 4.6 to GCC 11.2.0.