aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-01-09 10:31:51 +0100
committerJakub Jelinek <jakub@redhat.com>2024-01-09 10:31:51 +0100
commitb1d4e5b51375efd285378173375d634ad6ba8462 (patch)
tree3448d9754e51e55f36534e647fb08db2cb669594
parent4d3fd59953bcf423dd0859a2c6b95b5260aed71d (diff)
downloadgcc-b1d4e5b51375efd285378173375d634ad6ba8462.zip
gcc-b1d4e5b51375efd285378173375d634ad6ba8462.tar.gz
gcc-b1d4e5b51375efd285378173375d634ad6ba8462.tar.bz2
vect: Ensure both NITERSM1 and NITERS are INTEGER_CSTs or neither of them [PR113210]
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.
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr113210.c13
-rw-r--r--gcc/tree-vect-loop.cc13
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr113210.c b/gcc/testsuite/gcc.c-torture/compile/pr113210.c
new file mode 100644
index 0000000..0aa0780
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr113210.c
@@ -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)
+ ;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 9dd573e..cfea907 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -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;
}