https://gcc.gnu.org/g:08cc07aedf61cf69d6de3661728345572d7217d3
commit r17-5097-g08cc07aedf61cf69d6de3661728345572d7217d3 Author: Andrea Pinski <[email protected]> Date: Sat Sep 26 09:05:35 2026 -0700 range-ops: Allow for non singleton for deriving from comparisons [PR127485] 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]> Diff: --- 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(-) diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 9ac5a94341cf..a66993a0ab0a 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -1866,14 +1866,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 000000000000..dd81d6ff7634 --- /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 000000000000..39752aa6fcf0 --- /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 000000000000..fe3659051df9 --- /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" } } */
