From 0f76c81784532b94f15dad27e7aa1b68f1832969 Mon Sep 17 00:00:00 2001
From: Kaipeng Zhou <zhoukaipeng3@huawei.com>
Date: Sat, 13 Jun 2020 23:38:40 +0800
Subject: [PATCH] vect: CSE for bump and offset in strided load/store
 operations.

Every time "vect_get_strided_load_store_ops" is called, new bump and offset
variables and a series of stmts are created.  And IVOPTs is not able to
eliminate them.  The patch use "cse_and_gimplify_to_preheader" to CSE them.

2020-06-16  Bin Cheng <bin.cheng@linux.alibaba.com>
	    Kaipeng Zhou  <zhoukaipeng3@huawei.com>

	PR tree-optimization/95199
	* tree-vect-stmts.c: Eliminate common stmts for bump and offset in
	strided load/store operations and remove redundant code.

2020-06-16  Bin Cheng <bin.cheng@linux.alibaba.com>
	    Kaipeng Zhou  <zhoukaipeng3@huawei.com>

	PR tree-optimization/95199
	* gcc.target/aarch64/sve/pr95199.c: New test.
---
 gcc/ChangeLog                                  |  7 +++++++
 gcc/testsuite/ChangeLog                        |  6 ++++++
 gcc/testsuite/gcc.target/aarch64/sve/pr95199.c | 17 +++++++++++++++++
 gcc/tree-vect-stmts.c                          | 17 +++++------------
 4 files changed, 35 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr95199.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c92582df7fe..24d3c7124bf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2020-06-16  Bin Cheng <bin.cheng@linux.alibaba.com>
+	    Kaipeng Zhou  <zhoukaipeng3@huawei.com>
+
+	PR tree-optimization/95199
+	* tree-vect-stmts.c: Eliminate common stmts for bump and offset in
+	strided load/store operations and remove redundant code.
+
 2020-06-08  Tobias Burnus  <tobias@codesourcery.com>
 
 	PR lto/94848
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 60d9ecca3ed..9a69bad698c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-06-16  Bin Cheng <bin.cheng@linux.alibaba.com>
+	    Kaipeng Zhou  <zhoukaipeng3@huawei.com>
+
+	PR tree-optimization/95199
+	* gcc.target/aarch64/sve/pr95199.c: New test.
+
 2020-06-08  Harald Anlauf  <anlauf@gmx.de>
 
 	PR fortran/95195
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr95199.c b/gcc/testsuite/gcc.target/aarch64/sve/pr95199.c
new file mode 100644
index 00000000000..adcd5124a7c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr95199.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=armv8.2-a+sve -fdump-tree-vect" } */
+
+void
+foo (double *a, double *b, double m, int inc_x, int inc_y)
+{
+  int ix = 0, iy = 0;
+  for (int i = 0; i < 1000; ++i)
+    {
+      a[ix] += m * b[iy];
+      ix += inc_x;
+      iy += inc_y;
+    }
+  return ;
+}
+
+/* { dg-final { scan-tree-dump-times "VEC_SERIES_EXPR" 2 "vect" } } */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index b24b0fe4304..085a5d413e7 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2962,33 +2962,26 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info,
 				 tree *dataref_bump, tree *vec_offset)
 {
   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
-  class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
-  gimple_seq stmts;
 
   tree bump = size_binop (MULT_EXPR,
 			  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)
-    gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+  *dataref_bump = cse_and_gimplify_to_preheader (loop_vinfo, bump);
 
   /* The offset given in GS_INFO can have pointer type, so use the element
      type of the vector instead.  */
-  tree offset_type = TREE_TYPE (gs_info->offset);
-  offset_type = TREE_TYPE (gs_info->offset_vectype);
+  tree 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, 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);
 
   /* Create {0, X, X*2, X*3, ...}.  */
-  *vec_offset = gimple_build (&stmts, VEC_SERIES_EXPR, gs_info->offset_vectype,
-			      build_zero_cst (offset_type), step);
-  if (stmts)
-    gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+  tree offset = fold_build2 (VEC_SERIES_EXPR, gs_info->offset_vectype,
+			     build_zero_cst (offset_type), step);
+  *vec_offset = cse_and_gimplify_to_preheader (loop_vinfo, offset);
 }
 
 /* Return the amount that should be added to a vector pointer to move
-- 
2.19.1

