https://gcc.gnu.org/g:3526c3b792cc55d00a0585639baa5a6810899df1
commit r17-4864-g3526c3b792cc55d00a0585639baa5a6810899df1 Author: Aldy Hernandez <[email protected]> Date: Sat Oct 3 15:30:23 2026 +0000 VRP: fold a LE or GE test between two names to an equality When x <= y and the relation oracle knows VREL_GE, it can only mean x == y. Similarly for x >= y with VREL_LE. The oracle already derives the equality for the ranger. This is for passes that rewrite the IL. Since this is a statement change it lives in the simplifier, not range-ops. DOM does this from its expression table. This patch just find a better home for it. In a follow-up, I will replace the DOM code with a simplify_using_ranges call. Tested on ppc64le Linux. gcc/ChangeLog: * vr-values.cc (simplify_using_ranges::simplify_compare_using_ranges_1): Fold a LE or GE test between two names to EQ when the relation oracle implies it. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/vrp-le-ge-relation-1.c: New test. Diff: --- .../gcc.dg/tree-ssa/vrp-le-ge-relation-1.c | 31 ++++++++++++++++++++++ gcc/vr-values.cc | 14 ++++++++++ 2 files changed, 45 insertions(+) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp-le-ge-relation-1.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp-le-ge-relation-1.c new file mode 100644 index 000000000000..5dd9d0751e4a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp-le-ge-relation-1.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fgimple -fdump-tree-evrp" } */ + +/* i >= j where i <= j holds is i == j. */ + +void frob (void); + +void __GIMPLE (ssa,startwith("evrp")) +f (int i, int j) +{ + __BB(2): + if (i_1(D) <= j_2(D)) + goto __BB3; + else + goto __BB5; + + __BB(3): + if (i_1(D) >= j_2(D)) + goto __BB4; + else + goto __BB5; + + __BB(4): + frob (); + goto __BB5; + + __BB(5): + return; +} + +/* { dg-final { scan-tree-dump "if \\(i_1\\(D\\) == j_2\\(D\\)\\)" "evrp" } } */ diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc index c4edff871f06..11424c21d03e 100644 --- a/gcc/vr-values.cc +++ b/gcc/vr-values.cc @@ -1209,6 +1209,20 @@ simplify_using_ranges::simplify_compare_using_ranges_1 (tree_code &cond_code, tr } } } + // If OP0 >= OP1 and the relation between them is VREL_LE (or vice + // versa), we know OP0 == OP1. + else if ((cond_code == LE_EXPR || cond_code == GE_EXPR) + && gimple_range_ssa_p (op0) + && gimple_range_ssa_p (op1)) + { + relation_kind rel = query->relation ().query (stmt, op0, op1); + if (relation_intersect (cond_code == LE_EXPR ? VREL_LE : VREL_GE, rel) + == VREL_EQ) + { + cond_code = EQ_EXPR; + happened = true; + } + } // Try to simplify casted conditions. if (simplify_casted_compare (cond_code, op0, op1)) happened = true;
