]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vect: Ensure both NITERSM1 and NITERS are INTEGER_CSTs or neither of them [PR113210]
authorJakub Jelinek <jakub@redhat.com>
Tue, 9 Jan 2024 09:31:51 +0000 (10:31 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 9 Jan 2024 09:31:51 +0000 (10:31 +0100)
On the following testcase e.g. on riscv64 or aarch64 (latter with
-O3 -march=armv8-a+sve ) we ICE, because while NITERS is INTEGER_CST,
NITERSM1 is a complex expression like
(short unsigned int) (a.0_1 + 255) + 1 > 256 ? ~(short unsigned int) (a.0_1 + 255) : 0
where a.0_1 is unsigned char.  The condition is never true, so the above
is equivalent to just 0, but only when trying to fold the above with
PLUS_EXPR 1 we manage to simplify it (first
~(short unsigned int) (a.0_1 + 255)
to
-(short unsigned int) (a.0_1 + 255)
and then
(short unsigned int) (a.0_1 + 255) + 1 > 256 ? -(short unsigned int) (a.0_1 + 255) : 1
to
(short unsigned int) (a.0_1 + 255) >= 256 ? -(short unsigned int) (a.0_1 + 255) : 1
and only at this point we fold the condition to be false.

But the vectorizer seems to assume that if NITERS is known (i.e. suitable
INTEGER_CST) then NITERSM1 also is, so the following hack ensures that if
NITERS folds into INTEGER_CST NITERSM1 will be one as well.

2024-01-09  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/113210
* tree-vect-loop.cc (vect_get_loop_niters): If non-INTEGER_CST
value in *number_of_iterationsm1 PLUS_EXPR 1 is folded into
INTEGER_CST, recompute *number_of_iterationsm1 as the INTEGER_CST
minus 1.

* gcc.c-torture/compile/pr113210.c: New test.

gcc/testsuite/gcc.c-torture/compile/pr113210.c [new file with mode: 0644]
gcc/tree-vect-loop.cc

diff --git a/gcc/testsuite/gcc.c-torture/compile/pr113210.c b/gcc/testsuite/gcc.c-torture/compile/pr113210.c
new file mode 100644 (file)
index 0000000..0aa0780
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR tree-optimization/113210 */
+
+unsigned char a, c;
+unsigned short b;
+
+void
+foo (void)
+{
+  c = a + 255;
+  b = c;
+  while (++b > 256)
+    ;
+}
index 9dd573ef12541823400cf21ccb3446ff699f285f..cfea9074830aa60a8c1ac7eaadf9e02f84896357 100644 (file)
@@ -941,9 +941,22 @@ vect_get_loop_niters (class loop *loop, const_edge main_exit, tree *assumptions,
         ???  For UINT_MAX latch executions this number overflows to zero
         for loops like do { n++; } while (n != 0);  */
       if (niter && !chrec_contains_undetermined (niter))
+       {
          niter = fold_build2 (PLUS_EXPR, TREE_TYPE (niter),
                               unshare_expr (niter),
                               build_int_cst (TREE_TYPE (niter), 1));
+         if (TREE_CODE (niter) == INTEGER_CST
+             && TREE_CODE (*number_of_iterationsm1) != INTEGER_CST)
+           {
+             /* If we manage to fold niter + 1 into INTEGER_CST even when
+                niter is some complex expression, ensure back
+                *number_of_iterationsm1 is an INTEGER_CST as well.  See
+                PR113210.  */
+             *number_of_iterationsm1
+               = fold_build2 (PLUS_EXPR, TREE_TYPE (niter), niter,
+                              build_minus_one_cst (TREE_TYPE (niter)));
+           }
+       }
       *number_of_iterations = niter;
     }