]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
MATCH: Avoid recursive zero_one_valued_p for conversions
authorAndrew Pinski <apinski@marvell.com>
Sat, 16 Sep 2023 22:19:58 +0000 (15:19 -0700)
committerAndrew Pinski <apinski@marvell.com>
Mon, 18 Sep 2023 20:45:30 +0000 (13:45 -0700)
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.

gcc/match.pd
gcc/testsuite/gcc.c-torture/compile/pr111435-1.c [new file with mode: 0644]

index a05d4f07ab5b6f89fe09312765277df30aa8d8f2..a405c9ff6f82fa2c440f3ee61fab8bab90179468 100644 (file)
@@ -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 (file)
index 0000000..afa84dd
--- /dev/null
@@ -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);
+}