Unshare DR_STEP before gimplifying it
authorRichard Sandiford <richard.sandiford@arm.com>
Sun, 29 Dec 2019 09:28:34 +0000 (09:28 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 29 Dec 2019 09:28:34 +0000 (09:28 +0000)
In this testcase we use an unmasked SVE loop with an Advanced SIMD
epilogue (because we don't yet support fully-masked downward loops).
The main loop uses a gather load for the strided access while the
epilogue loop builds the access from scalars instead.  In both cases
we gimplify expressions based on the DR_STEP and insert them in the
loop preheader.

The problem was that the gather load code didn't copy the DR_STEP before
gimplifying it, meaning that the epilogue loop tried to reuse a result
from the (non-dominating) main loop preheader.

It looks at first glance like there could be other instances of this too,
but this patch just deals with the gather/scatter case.

2019-12-29  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* tree-vect-stmts.c (vect_get_strided_load_store_ops): Copy
DR_STEP before gimplifying it.

gcc/testsuite/
* gcc.dg/vect/vect-strided-epilogue-1.c: New test.

From-SVN: r279753

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-strided-epilogue-1.c [new file with mode: 0644]
gcc/tree-vect-stmts.c

index fc7af987cdf54873644f28d663471f3977b1db1f..1630efd1ac0a854ba6c5f95c6e46bd399f060a5a 100644 (file)
@@ -1,3 +1,8 @@
+2019-12-29  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * tree-vect-stmts.c (vect_get_strided_load_store_ops): Copy
+       DR_STEP before gimplifying it.
+
 2019-12-29  Richard Sandiford  <richard.sandiford@arm.com>
 
        * tree-vect-stmts.c (vectorizable_condition): For extract-last
index 2e0f36410df9733fd4cf276d57ddd7fcbd12b0f9..d3079d30304459d1b2ff0dbede2db889d7a875b4 100644 (file)
@@ -1,3 +1,7 @@
+2019-12-29  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * gcc.dg/vect/vect-strided-epilogue-1.c: New test.
+
 2019-12-29  Richard Sandiford  <richard.sandiford@arm.com>
 
        * gcc.dg/vect/vect-cond-12.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-epilogue-1.c b/gcc/testsuite/gcc.dg/vect/vect-strided-epilogue-1.c
new file mode 100644 (file)
index 0000000..e316706
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+void
+f (int *x, short *y, int z)
+{
+  for (int i = 0; i < 0x82; ++i)
+    x[-i] += x[z * i];
+}
index feb0b7eb7b3c2526a5ca5794129a87195ed3a92e..d4468083cd0b1288b06b4e22436a592f1516f502 100644 (file)
@@ -2993,7 +2993,7 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info,
   gimple_seq stmts;
 
   tree bump = size_binop (MULT_EXPR,
-                         fold_convert (sizetype, DR_STEP (dr)),
+                         fold_convert (sizetype, unshare_expr (DR_STEP (dr))),
                          size_int (TYPE_VECTOR_SUBPARTS (vectype)));
   *dataref_bump = force_gimple_operand (bump, &stmts, true, NULL_TREE);
   if (stmts)
@@ -3005,7 +3005,7 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info,
   offset_type = TREE_TYPE (gs_info->offset_vectype);
 
   /* Calculate X = DR_STEP / SCALE and convert it to the appropriate type.  */
-  tree step = size_binop (EXACT_DIV_EXPR, DR_STEP (dr),
+  tree step = size_binop (EXACT_DIV_EXPR, unshare_expr (DR_STEP (dr)),
                          ssize_int (gs_info->scale));
   step = fold_convert (offset_type, step);
   step = force_gimple_operand (step, &stmts, true, NULL_TREE);