tree-optimization/104214 - amend PR100740 fix for pointer compares
When we have a pointer relational compare we have stronger guarantees about overflow, in particular rewriting BASE0 + STEP0 cmp BASE1 + STEP1 as BASE0 + STEP0 - STEP1 cmp BASE1 is always valid and the new IV0 does not overflow. The patch basically reverts the previous change when pointers are involved, keeping only the more conservative handling for equality compares which can involve comparing different object addresses. 2022-01-25 Richard Biener <rguenther@suse.de> PR tree-optimization/104214 * tree-ssa-loop-niter.cc (number_of_iterations_cond): Use stronger guarantees for relational pointer compares when rewriting BASE0 + STEP0 cmp BASE1 + STEP1 as BASE0 + STEP0 - STEP1 cmp BASE1. * gcc.dg/vect/pr81196-2.c: New variant testcase only requiring vect_int.
This commit is contained in:
parent
ab2a245778
commit
2e211a0229
2 changed files with 28 additions and 3 deletions
16
gcc/testsuite/gcc.dg/vect/pr81196-2.c
Normal file
16
gcc/testsuite/gcc.dg/vect/pr81196-2.c
Normal file
|
@ -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" } } */
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue