aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2023-09-20 09:46:19 -0400
committerAldy Hernandez <aldyh@redhat.com>2023-09-20 13:03:14 -0400
commit0bd961634ad5561c205fa003ab5414578fa7dd54 (patch)
tree0085180c9694290f1af3d222bc351cef56c21973
parent53d834a7fae3afffebb45a2d66908f705773a7fc (diff)
downloadgcc-0bd961634ad5561c205fa003ab5414578fa7dd54.zip
gcc-0bd961634ad5561c205fa003ab5414578fa7dd54.tar.gz
gcc-0bd961634ad5561c205fa003ab5414578fa7dd54.tar.bz2
[frange] Remove special casing from unordered operators.
In coming up with testcases for the unordered folders, I realized that we were already handling them correctly, even in the absence of my work in this area lately. All of the unordered fold_range() methods try to fold with the ordered variants first, and if they return TRUE, we are guaranteed to be able to fold, even in the presence of NANs. For example: if (x_5 >= y_8) if (x_5 __UNLE y_8) On the true side of the first conditional we know that either x_5 < y_8 or that one or more operands is a NAN. Since UNLE_EXPR returns true for precisely this scenario, we can fold as true. This is handled in the fold_range() methods as follows: if (!range_op_handler (LE_EXPR).fold_range (r, type, op1_no_nan, op2_no_nan, trio)) return false; // The result is the same as the ordered version when the // comparison is true or when the operands cannot be NANs. if (!maybe_isnan (op1, op2) || r == range_true (type)) return true; This code has been there since the last release, and makes the special casing I am deleting obsolete. I have added tests to make sure we keep track of this behavior. gcc/ChangeLog: * range-op-float.cc (foperator_unordered_ge::fold_range): Remove special casing. (foperator_unordered_gt::fold_range): Same. (foperator_unordered_lt::fold_range): Same. (foperator_unordered_le::fold_range): Same. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/vrp-float-relations-5.c: New test. * gcc.dg/tree-ssa/vrp-float-relations-6.c: New test.
-rw-r--r--gcc/range-op-float.cc20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c54
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c54
3 files changed, 112 insertions, 16 deletions
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 399deee..0951bd3 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -1644,10 +1644,7 @@ public:
const frange &op1, const frange &op2,
relation_trio trio = TRIO_VARYING) const final override
{
- relation_kind rel = trio.op1_op2 ();
-
- if (op1.known_isnan () || op2.known_isnan ()
- || rel == VREL_LT)
+ if (op1.known_isnan () || op2.known_isnan ())
{
r = range_true (type);
return true;
@@ -1759,10 +1756,7 @@ public:
const frange &op1, const frange &op2,
relation_trio trio = TRIO_VARYING) const final override
{
- relation_kind rel = trio.op1_op2 ();
-
- if (op1.known_isnan () || op2.known_isnan ()
- || rel == VREL_LE)
+ if (op1.known_isnan () || op2.known_isnan ())
{
r = range_true (type);
return true;
@@ -1870,10 +1864,7 @@ public:
const frange &op1, const frange &op2,
relation_trio trio = TRIO_VARYING) const final override
{
- relation_kind rel = trio.op1_op2 ();
-
- if (op1.known_isnan () || op2.known_isnan ()
- || rel == VREL_GT)
+ if (op1.known_isnan () || op2.known_isnan ())
{
r = range_true (type);
return true;
@@ -1985,10 +1976,7 @@ public:
const frange &op1, const frange &op2,
relation_trio trio = TRIO_VARYING) const final override
{
- relation_kind rel = trio.op1_op2 ();
-
- if (op1.known_isnan () || op2.known_isnan ()
- || rel == VREL_GE)
+ if (op1.known_isnan () || op2.known_isnan ())
{
r = range_true (type);
return true;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c
new file mode 100644
index 0000000..2bd06c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-5.c
@@ -0,0 +1,54 @@
+// { dg-do compile }
+// { dg-options "-O2 -fgimple -fdump-tree-evrp" }
+
+void link_error();
+
+void __GIMPLE (ssa,startwith("evrp"))
+foo1 (float x, float y)
+{
+ __BB(2):
+ if (x_4(D) <= y_5(D))
+ goto __BB5;
+ else
+ goto __BB3;
+
+ __BB(3):
+ // Relation at this point is VREL_GT.
+ if (x_4(D) __UNGE y_5(D))
+ goto __BB5;
+ else
+ goto __BB4;
+
+ __BB(4):
+ link_error ();
+ goto __BB5;
+
+ __BB(5):
+ return;
+}
+
+void __GIMPLE (ssa,startwith("evrp"))
+foo2 (float x, float y)
+{
+ __BB(2):
+ if (x_4(D) <= y_5(D))
+ goto __BB5;
+ else
+ goto __BB3;
+
+ __BB(3):
+ // Relation at this point is VREL_GT.
+ if (x_4(D) __UNGT y_5(D))
+ goto __BB5;
+ else
+ goto __BB4;
+
+ __BB(4):
+ link_error ();
+ goto __BB5;
+
+ __BB(5):
+ return;
+}
+
+// { dg-final { scan-tree-dump-not "link_error" "evrp" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c
new file mode 100644
index 0000000..a75ae5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-float-relations-6.c
@@ -0,0 +1,54 @@
+// { dg-do compile }
+// { dg-options "-O2 -fgimple -fdump-tree-evrp" }
+
+void link_error();
+
+void __GIMPLE (ssa,startwith("evrp"))
+foo1 (float x, float y)
+{
+ __BB(2):
+ if (x_4(D) >= y_5(D))
+ goto __BB5;
+ else
+ goto __BB3;
+
+ __BB(3):
+ // Relation at this point is VREL_LT.
+ if (x_4(D) __UNLT y_5(D))
+ goto __BB5;
+ else
+ goto __BB4;
+
+ __BB(4):
+ link_error ();
+ goto __BB5;
+
+ __BB(5):
+ return;
+}
+
+void __GIMPLE (ssa,startwith("evrp"))
+foo2 (float x, float y)
+{
+ __BB(2):
+ if (x_4(D) >= y_5(D))
+ goto __BB5;
+ else
+ goto __BB3;
+
+ __BB(3):
+ // Relation at this point is VREL_LT.
+ if (x_4(D) __UNLE y_5(D))
+ goto __BB5;
+ else
+ goto __BB4;
+
+ __BB(4):
+ link_error ();
+ goto __BB5;
+
+ __BB(5):
+ return;
+}
+
+// { dg-final { scan-tree-dump-not "link_error" "evrp" } }