aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@marvell.com>2023-09-16 15:19:58 -0700
committerAndrew Pinski <apinski@marvell.com>2023-09-18 13:45:30 -0700
commit951d3c191d01440ad54415f683437770b0c957e4 (patch)
treef3ddd452db2b9e8bc7f0d1f3f5aa2e48d1431729
parent80968d5f4683ffb50dbe8051d10f754d5fd00dfb (diff)
downloadgcc-951d3c191d01440ad54415f683437770b0c957e4.zip
gcc-951d3c191d01440ad54415f683437770b0c957e4.tar.gz
gcc-951d3c191d01440ad54415f683437770b0c957e4.tar.bz2
MATCH: Avoid recursive zero_one_valued_p for conversions
So when VN finds a name which has a nop conversion, it says both names are equivalent to each other and the valuaization function for one will return the other. This normally does not cause any issues as there is no recursive matches. But after r14-4038-gb975c0dc3be285, there was one added. So we would do an infinite recursion on the match and never finish. This fixes the issue (and adds a comment in match.pd) by for converts just handle one level instead of being recursive always. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Note the testcase was reduced from tree-ssa-loop-niter.cc and then changed slightly into C rather than C++ but it still needs exceptions turned on get the IR that VN would produce this equivalence relationship going on. Also had to turn off early inline to force put to be inlined later. PR tree-optimization/111435 gcc/ChangeLog: * match.pd (zero_one_valued_p): Don't do recursion on converts. gcc/testsuite/ChangeLog: * gcc.c-torture/compile/pr111435-1.c: New test.
-rw-r--r--gcc/match.pd8
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr111435-1.c18
2 files changed, 25 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index a05d4f0..a405c9f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2188,8 +2188,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* A conversion from an zero_one_valued_p is still a [0,1].
This is useful when the range of a variable is not known */
+/* Note this matches can't be recursive because of the way VN handles
+ nop conversions being equivalent and then recursive between them. */
(match zero_one_valued_p
- (convert@0 zero_one_valued_p))
+ (convert@0 @1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+ && (TYPE_UNSIGNED (TREE_TYPE (@1))
+ || TYPE_PRECISION (TREE_TYPE (@1)) > 1)
+ && wi::leu_p (tree_nonzero_bits (@1), 1))))
/* Transform { 0 or 1 } * { 0 or 1 } into { 0 or 1 } & { 0 or 1 }. */
(simplify
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr111435-1.c b/gcc/testsuite/gcc.c-torture/compile/pr111435-1.c
new file mode 100644
index 0000000..afa84dd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr111435-1.c
@@ -0,0 +1,18 @@
+/* { dg-options "-fexceptions -fno-early-inlining" } */
+/* { dg-require-effective-target exceptions } */
+
+void find_slot_with_hash(const int *);
+
+void put(const int *k, const int *) {
+ find_slot_with_hash(k);
+}
+unsigned len();
+int *address();
+void h(int header, int **bounds) {
+ if (!*bounds)
+ return;
+ unsigned t = *bounds ? len() : 0;
+ int queue_index = t;
+ address()[(unsigned)queue_index] = 0;
+ put(&header, &queue_index);
+}