On Wed, Apr 12, 2023 at 12:33:39PM +0200, Jakub Jelinek via Gcc-patches wrote: > On Tue, Apr 11, 2023 at 04:58:19PM -0400, Andrew MacLeod wrote: > > This bootstraps and has no regressions, and is fine by me if you want to use > > it. > > Thanks, looks nice. > My incremental patch on top of that would then be below. > > Though, > FAIL: gcc.dg/tree-ssa/vrp-float-6.c scan-tree-dump-times evrp "Folding > predicate x_.* <= y_.* to 1" 1 > still FAILs with those 2 patches together. > Shall we just xfail it for now and find some solution for GCC 14?
Except that testing of this patch on top of your patch has shown +FAIL: gfortran.dg/maxlocval_4.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/maxlocval_4.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) +UNRESOLVED: gfortran.dg/maxlocval_4.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions compilation failed to produce executable +FAIL: gfortran.dg/maxlocval_4.f90 -O3 -g (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/maxlocval_4.f90 -O3 -g (test for excess errors) +UNRESOLVED: gfortran.dg/maxlocval_4.f90 -O3 -g compilation failed to produce executable +FAIL: gfortran.dg/minlocval_1.f90 -Os (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/minlocval_1.f90 -Os (test for excess errors) +UNRESOLVED: gfortran.dg/minlocval_1.f90 -Os compilation failed to produce executable +FAIL: gfortran.dg/minlocval_4.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/minlocval_4.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors) +UNRESOLVED: gfortran.dg/minlocval_4.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions compilation failed to produce executable +FAIL: gfortran.dg/minlocval_4.f90 -O3 -g (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/minlocval_4.f90 -O3 -g (test for excess errors) +UNRESOLVED: gfortran.dg/minlocval_4.f90 -O3 -g compilation failed to produce executable +FAIL: gfortran.dg/pr104466.f90 -O (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/pr104466.f90 -O (test for excess errors) +FAIL: gfortran.dg/pr79315.f90 -O (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/pr79315.f90 -O (test for excess errors) +FAIL: gfortran.dg/pr81175.f -O (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/pr81175.f -O (test for excess errors) +FAIL: gfortran.dg/graphite/id-11.f -O (internal compiler error: in type, at value-range.h:1157) +FAIL: gfortran.dg/graphite/id-11.f -O (test for excess errors) regressions, missed the fact that frange::type ICEs on undefined_p values. Seems the HONOR_NANS case was there just as a bad attempt to speed the test up, we can just test known_isnan || maybe_isnan on both operands and that is it. With this version all those tests pass again: 2023-04-12 Jakub Jelinek <ja...@redhat.com> * range-op-float.cc (foperator_lt::op1_op2_relation): Return VREL_VARYING instead of VREL_GE if op1 or op2 could be NANs. (foperator_le::op1_op2_relation): Similarly return VREL_VARYING instead of VREL_GT. (foperator_gt::op1_op2_relation): Similarly return VREL_VARYING instead of VREL_LE. (foperator_ge::op1_op2_relation): Similarly return VREL_VARYING instead of VREL_LT. (foperator_unordered_lt::op1_op2_relation, foperator_unordered_le::op1_op2_relation, foperator_unordered_gt::op1_op2_relation, foperator_unordered_ge::op1_op2_relation): New. --- gcc/range-op-float.cc.jj 2023-04-12 12:17:44.784962757 +0200 +++ gcc/range-op-float.cc 2023-04-12 16:07:54.948759355 +0200 @@ -835,10 +835,17 @@ public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, relation_trio = TRIO_VARYING) const final override; - relation_kind op1_op2_relation (const irange &lhs, const frange &, - const frange &) const final override + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override { - return lt_op1_op2_relation (lhs); + relation_kind ret = lt_op1_op2_relation (lhs); + if (ret == VREL_GE + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Inverse of VREL_LT is VREL_UNGE with NAN ops. + return ret; } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, @@ -952,9 +959,17 @@ public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, relation_trio rel = TRIO_VARYING) const final override; - relation_kind op1_op2_relation (const irange &lhs, const frange &, - const frange &) const final override + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override { + relation_kind ret = le_op1_op2_relation (lhs); + if (ret == VREL_GT + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Inverse of VREL_LE is VREL_UNGT with NAN ops. + return ret; return le_op1_op2_relation (lhs); } bool op1_range (frange &r, tree type, @@ -1063,10 +1078,17 @@ public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, relation_trio = TRIO_VARYING) const final override; - relation_kind op1_op2_relation (const irange &lhs, const frange &, - const frange &) const final override + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override { - return gt_op1_op2_relation (lhs); + relation_kind ret = gt_op1_op2_relation (lhs); + if (ret == VREL_LE + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Inverse of VREL_GT is VREL_UNLE with NAN ops. + return ret; } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, @@ -1184,10 +1206,17 @@ public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, relation_trio = TRIO_VARYING) const final override; - relation_kind op1_op2_relation (const irange &lhs, const frange &, - const frange &) const final override + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override { - return ge_op1_op2_relation (lhs); + relation_kind ret = ge_op1_op2_relation (lhs); + if (ret == VREL_LT + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Inverse of VREL_GE is VREL_UNLT with NAN ops. + return ret; } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, @@ -1581,6 +1610,7 @@ class foperator_unordered_lt : public ra using range_operator_float::fold_range; using range_operator_float::op1_range; using range_operator_float::op2_range; + using range_operator_float::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1609,6 +1639,18 @@ public: return true; } } + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override + { + relation_kind ret = lt_op1_op2_relation (lhs); + if (ret == VREL_LT + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Should have been VREL_UNLT with NAN ops. + return ret; + } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, @@ -1692,6 +1734,7 @@ class foperator_unordered_le : public ra using range_operator_float::fold_range; using range_operator_float::op1_range; using range_operator_float::op2_range; + using range_operator_float::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1720,6 +1763,18 @@ public: return true; } } + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override + { + relation_kind ret = le_op1_op2_relation (lhs); + if (ret == VREL_LE + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Should have been VREL_UNLE with NAN ops. + return ret; + } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, relation_trio = TRIO_VARYING) const final override; @@ -1799,6 +1854,7 @@ class foperator_unordered_gt : public ra using range_operator_float::fold_range; using range_operator_float::op1_range; using range_operator_float::op2_range; + using range_operator_float::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1827,6 +1883,18 @@ public: return true; } } + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override + { + relation_kind ret = gt_op1_op2_relation (lhs); + if (ret == VREL_GT + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Should have been VREL_UNGT with NAN ops. + return ret; + } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, relation_trio = TRIO_VARYING) const final override; @@ -1910,6 +1978,7 @@ class foperator_unordered_ge : public ra using range_operator_float::fold_range; using range_operator_float::op1_range; using range_operator_float::op2_range; + using range_operator_float::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1938,6 +2007,18 @@ public: return true; } } + relation_kind op1_op2_relation (const irange &lhs, const frange &op1, + const frange &op2) const final override + { + relation_kind ret = ge_op1_op2_relation (lhs); + if (ret == VREL_GE + && (op1.known_isnan () + || op1.maybe_isnan () + || op2.known_isnan () + || op2.maybe_isnan ())) + ret = VREL_VARYING; // Should have been VREL_UNGE with NAN ops. + return ret; + } bool op1_range (frange &r, tree type, const irange &lhs, const frange &op2, relation_trio = TRIO_VARYING) const final override; Jakub