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

            Bug ID: 105414
           Summary: constant folding for fmin/max(snan, snan) is wrong
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: guihaoc at gcc dot gnu.org
  Target Milestone: ---

gcc -O0 -fsignaling-nans -D_WANT_SNAN -lm -o fmin fmin.c && ./fmin
(snan, snan), fmin: nan
gcc -O3 -fsignaling-nans -D_WANT_SNAN -lm -o fmin fmin.c && ./fmin
(snan, snan), fmin: snan

The fmin(SNaN, SNaN) got different result with O0 and O3. The result should be
nan(QNaN) according to C standard. 

The problem might be at match.pd. fmin(a,a) can't be folded to a when a is
SNaN. I propose following patch to fix it.

diff --git a/gcc/match.pd b/gcc/match.pd
index cad61848daa..2c2efda158b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3093,7 +3093,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (for minmax (min max FMIN_ALL FMAX_ALL)
  (simplify
   (minmax @0 @0)
-  @0))
+  (if(!HONOR_SNANS (@0) || !TREE_REAL_CST (@0).signalling)
+  @0)))
 /* min(max(x,y),y) -> y.  */
 (simplify
  (min:c (max:c @0 @1) @1)

Reply via email to