re PR lto/83338 (SPEC CPU2017 510.parest_r ICE)
authorJakub Jelinek <jakub@redhat.com>
Sat, 9 Dec 2017 11:43:31 +0000 (12:43 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 9 Dec 2017 11:43:31 +0000 (12:43 +0100)
PR tree-optimization/83338
* tree-vect-stmts.c (vectorizable_operation): Handle POINTER_DIFF_EXPR
vectorization as MINUS_EXPR with a subsequent VIEW_CONVERT_EXPR from
vector of unsigned integers to vector of signed integers.

* gcc.dg/vect/pr83338.c: New test.

From-SVN: r255523

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

index 973fb15be93e8b475f41f0ee632dcc9ae82174dc..5d9bf779c8cdb3732af1930a6ee248963bf438db 100644 (file)
@@ -1,3 +1,10 @@
+2017-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/83338
+       * tree-vect-stmts.c (vectorizable_operation): Handle POINTER_DIFF_EXPR
+       vectorization as MINUS_EXPR with a subsequent VIEW_CONVERT_EXPR from
+       vector of unsigned integers to vector of signed integers.
+
 2017-12-08  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR rtl-optimization/83317
index 99842f0622aff7184db76c760893ff2c8b006f74..1653d6b57099a5725d4facd10ea41b55c07cd3b7 100644 (file)
@@ -1,3 +1,8 @@
+2017-12-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/83338
+       * gcc.dg/vect/pr83338.c: New test.
+
 2017-12-09  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/83316
diff --git a/gcc/testsuite/gcc.dg/vect/pr83338.c b/gcc/testsuite/gcc.dg/vect/pr83338.c
new file mode 100644 (file)
index 0000000..e266063
--- /dev/null
@@ -0,0 +1,10 @@
+/* PR tree-optimization/83338 */
+/* { dg-do compile } */
+
+void
+foo (char **p, char **q, __PTRDIFF_TYPE__ *r)
+{
+  int i;
+  for (i = 0; i < 1024; i++)
+    r[i] = p[i] - q[i];
+}
index 2bebad152ebee1105b572abc62120dd7f17efd3f..0c343d4e7d9ba3758416e3761c31230e31ff9284 100644 (file)
@@ -5226,7 +5226,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   tree vectype;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
-  enum tree_code code;
+  enum tree_code code, orig_code;
   machine_mode vec_mode;
   tree new_temp;
   int op_type;
@@ -5264,7 +5264,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
     return false;
 
-  code = gimple_assign_rhs_code (stmt);
+  orig_code = code = gimple_assign_rhs_code (stmt);
 
   /* For pointer addition and subtraction, we should use the normal
      plus and minus for the vector operation.  */
@@ -5455,6 +5455,14 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
   /* Handle def.  */
   vec_dest = vect_create_destination_var (scalar_dest, vectype);
 
+  /* POINTER_DIFF_EXPR has pointer arguments which are vectorized as
+     vectors with unsigned elements, but the result is signed.  So, we
+     need to compute the MINUS_EXPR into vectype temporary and
+     VIEW_CONVERT_EXPR it into the final vectype_out result.  */
+  tree vec_cvt_dest = NULL_TREE;
+  if (orig_code == POINTER_DIFF_EXPR)
+    vec_cvt_dest = vect_create_destination_var (scalar_dest, vectype_out);
+
   /* In case the vectorization factor (VF) is bigger than the number
      of elements that we can fit in a vectype (nunits), we have to generate
      more than one vector stmt - i.e - we need to "unroll" the
@@ -5546,6 +5554,15 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
          new_temp = make_ssa_name (vec_dest, new_stmt);
          gimple_assign_set_lhs (new_stmt, new_temp);
          vect_finish_stmt_generation (stmt, new_stmt, gsi);
+         if (vec_cvt_dest)
+           {
+             new_temp = build1 (VIEW_CONVERT_EXPR, vectype_out, new_temp);
+             new_stmt = gimple_build_assign (vec_cvt_dest, VIEW_CONVERT_EXPR,
+                                             new_temp);
+             new_temp = make_ssa_name (vec_cvt_dest, new_stmt);
+             gimple_assign_set_lhs (new_stmt, new_temp);
+             vect_finish_stmt_generation (stmt, new_stmt, gsi);
+           }
           if (slp_node)
            SLP_TREE_VEC_STMTS (slp_node).quick_push (new_stmt);
         }