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

Reply via email to