]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/110176 - wrong zext (bool) <= (int) 4294967295u folding
authorRichard Biener <rguenther@suse.de>
Wed, 31 Jan 2024 13:40:24 +0000 (14:40 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 21 Jun 2024 09:21:29 +0000 (11:21 +0200)
The following fixes a wrong pattern that didn't match the behavior
of the original fold_widened_comparison in that get_unwidened
returned a constant always in the wider type.  But here we're
using (int) 4294967295u without the conversion applied.  Fixed
by doing as earlier in the pattern - matching constants only
if the conversion was actually applied.

PR middle-end/110176
* match.pd (zext (bool) <= (int) 4294967295u): Make sure
to match INTEGER_CST only without outstanding conversion.

* gcc.dg/torture/pr110176.c: New testcase.

(cherry picked from commit 22dbfbe8767ff4c1d93e39f68ec7c2d5b1358beb)

gcc/match.pd
gcc/testsuite/gcc.dg/torture/pr110176.c [new file with mode: 0644]

index d040c8539425f1c61372b3c2af5e25837558b0cc..7f59b1dac8a55ad9f22ca967b3277eaec642a126 100644 (file)
@@ -4712,19 +4712,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
                   >= TYPE_PRECISION (TREE_TYPE (@10)))
                  && (TYPE_UNSIGNED (TREE_TYPE (@00))
                      == TYPE_UNSIGNED (TREE_TYPE (@10))))
-             || (TREE_CODE (@10) == INTEGER_CST
+             || (TREE_CODE (@1) == INTEGER_CST
                  && INTEGRAL_TYPE_P (TREE_TYPE (@00))
-                 && int_fits_type_p (@10, TREE_TYPE (@00)))))
+                 && int_fits_type_p (@1, TREE_TYPE (@00)))))
       (cmp @00 (convert @10))
-      (if (TREE_CODE (@10) == INTEGER_CST
+      (if (TREE_CODE (@1) == INTEGER_CST
           && INTEGRAL_TYPE_P (TREE_TYPE (@00))
-          && !int_fits_type_p (@10, TREE_TYPE (@00)))
+          && !int_fits_type_p (@1, TREE_TYPE (@00)))
        (with
        {
          tree min = lower_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00));
          tree max = upper_bound_in_type (TREE_TYPE (@10), TREE_TYPE (@00));
-         bool above = integer_nonzerop (const_binop (LT_EXPR, type, max, @10));
-         bool below = integer_nonzerop (const_binop (LT_EXPR, type, @10, min));
+         bool above = integer_nonzerop (const_binop (LT_EXPR, type, max, @1));
+         bool below = integer_nonzerop (const_binop (LT_EXPR, type, @1, min));
        }
        (if (above || below)
         (if (cmp == EQ_EXPR || cmp == NE_EXPR)
diff --git a/gcc/testsuite/gcc.dg/torture/pr110176.c b/gcc/testsuite/gcc.dg/torture/pr110176.c
new file mode 100644 (file)
index 0000000..e41e3a0
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+
+int f(_Bool t)
+{
+        int tt = t;
+        unsigned x = -1;
+        int xx = x;
+        return xx <= tt;
+}
+
+int a, b;
+void c() {}
+__attribute__((noipa))
+void h() {__builtin_abort();}
+int d() {
+  unsigned f[1];
+  int i;
+  if (a)
+    goto h;
+  f[0] = -1;
+  while (1) {
+    c();
+    for (; a < 1; a++) {
+      if (0) {
+      j:
+        continue;
+      }
+      i = f[0];
+      if (a)
+        break;
+      b = i >= (b == 0);
+    }
+    if (!b) {
+      if (0) {
+      h:
+        goto j;
+      }
+      return 0;
+    }
+    h();
+  }
+}
+int main() {
+  d();
+  return 0;
+}