On Wed, Mar 8, 2017 at 11:53 AM, Andrew Haley 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
>
> 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
>
> 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([0], [2], [10]);
> + if (regions[1].n != 1)
> +abort();
> +}