diff --git a/gcc/testsuite/gcc.dg/vect/pr81196-2.c b/gcc/testsuite/gcc.dg/vect/pr81196-2.c new file mode 100644 index 00000000000..8d5ce6bad53 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr81196-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void b (int *p) +{ + p = (int *)__builtin_assume_aligned(p, __BIGGEST_ALIGNMENT__); + int *q = p + 255; + for(; p < q; ++p, --q) + { + int t = *p; + *p = *q; + *q = t; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 04c209561d8..d33095b8e03 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -1915,14 +1915,23 @@ number_of_iterations_cond (class loop *loop, } /* If the new step of IV0 has changed sign or is of greater magnitude then we do not know whether IV0 does overflow - and thus the transform is not valid for code other than NE_EXPR */ + and thus the transform is not valid for code other than NE_EXPR. */ else if (tree_int_cst_sign_bit (step) != tree_int_cst_sign_bit (iv0->step) || wi::gtu_p (wi::abs (wi::to_widest (step)), wi::abs (wi::to_widest (iv0->step)))) { - if (code != NE_EXPR) + if (POINTER_TYPE_P (type) && code != NE_EXPR) + /* For relational pointer compares we have further guarantees + that the pointers always point to the same object (or one + after it) and that objects do not cross the zero page. So + not only is the transform always valid for relational + pointer compares, we also know the resulting IV does not + overflow. */ + ; + else if (code != NE_EXPR) return false; - iv0->no_overflow = false; + else + iv0->no_overflow = false; } iv0->step = step;