So currently we only allow deriving other operands from comparisons on the edges
using singleton.  That is `a == CST` and only on the true edge there.  This 
means
in some cases like when we know that `a != 0`, we don't derive information
from `a = b - c` where we notice that `b != c` on that edge too.

I have not measued the compile time or how efficient this is though.
But since most of the time was already added with the r17-4663-gbddea69ee406a
change in register_outgoing_edges; this instead of bypassing for the singleton
case.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/127485

gcc/ChangeLog:

        * gimple-range-fold.cc (fur_source::register_outgoing_edges): Don't
        require a singleton; only not undefined or varying.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/vrp-cmp-sub-1.c: New test.
        * gcc.dg/tree-ssa/vrp-cmp-sub-2.c: New test.
        * gcc.dg/tree-ssa/vrp-cmp-sub-3.c: New test.

Signed-off-by: Andrea Pinski <[email protected]>
---
 gcc/gimple-range-fold.cc                      |  6 ++--
 gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-1.c | 26 ++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-2.c | 30 +++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-3.c | 21 +++++++++++++
 4 files changed, 81 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-2.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-3.c

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index a143c19647a..fceb5121709 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -1770,14 +1770,16 @@ fur_source::register_outgoing_edges (gcond *s, irange 
&lhs_range,
          r1.set_varying (TREE_TYPE (ssa1));
          r2.set_varying (TREE_TYPE (ssa2));
          if (e0 && gori ()->edge_range_p (r, e0, name, *m_query)
-             && r.singleton_p ())
+             && !r.undefined_p ()
+             && !r.varying_p ())
            {
              relation_kind relation = handler.op1_op2_relation (r, r1, r2);
              if (relation != VREL_VARYING)
                register_relation (e0, relation, ssa1, ssa2);
            }
          if (e1 && gori ()->edge_range_p (r, e1, name, *m_query)
-             && r.singleton_p ())
+             && !r.undefined_p ()
+             && !r.varying_p ())
            {
              relation_kind relation = handler.op1_op2_relation (r, r1, r2);
              if (relation != VREL_VARYING)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-1.c
new file mode 100644
index 00000000000..dd81d6ff763
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/127485 */
+
+unsigned fu(unsigned x, unsigned y)
+{
+  unsigned diff = x - y;
+  if (diff > 1)
+   ;
+  else
+    __builtin_unreachable ();
+  return x == y;
+}
+
+signed fs(signed x, signed y)
+{
+  signed diff = x - y;
+  if (diff > 1)
+   ;
+  else
+    __builtin_unreachable ();
+  return x == y;
+}
+
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-2.c
new file mode 100644
index 00000000000..39752aa6fcf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/127485 */
+
+
+unsigned fu(unsigned x, unsigned y)
+{
+  unsigned diff = x - y;
+  if (diff >= 1)
+   ;
+  else
+    __builtin_unreachable ();
+  if (x == y) diff ++ ;
+  return diff;
+}
+
+signed fs(signed x, signed y)
+{
+  signed diff = x - y;
+  if (diff != 0)
+   ;
+  else
+    __builtin_unreachable ();
+  if (x == y) diff ++ ;
+  return diff;
+}
+
+/* { dg-final { scan-tree-dump-not " if " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-3.c 
b/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-3.c
new file mode 100644
index 00000000000..fe3659051df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-cmp-sub-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-evrp" } */
+/* PR tree-optimization/127485 */
+
+void dead (int);
+
+void f (int a, int b)
+{
+  int d = a - b;
+  if (d != 0) // `a - b != 0` -> `a != b`
+    if (a == b)
+      dead (d);
+  return;
+}
+
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " if " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " dead " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
+
+/* { dg-final { scan-tree-dump-not " dead " "evrp" } } */
-- 
2.43.0

Reply via email to