https://gcc.gnu.org/g:1ef005a99c1cda79daf1340677c7d7f01d261216

commit r17-4040-g1ef005a99c1cda79daf1340677c7d7f01d261216
Author: Andrea Pinski <[email protected]>
Date:   Tue Sep 8 12:06:22 2026 -0700

    VN: Fix insert_predicates_for_cond infinite recusion for `a != 0` handling 
[PR127261]
    
    The fix for PR 117859 (r15-5844-ge1009b3de2d057) was not robust
    enough to stop some infinite recusion happening.
    What happens in this case is we have:
    c15_30 = g24_a1.3_8 != c14_12;
    
    And _8 is valueized as 0 and _12 is valueized as _30.
    But we don't realize that _30 didn't change here as
    the comparison is not canonicalized before the testing
    but rather after inside insert_predicates_for_cond.
    
    This adds the canonicalization before testing for infinite
    recusion which allows us to stop the recusion.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/127261
    
    gcc/ChangeLog:
    
            * tree-ssa-sccvn.cc (insert_predicates_for_cond): Canonicalize
            the comparison before testing for recusion.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr127261-1.c: New test.
    
    Signed-off-by: Andrea Pinski <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr127261-1.c | 26 ++++++++++++++++++++++++++
 gcc/tree-ssa-sccvn.cc                     |  7 +++++++
 2 files changed, 33 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr127261-1.c 
b/gcc/testsuite/gcc.dg/torture/pr127261-1.c
new file mode 100644
index 000000000000..8e311ecc1874
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr127261-1.c
@@ -0,0 +1,26 @@
+unsigned short g6, g20;
+bool g24_a1;
+void g24() {
+  bool c10 = 1, c14, c15;
+  unsigned v13;
+lbl_f11_b25:
+  if (g24_a1)
+    goto lbl_f11_b29;
+lbl_f11_b27:
+  goto lbl_f11_b32;
+lbl_f11_b29:
+  g24_a1 = 0;
+  short __ov_tmp_g20;
+  c14 = __builtin_mul_overflow(g6, g20, &__ov_tmp_g20);
+  if (c10)
+    goto lbl_f11_b32;
+lbl_f11_b32:
+  v13 = c15 ? ~00 : 0;
+  c15 = g24_a1 ^ c14 ^ 1 ^ 1;
+  (void)__builtin_clz(v13);
+  if (c14)
+    goto lbl_f11_b27;
+  c10 = 0;
+  goto lbl_f11_b25;
+}
+
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 95b5642ba363..bfc227f7ca0c 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -8430,6 +8430,13 @@ insert_predicates_for_cond (tree_code code, tree lhs, 
tree rhs,
            tree_code nc = gimple_assign_rhs_code (def_stmt);
            tree nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
            tree nrhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
+           // Canonicalize the comparison before the check below,
+           // it might be the case where nlhs is a constant now.
+           if (tree_swap_operands_p (nlhs, nrhs))
+             {
+               std::swap (nlhs, nrhs);
+               nc = swap_tree_comparison (nc);
+             }
            edge nt = true_e;
            edge nf = false_e;
            if (code == EQ_EXPR)

Reply via email to