diff mbox

Loop splitting breaks with loops of pointer type

Message ID e79d7a83-abe2-3008-3d12-3137e9266f84@redhat.com
State New
Headers show

Commit Message

Andrew Haley March 8, 2017, 10:53 a.m. UTC
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?

Andrew.


2017-03-08  Andrew Haley  <aph@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.

Comments

Richard Biener March 8, 2017, 11:03 a.m. UTC | #1
On Wed, Mar 8, 2017 at 11:53 AM, Andrew Haley <aph@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  <aph@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  <aph@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(&regions[0], &regions[2], &regions[10]);
> +  if (regions[1].n != 1)
> +    abort();
> +}
diff mbox

Patch

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  <aph@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(&regions[0], &regions[2], &regions[10]);
+  if (regions[1].n != 1)
+    abort();
+}