re PR tree-optimization/81303 (410.bwaves regression caused by r249919)
authorRichard Biener <rguenther@suse.de>
Fri, 8 Dec 2017 08:06:31 +0000 (08:06 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 8 Dec 2017 08:06:31 +0000 (08:06 +0000)
2017-12-08  Richard Biener  <rguenther@suse.de>

PR tree-optimization/81303
* tree-vect-stmts.c (vect_is_simple_cond): For invariant
conditions try to create a comparison vector type matching
the data vector type.
(vectorizable_condition): Adjust.
* tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
Leave invariant conditions alone in case we can vectorize those.

* gcc.target/i386/vectorize9.c: New testcase.
* gcc.target/i386/vectorize10.c: New testcase.

From-SVN: r255497

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/vectorize10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/vectorize9.c [new file with mode: 0644]
gcc/tree-vect-patterns.c
gcc/tree-vect-stmts.c

index 1d20dc5234c74390c2a153a8ffda2dbbb1399c23..a666d115e3786076e7d765a9be28411154b4ba9d 100644 (file)
@@ -1,3 +1,13 @@
+2017-12-08  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81303
+       * tree-vect-stmts.c (vect_is_simple_cond): For invariant
+       conditions try to create a comparison vector type matching
+       the data vector type.
+       (vectorizable_condition): Adjust.
+       * tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
+       Leave invariant conditions alone in case we can vectorize those.
+
 2017-12-08  Julia Koval  <julia.koval@intel.com>
 
        * config/i386/avx512vnniintrin.h (_mm512_dpwssd_epi32,
index b13130d445415b0800895faadcf5cfcca0899445..8324d4f3ad4bde437bd11787e6e98208dd36c2e3 100644 (file)
@@ -1,3 +1,9 @@
+2017-12-08  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81303
+       * gcc.target/i386/vectorize9.c: New testcase.
+       * gcc.target/i386/vectorize10.c: New testcase.
+
 2017-12-08  Julia Koval  <julia.koval@intel.com>
 
        * gcc.target/i386/avx512f-vnni-1.c: Add vdpwssd checks.
diff --git a/gcc/testsuite/gcc.target/i386/vectorize10.c b/gcc/testsuite/gcc.target/i386/vectorize10.c
new file mode 100644 (file)
index 0000000..4353aec
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-loop-vectorize -fdump-tree-vect-details -fno-tree-loop-im -msse2 -mno-avx" } */
+
+double x[1024][1024], red[1024];
+void foo (void)
+{
+  for (int i = 0; i < 1024; ++i)
+    for (int j = 0; j < 1024; ++j)
+      {
+       double v = i == 0 ? 0.0 : red[j];
+       v = v + x[i][j];
+       red[j] = v;
+      }
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vectorize9.c b/gcc/testsuite/gcc.target/i386/vectorize9.c
new file mode 100644 (file)
index 0000000..3f02be4
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-loop-vectorize -fdump-tree-vect-details -fno-tree-loop-im -mavx2 -mprefer-vector-width=256" } */
+
+double x[1024][1024], red[1024];
+void foo (void)
+{
+  for (int i = 0; i < 1024; ++i)
+    for (int j = 0; j < 1024; ++j)
+      {
+       double v = i == 0 ? 0.0 : red[j];
+       v = v + x[i][j];
+       red[j] = v;
+      }
+}
+
+/* { dg-final { scan-tree-dump "vectorization factor = 4" "vect" } } */
index e4051b68dd0188b99b0e1d27f5180f40eaa9d2bf..a2c629309e021dad46bbe3ea5e66d149e5286961 100644 (file)
@@ -3976,6 +3976,32 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
          || TYPE_VECTOR_SUBPARTS (vectype1) == TYPE_VECTOR_SUBPARTS (vectype2))
        return NULL;
 
+      /* If rhs1 is invariant and we can promote it leave the COND_EXPR
+         in place, we can handle it in vectorizable_condition.  This avoids
+        unnecessary promotion stmts and increased vectorization factor.  */
+      if (COMPARISON_CLASS_P (rhs1)
+         && INTEGRAL_TYPE_P (rhs1_type)
+         && TYPE_VECTOR_SUBPARTS (vectype1) < TYPE_VECTOR_SUBPARTS (vectype2))
+       {
+         gimple *dummy;
+         enum vect_def_type dt;
+         if (vect_is_simple_use (TREE_OPERAND (rhs1, 0), stmt_vinfo->vinfo,
+                                 &dummy, &dt)
+             && dt == vect_external_def
+             && vect_is_simple_use (TREE_OPERAND (rhs1, 1), stmt_vinfo->vinfo,
+                                    &dummy, &dt)
+             && (dt == vect_external_def
+                 || dt == vect_constant_def))
+           {
+             tree wide_scalar_type = build_nonstandard_integer_type
+               (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype1))),
+                TYPE_UNSIGNED (rhs1_type));
+             tree vectype3 = get_vectype_for_scalar_type (wide_scalar_type);
+             if (expand_vec_cond_expr_p (vectype1, vectype3, TREE_CODE (rhs1)))
+               return NULL;
+           }
+       }
+
       /* If rhs1 is a comparison we need to move it into a
         separate statement.  */
       if (TREE_CODE (rhs1) != SSA_NAME)
index ee2f1ca1ccdb279c573b2e361fb4ce2350d59e14..2bebad152ebee1105b572abc62120dd7f17efd3f 100644 (file)
@@ -7791,7 +7791,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
 
 static bool
 vect_is_simple_cond (tree cond, vec_info *vinfo,
-                    tree *comp_vectype, enum vect_def_type *dts)
+                    tree *comp_vectype, enum vect_def_type *dts,
+                    tree vectype)
 {
   tree lhs, rhs;
   tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
@@ -7844,6 +7845,20 @@ vect_is_simple_cond (tree cond, vec_info *vinfo,
     return false;
 
   *comp_vectype = vectype1 ? vectype1 : vectype2;
+  /* Invariant comparison.  */
+  if (! *comp_vectype)
+    {
+      tree scalar_type = TREE_TYPE (lhs);
+      /* If we can widen the comparison to match vectype do so.  */
+      if (INTEGRAL_TYPE_P (scalar_type)
+         && tree_int_cst_lt (TYPE_SIZE (scalar_type),
+                             TYPE_SIZE (TREE_TYPE (vectype))))
+       scalar_type = build_nonstandard_integer_type
+         (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (vectype))),
+          TYPE_UNSIGNED (scalar_type));
+      *comp_vectype = get_vectype_for_scalar_type (scalar_type);
+    }
+
   return true;
 }
 
@@ -7941,7 +7956,7 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
   else_clause = gimple_assign_rhs3 (stmt);
 
   if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo,
-                           &comp_vectype, &dts[0])
+                           &comp_vectype, &dts[0], vectype)
       || !comp_vectype)
     return false;