re PR tree-optimization/80457 (vectorizable_condition does not update the vectorizer...
authorJames Greenhalgh <james.greenhalgh@arm.com>
Tue, 16 May 2017 20:18:05 +0000 (20:18 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Tue, 16 May 2017 20:18:05 +0000 (20:18 +0000)
[gcc]

2017-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
    Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR tree-optimization/80457
* tree-vect-stmts.c (vect_model_simple_cost): Model the cost
of all arguments to a statement as scalar_to_vec operations.
(vectorizable_call): Adjust call to vect_model_simple_cost for
new parameter.
(vectorizable_conversion): Likewise.
(vectorizable_assignment): Likewise.
(vectorizable_shift): Likewise.
(vectorizable_operation): Likewise.
(vectorizable_comparison): Likewise.
(vect_is_simple_cond): Record the def types for operands.
(vectorizable_condition): Likewise, call vect_model_simple_cost.
* tree-vectorizer.h (vect_model_simple_cost): Add new parameter
for statement argument count.

[gcc/testsuite]

2017-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
    Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR tree-optimization/80457
* gcc.target/powerpc/pr78604.c: Verify that vectorized COND_EXPRs
call vect_model_simple_cost.

Co-Authored-By: Bill Schmidt <wschmidt@linux.vnet.ibm.com>
From-SVN: r248130

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr78604.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index 1cdda6d59147dddbcb496e803380bd565277cfc7..25a2d3b6a908a165ddd1b5c26d77023ce57d0a73 100644 (file)
@@ -1,3 +1,21 @@
+2017-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
+           Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/80457
+       * tree-vect-stmts.c (vect_model_simple_cost): Model the cost
+       of all arguments to a statement as scalar_to_vec operations.
+       (vectorizable_call): Adjust call to vect_model_simple_cost for
+       new parameter.
+       (vectorizable_conversion): Likewise.
+       (vectorizable_assignment): Likewise.
+       (vectorizable_shift): Likewise.
+       (vectorizable_operation): Likewise.
+       (vectorizable_comparison): Likewise.
+       (vect_is_simple_cond): Record the def types for operands.
+       (vectorizable_condition): Likewise, call vect_model_simple_cost.
+       * tree-vectorizer.h (vect_model_simple_cost): Add new parameter
+       for statement argument count.
+
 2017-05-16  Carl Love  <cel@us.ibm.com>
 
        * config/rs6000/rs6000-c: Add support for built-in functions
index b8ea07b10f6750dc6e4c8c2767e00b644b0aa5d8..9572cc49ba98aaf96ee845f4d00f5647892ad913 100644 (file)
@@ -1,3 +1,10 @@
+2017-05-16  James Greenhalgh  <james.greenhalgh@arm.com>
+           Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR tree-optimization/80457
+       * gcc.target/powerpc/pr78604.c: Verify that vectorized COND_EXPRs
+       call vect_model_simple_cost.
+
 2017-05-16  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/80554
index 2ee5ab9b12c7238839a74f9ee0c8220cd0cab034..757328e1a55d70ef01cda5cd910c30b14d598ee1 100644 (file)
@@ -2,7 +2,7 @@
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
 /* { dg-require-effective-target powerpc_p8vector_ok } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
-/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize" } */
+/* { dg-options "-mcpu=power8 -O2 -ftree-vectorize -fdump-tree-details" } */
 
 #ifndef SIZE
 #define SIZE 1024
@@ -110,3 +110,4 @@ uns_gte (UNS_TYPE val1, UNS_TYPE val2)
 /* { dg-final { scan-assembler-times {\mvcmpgtsd\M} 4 } } */
 /* { dg-final { scan-assembler-times {\mvcmpgtud\M} 4 } } */
 /* { dg-final { scan-assembler-not   {\mvcmpequd\M} } } */
+/* { dg-final { scan-tree-dump-times "vect_model_simple_cost" 8 "vect" } } */
index 31349f2b9c13dabbcf138f93bf3e39605539591d..74c9a113082893c700c688b2ab14be87111b95a7 100644 (file)
@@ -801,6 +801,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
 void
 vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies,
                        enum vect_def_type *dt,
+                       int ndts,
                        stmt_vector_for_cost *prologue_cost_vec,
                        stmt_vector_for_cost *body_cost_vec)
 {
@@ -811,10 +812,12 @@ vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies,
   if (PURE_SLP_STMT (stmt_info))
     return;
 
-  /* FORNOW: Assuming maximum 2 args per stmts.  */
-  for (i = 0; i < 2; i++)
+  /* Cost the "broadcast" of a scalar operand in to a vector operand.
+     Use scalar_to_vec to cost the broadcast, as elsewhere in the vector
+     cost model.  */
+  for (i = 0; i < ndts; i++)
     if (dt[i] == vect_constant_def || dt[i] == vect_external_def)
-      prologue_cost += record_stmt_cost (prologue_cost_vec, 1, vector_stmt,
+      prologue_cost += record_stmt_cost (prologue_cost_vec, 1, scalar_to_vec,
                                         stmt_info, 0, vect_prologue);
 
   /* Pass the inside-of-loop statements to the target-specific cost model.  */
@@ -2601,6 +2604,7 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
   gimple *def_stmt;
   enum vect_def_type dt[3]
     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
+  int ndts = 3;
   gimple *new_stmt = NULL;
   int ncopies, j;
   vec<tree> vargs = vNULL;
@@ -2806,7 +2810,7 @@ vectorizable_call (gimple *gs, gimple_stmt_iterator *gsi, gimple **vec_stmt,
       if (dump_enabled_p ())
         dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_call ==="
                          "\n");
-      vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
+      vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
       if (ifn != IFN_LAST && modifier == NARROW && !slp_node)
        add_stmt_cost (stmt_info->vinfo->target_cost_data, ncopies / 2,
                       vec_promote_demote, stmt_info, 0, vect_body);
@@ -4025,6 +4029,7 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
   tree new_temp;
   gimple *def_stmt;
   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
+  int ndts = 2;
   gimple *new_stmt = NULL;
   stmt_vec_info prev_stmt_info;
   int nunits_in;
@@ -4303,7 +4308,7 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
       if (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR)
         {
          STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type;
-         vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
+         vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
        }
       else if (modifier == NARROW)
        {
@@ -4612,7 +4617,8 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi,
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
   tree new_temp;
   gimple *def_stmt;
-  enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
+  enum vect_def_type dt[1] = {vect_unknown_def_type};
+  int ndts = 1;
   int ncopies;
   int i, j;
   vec<tree> vec_oprnds = vNULL;
@@ -4712,7 +4718,7 @@ vectorizable_assignment (gimple *stmt, gimple_stmt_iterator *gsi,
       if (dump_enabled_p ())
         dump_printf_loc (MSG_NOTE, vect_location,
                          "=== vectorizable_assignment ===\n");
-      vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
+      vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
       return true;
     }
 
@@ -4824,6 +4830,7 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
   machine_mode optab_op2_mode;
   gimple *def_stmt;
   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
+  int ndts = 2;
   gimple *new_stmt = NULL;
   stmt_vec_info prev_stmt_info;
   int nunits_in;
@@ -5082,7 +5089,7 @@ vectorizable_shift (gimple *stmt, gimple_stmt_iterator *gsi,
       if (dump_enabled_p ())
         dump_printf_loc (MSG_NOTE, vect_location,
                          "=== vectorizable_shift ===\n");
-      vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
+      vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
       return true;
     }
 
@@ -5198,6 +5205,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
   gimple *def_stmt;
   enum vect_def_type dt[3]
     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
+  int ndts = 3;
   gimple *new_stmt = NULL;
   stmt_vec_info prev_stmt_info;
   int nunits_in;
@@ -5409,7 +5417,7 @@ vectorizable_operation (gimple *stmt, gimple_stmt_iterator *gsi,
       if (dump_enabled_p ())
         dump_printf_loc (MSG_NOTE, vect_location,
                          "=== vectorizable_operation ===\n");
-      vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
+      vect_model_simple_cost (stmt_info, ncopies, dt, ndts, NULL, NULL);
       return true;
     }
 
@@ -7661,15 +7669,16 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
 
    Output:
    *COMP_VECTYPE - the vector type for the comparison.
+   *DTS - The def types for the arguments of the comparison
 
    Returns whether a COND can be vectorized.  Checks whether
    condition operands are supportable using vec_is_simple_use.  */
 
 static bool
-vect_is_simple_cond (tree cond, vec_info *vinfo, tree *comp_vectype)
+vect_is_simple_cond (tree cond, vec_info *vinfo,
+                    tree *comp_vectype, enum vect_def_type *dts)
 {
   tree lhs, rhs;
-  enum vect_def_type dt;
   tree vectype1 = NULL_TREE, vectype2 = NULL_TREE;
 
   /* Mask case.  */
@@ -7678,7 +7687,7 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, tree *comp_vectype)
     {
       gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (cond);
       if (!vect_is_simple_use (cond, vinfo, &lhs_def_stmt,
-                              &dt, comp_vectype)
+                              &dts[0], comp_vectype)
          || !*comp_vectype
          || !VECTOR_BOOLEAN_TYPE_P (*comp_vectype))
        return false;
@@ -7694,21 +7703,25 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, tree *comp_vectype)
   if (TREE_CODE (lhs) == SSA_NAME)
     {
       gimple *lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
-      if (!vect_is_simple_use (lhs, vinfo, &lhs_def_stmt, &dt, &vectype1))
+      if (!vect_is_simple_use (lhs, vinfo, &lhs_def_stmt, &dts[0], &vectype1))
        return false;
     }
-  else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
-          && TREE_CODE (lhs) != FIXED_CST)
+  else if (TREE_CODE (lhs) == INTEGER_CST || TREE_CODE (lhs) == REAL_CST
+          || TREE_CODE (lhs) == FIXED_CST)
+    dts[0] = vect_constant_def;
+  else
     return false;
 
   if (TREE_CODE (rhs) == SSA_NAME)
     {
       gimple *rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
-      if (!vect_is_simple_use (rhs, vinfo, &rhs_def_stmt, &dt, &vectype2))
+      if (!vect_is_simple_use (rhs, vinfo, &rhs_def_stmt, &dts[1], &vectype2))
        return false;
     }
-  else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
-          && TREE_CODE (rhs) != FIXED_CST)
+  else if (TREE_CODE (rhs) == INTEGER_CST || TREE_CODE (rhs) == REAL_CST
+          || TREE_CODE (rhs) == FIXED_CST)
+    dts[1] = vect_constant_def;
+  else
     return false;
 
   if (vectype1 && vectype2
@@ -7748,7 +7761,10 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
   tree vec_compare;
   tree new_temp;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
-  enum vect_def_type dt, dts[4];
+  enum vect_def_type dts[4]
+    = {vect_unknown_def_type, vect_unknown_def_type,
+       vect_unknown_def_type, vect_unknown_def_type};
+  int ndts = 4;
   int ncopies;
   enum tree_code code, cond_code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
   stmt_vec_info prev_stmt_info = NULL;
@@ -7810,15 +7826,16 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
   then_clause = gimple_assign_rhs2 (stmt);
   else_clause = gimple_assign_rhs3 (stmt);
 
-  if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo, &comp_vectype)
+  if (!vect_is_simple_cond (cond_expr, stmt_info->vinfo,
+                           &comp_vectype, &dts[0])
       || !comp_vectype)
     return false;
 
   gimple *def_stmt;
-  if (!vect_is_simple_use (then_clause, stmt_info->vinfo, &def_stmt, &dt,
+  if (!vect_is_simple_use (then_clause, stmt_info->vinfo, &def_stmt, &dts[2],
                           &vectype1))
     return false;
-  if (!vect_is_simple_use (else_clause, stmt_info->vinfo, &def_stmt, &dt,
+  if (!vect_is_simple_use (else_clause, stmt_info->vinfo, &def_stmt, &dts[3],
                           &vectype2))
     return false;
 
@@ -7902,8 +7919,13 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
                return false;
            }
        }
-      return expand_vec_cond_expr_p (vectype, comp_vectype,
-                                    cond_code);
+      if (expand_vec_cond_expr_p (vectype, comp_vectype,
+                                    cond_code))
+       {
+         vect_model_simple_cost (stmt_info, ncopies, dts, ndts, NULL, NULL);
+         return true;
+       }
+      return false;
     }
 
   /* Transform.  */
@@ -8106,6 +8128,7 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
   tree new_temp;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
   enum vect_def_type dts[2] = {vect_unknown_def_type, vect_unknown_def_type};
+  int ndts = 2;
   unsigned nunits;
   int ncopies;
   enum tree_code code, bitop1 = NOP_EXPR, bitop2 = NOP_EXPR;
@@ -8231,7 +8254,7 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_iterator *gsi,
     {
       STMT_VINFO_TYPE (stmt_info) = comparison_vec_info_type;
       vect_model_simple_cost (stmt_info, ncopies * (1 + (bitop2 != NOP_EXPR)),
-                             dts, NULL, NULL);
+                             dts, ndts, NULL, NULL);
       if (bitop1 == NOP_EXPR)
        return expand_vec_cmp_expr_p (vectype, mask_type, code);
       else
index 12bb904abee5c0811576ad808bee451c6463a7fd..c0bc4930605400ff3d311f88aa6961030069288e 100644 (file)
@@ -1079,7 +1079,7 @@ extern bool supportable_narrowing_operation (enum tree_code, tree, tree,
 extern stmt_vec_info new_stmt_vec_info (gimple *stmt, vec_info *);
 extern void free_stmt_vec_info (gimple *stmt);
 extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
-                                    stmt_vector_for_cost *,
+                                   int, stmt_vector_for_cost *,
                                    stmt_vector_for_cost *);
 extern void vect_model_store_cost (stmt_vec_info, int, vect_memory_access_type,
                                   enum vect_def_type, slp_tree,