This patch splits out the rhs checking code that's common to both vectorizable_mask_load_store and vectorizable_store.
Richard 2017-11-17 Richard Sandiford <richard.sandif...@linaro.org> gcc/ * tree-vect-stmts.c (vect_check_store_rhs): New function, split out from... (vectorizable_mask_load_store): ...here. (vectorizable_store): ...and here. Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2017-11-17 09:06:49.784303349 +0000 +++ gcc/tree-vect-stmts.c 2017-11-17 09:06:53.395522598 +0000 @@ -2091,6 +2091,55 @@ vect_check_load_store_mask (gimple *stmt return true; } +/* Return true if stored value RHS is suitable for vectorizing store + statement STMT. When returning true, store the type of the + vectorized store value in *RHS_VECTYPE_OUT and the type of the + store in *VLS_TYPE_OUT. */ + +static bool +vect_check_store_rhs (gimple *stmt, tree rhs, tree *rhs_vectype_out, + vec_load_store_type *vls_type_out) +{ + /* In the case this is a store from a constant make sure + native_encode_expr can handle it. */ + if (CONSTANT_CLASS_P (rhs) && native_encode_expr (rhs, NULL, 64) == 0) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "cannot encode constant as a byte sequence.\n"); + return false; + } + + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + gimple *def_stmt; + enum vect_def_type dt; + tree rhs_vectype; + if (!vect_is_simple_use (rhs, stmt_info->vinfo, &def_stmt, &dt, + &rhs_vectype)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "use not simple.\n"); + return false; + } + + tree vectype = STMT_VINFO_VECTYPE (stmt_info); + if (rhs_vectype && !useless_type_conversion_p (vectype, rhs_vectype)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "incompatible vector types.\n"); + return false; + } + + *rhs_vectype_out = rhs_vectype; + if (dt == vect_constant_def || dt == vect_external_def) + *vls_type_out = VLS_STORE_INVARIANT; + else + *vls_type_out = VLS_STORE; + return true; +} + /* Function vectorizable_mask_load_store. Check if STMT performs a conditional load or store that can be vectorized. @@ -2161,12 +2210,8 @@ vectorizable_mask_load_store (gimple *st if (gimple_call_internal_fn (stmt) == IFN_MASK_STORE) { tree rhs = gimple_call_arg (stmt, 3); - if (!vect_is_simple_use (rhs, loop_vinfo, &def_stmt, &dt, &rhs_vectype)) + if (!vect_check_store_rhs (stmt, rhs, &rhs_vectype, &vls_type)) return false; - if (dt == vect_constant_def || dt == vect_external_def) - vls_type = VLS_STORE_INVARIANT; - else - vls_type = VLS_STORE; } else vls_type = VLS_LOAD; @@ -2200,9 +2245,7 @@ vectorizable_mask_load_store (gimple *st else if (!VECTOR_MODE_P (TYPE_MODE (vectype)) || !can_vec_mask_load_store_p (TYPE_MODE (vectype), TYPE_MODE (mask_vectype), - vls_type == VLS_LOAD) - || (rhs_vectype - && !useless_type_conversion_p (vectype, rhs_vectype))) + vls_type == VLS_LOAD)) return false; if (!vec_stmt) /* transformation not required. */ @@ -5798,26 +5841,7 @@ vectorizable_store (gimple *stmt, gimple } op = gimple_assign_rhs1 (stmt); - - /* In the case this is a store from a constant make sure - native_encode_expr can handle it. */ - if (CONSTANT_CLASS_P (op) && native_encode_expr (op, NULL, 64) == 0) - return false; - - if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt, &rhs_vectype)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "use not simple.\n"); - return false; - } - - if (dt == vect_constant_def || dt == vect_external_def) - vls_type = VLS_STORE_INVARIANT; - else - vls_type = VLS_STORE; - - if (rhs_vectype && !useless_type_conversion_p (vectype, rhs_vectype)) + if (!vect_check_store_rhs (stmt, op, &rhs_vectype, &vls_type)) return false; elem_type = TREE_TYPE (vectype);