From 4fc5ebf12924235c9b88a2c645624bc8b1ea266c Mon Sep 17 00:00:00 2001 From: James Greenhalgh Date: Tue, 16 May 2017 20:18:05 +0000 Subject: [PATCH] re PR tree-optimization/80457 (vectorizable_condition does not update the vectorizer cost model) [gcc] 2017-05-16 James Greenhalgh Bill Schmidt 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 Bill Schmidt PR tree-optimization/80457 * gcc.target/powerpc/pr78604.c: Verify that vectorized COND_EXPRs call vect_model_simple_cost. Co-Authored-By: Bill Schmidt From-SVN: r248130 --- gcc/ChangeLog | 18 ++++++ gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.target/powerpc/pr78604.c | 3 +- gcc/tree-vect-stmts.c | 73 ++++++++++++++-------- gcc/tree-vectorizer.h | 2 +- 5 files changed, 76 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1cdda6d5914..25a2d3b6a90 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2017-05-16 James Greenhalgh + Bill Schmidt + + 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 * config/rs6000/rs6000-c: Add support for built-in functions diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b8ea07b10f6..9572cc49ba9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-05-16 James Greenhalgh + Bill Schmidt + + PR tree-optimization/80457 + * gcc.target/powerpc/pr78604.c: Verify that vectorized COND_EXPRs + call vect_model_simple_cost. + 2017-05-16 Paul Thomas PR fortran/80554 diff --git a/gcc/testsuite/gcc.target/powerpc/pr78604.c b/gcc/testsuite/gcc.target/powerpc/pr78604.c index 2ee5ab9b12c..757328e1a55 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr78604.c +++ b/gcc/testsuite/gcc.target/powerpc/pr78604.c @@ -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" } } */ diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 31349f2b9c1..74c9a113082 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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 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 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 diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 12bb904abee..c0bc4930605 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -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, -- 2.30.2