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