Unshare DR_STEP before gimplifying it

Richard Sandiford richard.sandiford@arm.com
Sat Dec 28 16:38:00 GMT 2019


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.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?

Richard


2019-12-28  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.

Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	2019-12-28 16:28:16.344143831 +0000
+++ gcc/tree-vect-stmts.c	2019-12-28 16:29:52.003499967 +0000
@@ -2993,7 +2993,7 @@ vect_get_strided_load_store_ops (stmt_ve
   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_ve
   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);
Index: gcc/testsuite/gcc.dg/vect/vect-strided-epilogue-1.c
===================================================================
--- /dev/null	2019-09-17 11:41:18.176664108 +0100
+++ gcc/testsuite/gcc.dg/vect/vect-strided-epilogue-1.c	2019-12-28 16:29:52.003499967 +0000
@@ -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];
+}



More information about the Gcc-patches mailing list