diff options
Diffstat (limited to 'gcc/tree-vect-patterns.c')
-rw-r--r-- | gcc/tree-vect-patterns.c | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 8e28950..4c22afd 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -3905,65 +3905,68 @@ vect_recog_mask_conversion_pattern (stmt_vec_info stmt_vinfo, tree *type_out) /* Check for MASK_LOAD ans MASK_STORE calls requiring mask conversion. */ if (is_gimple_call (last_stmt) - && gimple_call_internal_p (last_stmt) - && (gimple_call_internal_fn (last_stmt) == IFN_MASK_STORE - || gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD)) + && gimple_call_internal_p (last_stmt)) { gcall *pattern_stmt; - bool load = (gimple_call_internal_fn (last_stmt) == IFN_MASK_LOAD); - if (load) + internal_fn ifn = gimple_call_internal_fn (last_stmt); + int mask_argno = internal_fn_mask_index (ifn); + if (mask_argno < 0) + return NULL; + + bool store_p = internal_store_fn_p (ifn); + if (store_p) { - lhs = gimple_call_lhs (last_stmt); - vectype1 = get_vectype_for_scalar_type (TREE_TYPE (lhs)); + int rhs_index = internal_fn_stored_value_index (ifn); + tree rhs = gimple_call_arg (last_stmt, rhs_index); + vectype1 = get_vectype_for_scalar_type (TREE_TYPE (rhs)); } else { - rhs2 = gimple_call_arg (last_stmt, 3); - vectype1 = get_vectype_for_scalar_type (TREE_TYPE (rhs2)); + lhs = gimple_call_lhs (last_stmt); + vectype1 = get_vectype_for_scalar_type (TREE_TYPE (lhs)); } - rhs1 = gimple_call_arg (last_stmt, 2); - rhs1_type = search_type_for_mask (rhs1, vinfo); - if (!rhs1_type) + tree mask_arg = gimple_call_arg (last_stmt, mask_argno); + tree mask_arg_type = search_type_for_mask (mask_arg, vinfo); + if (!mask_arg_type) return NULL; - vectype2 = get_mask_type_for_scalar_type (rhs1_type); + vectype2 = get_mask_type_for_scalar_type (mask_arg_type); if (!vectype1 || !vectype2 || known_eq (TYPE_VECTOR_SUBPARTS (vectype1), TYPE_VECTOR_SUBPARTS (vectype2))) return NULL; - tmp = build_mask_conversion (rhs1, vectype1, stmt_vinfo); + tmp = build_mask_conversion (mask_arg, vectype1, stmt_vinfo); - if (load) + auto_vec<tree, 8> args; + unsigned int nargs = gimple_call_num_args (last_stmt); + args.safe_grow (nargs); + for (unsigned int i = 0; i < nargs; ++i) + args[i] = ((int) i == mask_argno + ? tmp + : gimple_call_arg (last_stmt, i)); + pattern_stmt = gimple_build_call_internal_vec (ifn, args); + + if (!store_p) { lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); - pattern_stmt - = gimple_build_call_internal (IFN_MASK_LOAD, 3, - gimple_call_arg (last_stmt, 0), - gimple_call_arg (last_stmt, 1), - tmp); gimple_call_set_lhs (pattern_stmt, lhs); } - else - pattern_stmt - = gimple_build_call_internal (IFN_MASK_STORE, 4, - gimple_call_arg (last_stmt, 0), - gimple_call_arg (last_stmt, 1), - tmp, - gimple_call_arg (last_stmt, 3)); - gimple_call_set_nothrow (pattern_stmt, true); pattern_stmt_info = new_stmt_vec_info (pattern_stmt, vinfo); set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); - STMT_VINFO_DATA_REF (pattern_stmt_info) - = STMT_VINFO_DATA_REF (stmt_vinfo); - STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info) - = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo); - STMT_VINFO_GATHER_SCATTER_P (pattern_stmt_info) - = STMT_VINFO_GATHER_SCATTER_P (stmt_vinfo); + if (STMT_VINFO_DATA_REF (stmt_vinfo)) + { + STMT_VINFO_DATA_REF (pattern_stmt_info) + = STMT_VINFO_DATA_REF (stmt_vinfo); + STMT_VINFO_DR_WRT_VEC_LOOP (pattern_stmt_info) + = STMT_VINFO_DR_WRT_VEC_LOOP (stmt_vinfo); + STMT_VINFO_GATHER_SCATTER_P (pattern_stmt_info) + = STMT_VINFO_GATHER_SCATTER_P (stmt_vinfo); + } *type_out = vectype1; vect_pattern_detected ("vect_recog_mask_conversion_pattern", last_stmt); |