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]>
---
 gcc/testsuite/gcc.dg/torture/pr127261-1.c | 26 +++++++++++++++++++++++
 gcc/tree-ssa-sccvn.cc                     |  7 ++++++
 2 files changed, 33 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr127261-1.c

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 00000000000..8e311ecc187
--- /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 dbb19e4a498..05e0de8dc38 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -8419,6 +8419,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)
-- 
2.43.0

Reply via email to