On Wed, Mar 8, 2017 at 11:53 AM, Andrew Haley <a...@redhat.com> wrote: > Loop splitting is fine when the control variable is of integer type, > but when it is a pointer type the upper bound of the new loop is > calculated incorrectly. > The calculation should be guard_init + (end-beg), but instead we do > guard_init - (end-beg). > > Fixed thusly. Bootstrapped, regtested. > > OK?
Ok. Thanks, Richard. > Andrew. > > > 2017-03-08 Andrew Haley <a...@redhat.com> > > PR tree-optimization/79894 > * tree-ssa-loop-split.c (compute_new_first_bound): When > calculating the new upper bound, (END-BEG) should be added, not > subtracted. > > Index: gcc/tree-ssa-loop-split.c > =================================================================== > --- gcc/tree-ssa-loop-split.c (revision 245948) > +++ gcc/tree-ssa-loop-split.c (working copy) > @@ -436,7 +436,6 @@ > if (POINTER_TYPE_P (TREE_TYPE (guard_init))) > { > enddiff = gimple_convert (stmts, sizetype, enddiff); > - enddiff = gimple_build (stmts, NEGATE_EXPR, sizetype, enddiff); > newbound = gimple_build (stmts, POINTER_PLUS_EXPR, > TREE_TYPE (guard_init), > guard_init, enddiff); > > > 2017-03-08 Andrew Haley <a...@redhat.com> > > PR tree-optimization/79894 > * gcc.dg/tree-ssa/pr79943.c: New test. > > Index: gcc/testsuite/gcc.dg/tree-ssa/pr79943.c > =================================================================== > --- gcc/testsuite/gcc.dg/tree-ssa/pr79943.c (revision 0) > +++ gcc/testsuite/gcc.dg/tree-ssa/pr79943.c (revision 0) > @@ -0,0 +1,40 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 -fsplit-loops -fdump-tree-lsplit-details" } */ > +/* { dg-require-effective-target int32plus } */ > + > +#ifdef __cplusplus > +extern "C" void abort (void); > +#else > +extern void abort (void); > +#endif > + > +typedef struct { > + int n; > +} region_t; > + > +void set (region_t *region) __attribute__((noinline)); > +void doit (region_t *beg, region_t *end, region_t *limit) > + __attribute__((noinline)); > + > +region_t regions[10]; > + > +void > +set (region_t *region) { > + region->n = 1; > +} > + > +void > +doit (region_t *beg, region_t *end, region_t *limit) { > + for (region_t *cur = beg; cur < end; cur++) { > + if (cur < limit) { > + set(cur); > + } > + } > +} > + > +int > +main (void) { > + doit(®ions[0], ®ions[2], ®ions[10]); > + if (regions[1].n != 1) > + abort(); > +}