diff options
Diffstat (limited to 'gcc/tree-vect-patterns.cc')
-rw-r--r-- | gcc/tree-vect-patterns.cc | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index f0ddbf9..d0bf2f9 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -130,7 +130,6 @@ vect_init_pattern_stmt (vec_info *vinfo, gimple *pattern_stmt, STMT_VINFO_RELATED_STMT (pattern_stmt_info) = orig_stmt_info; STMT_VINFO_DEF_TYPE (pattern_stmt_info) = STMT_VINFO_DEF_TYPE (orig_stmt_info); - STMT_VINFO_TYPE (pattern_stmt_info) = STMT_VINFO_TYPE (orig_stmt_info); if (!STMT_VINFO_VECTYPE (pattern_stmt_info)) { gcc_assert (!vectype @@ -4078,8 +4077,7 @@ vect_recog_vector_vector_shift_pattern (vec_info *vinfo, lhs = gimple_assign_lhs (last_stmt); oprnd0 = gimple_assign_rhs1 (last_stmt); oprnd1 = gimple_assign_rhs2 (last_stmt); - if (TREE_CODE (oprnd0) != SSA_NAME - || TREE_CODE (oprnd1) != SSA_NAME + if (TREE_CODE (oprnd1) != SSA_NAME || TYPE_MODE (TREE_TYPE (oprnd0)) == TYPE_MODE (TREE_TYPE (oprnd1)) || !INTEGRAL_TYPE_P (TREE_TYPE (oprnd0)) || !type_has_mode_precision_p (TREE_TYPE (oprnd1)) @@ -4315,6 +4313,42 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, tree val, if (!possible) return NULL; + if (vect_is_reduction (stmt_vinfo)) + { + int op_uses = alg.op[0] != alg_zero; + for (int i = 1; i < alg.ops; i++) + switch (alg.op[i]) + { + case alg_add_t_m2: + case alg_sub_t_m2: + if (synth_shift_p && alg.log[i]) + return NULL; + else + op_uses++; + break; + case alg_add_t2_m: + case alg_sub_t2_m: + op_uses++; + /* Fallthru. */ + case alg_shift: + if (synth_shift_p && alg.log[i]) + return NULL; + break; + case alg_add_factor: + case alg_sub_factor: + return NULL; + default: + break; + } + if (variant == add_variant) + op_uses++; + /* When we'll synthesize more than a single use of the reduction + operand the reduction constraints are violated. Avoid this + situation. */ + if (op_uses > 1) + return NULL; + } + if (!target_supports_mult_synth_alg (&alg, variant, vectype, synth_shift_p)) return NULL; @@ -4819,7 +4853,9 @@ vect_recog_divmod_pattern (vec_info *vinfo, tree q, cst; int prec; - if (!is_gimple_assign (last_stmt)) + if (!is_gimple_assign (last_stmt) + /* The pattern will disrupt the reduction chain with multiple uses. */ + || vect_is_reduction (stmt_vinfo)) return NULL; rhs_code = gimple_assign_rhs_code (last_stmt); @@ -6003,16 +6039,17 @@ vect_recog_gather_scatter_pattern (vec_info *vinfo, This is null if the operation is unconditional. */ tree mask = vect_get_load_store_mask (stmt_info); + /* DR analysis nailed down the vector type for the access. */ + tree gs_vectype = STMT_VINFO_VECTYPE (stmt_info); + /* Make sure that the target supports an appropriate internal function for the gather/scatter operation. */ gather_scatter_info gs_info; - if (!vect_check_gather_scatter (stmt_info, loop_vinfo, &gs_info) + if (!vect_check_gather_scatter (stmt_info, gs_vectype, loop_vinfo, &gs_info) || gs_info.ifn == IFN_LAST) return NULL; /* Convert the mask to the right form. */ - tree gs_vectype = get_vectype_for_scalar_type (loop_vinfo, - gs_info.element_type); if (mask) mask = vect_convert_mask_for_vectype (mask, gs_vectype, stmt_info, loop_vinfo); @@ -6074,8 +6111,7 @@ vect_recog_gather_scatter_pattern (vec_info *vinfo, stmt_vec_info pattern_stmt_info = loop_vinfo->add_stmt (pattern_stmt); loop_vinfo->move_dr (pattern_stmt_info, stmt_info); - tree vectype = STMT_VINFO_VECTYPE (stmt_info); - *type_out = vectype; + *type_out = gs_vectype; vect_pattern_detected ("gather/scatter pattern", stmt_info->stmt); return pattern_stmt; |