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