]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/108793 - niter compute type mismatch
authorRichard Biener <rguenther@suse.de>
Mon, 20 Feb 2023 11:58:50 +0000 (12:58 +0100)
committerRichard Biener <rguenther@suse.de>
Tue, 21 Feb 2023 13:02:58 +0000 (14:02 +0100)
When computing the number of iterations until wrap types are mixed up,
eventually leading to checking ICEs with a pointer bitwise inversion.
The following uses niter_type for the calculation.

PR tree-optimization/108793
* tree-ssa-loop-niter.cc (number_of_iterations_until_wrap):
Use convert operands to niter_type when computing num.

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

gcc/testsuite/gcc.dg/torture/pr108793.c [new file with mode: 0644]
gcc/tree-ssa-loop-niter.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr108793.c b/gcc/testsuite/gcc.dg/torture/pr108793.c
new file mode 100644 (file)
index 0000000..83973eb
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+typedef int *p;
+extern p a[], b[];
+int f () {
+  int n = 0;
+  for (p* i = &a[0]; i > &b[0]; i++)
+    n++;
+  return n;
+}
index 1ce5e736ce39a39ad8f3138f2174cfcca9ee0d01..dc4c7a418f644160f6ee48a190c8bebf70f8914f 100644 (file)
@@ -1494,8 +1494,9 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0,
       if (integer_zerop (assumptions))
        return false;
 
-      num = fold_build2 (MINUS_EXPR, niter_type, wide_int_to_tree (type, max),
-                        iv1->base);
+      num = fold_build2 (MINUS_EXPR, niter_type,
+                        wide_int_to_tree (niter_type, max),
+                        fold_convert (niter_type, iv1->base));
 
       /* When base has the form iv + 1, if we know iv >= n, then iv + 1 < n
         only when iv + 1 overflows, i.e. when iv == TYPE_VALUE_MAX.  */
@@ -1531,8 +1532,9 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0,
       if (integer_zerop (assumptions))
        return false;
 
-      num = fold_build2 (MINUS_EXPR, niter_type, iv0->base,
-                        wide_int_to_tree (type, min));
+      num = fold_build2 (MINUS_EXPR, niter_type,
+                        fold_convert (niter_type, iv0->base),
+                        wide_int_to_tree (niter_type, min));
       low = min;
       if (TREE_CODE (iv0->base) == INTEGER_CST)
        high = wi::to_wide (iv0->base) + 1;
@@ -1546,7 +1548,6 @@ number_of_iterations_until_wrap (class loop *loop, tree type, affine_iv *iv0,
 
   /* (delta + step - 1) / step */
   step = fold_convert (niter_type, step);
-  num = fold_convert (niter_type, num);
   num = fold_build2 (PLUS_EXPR, niter_type, num, step);
   niter->niter = fold_build2 (FLOOR_DIV_EXPR, niter_type, num, step);