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)