diff options
author | Xionghu Luo <luoxhu@linux.ibm.com> | 2020-09-27 00:27:32 -0500 |
---|---|---|
committer | Xionghu Luo <luoxhu@linux.ibm.com> | 2020-09-27 00:27:32 -0500 |
commit | 683e55facfd5c1d348796119424d7b3f9e889ffe (patch) | |
tree | 182e5ca06d98352268ad98a44f900859843331ec /gcc/optabs.c | |
parent | 91dd4a3864110704c921ab8467f568ff42c38e5c (diff) | |
download | gcc-683e55facfd5c1d348796119424d7b3f9e889ffe.zip gcc-683e55facfd5c1d348796119424d7b3f9e889ffe.tar.gz gcc-683e55facfd5c1d348796119424d7b3f9e889ffe.tar.bz2 |
IFN: Implement IFN_VEC_SET for ARRAY_REF with VIEW_CONVERT_EXPR
This patch enables transformation from ARRAY_REF(VIEW_CONVERT_EXPR) to
VEC_SET internal function in gimple-isel pass if target supports
vec_set with variable index by checking can_vec_set_var_idx_p.
gcc/ChangeLog:
2020-09-27 Xionghu Luo <luoxhu@linux.ibm.com>
* gimple-isel.cc (gimple_expand_vec_set_expr): New function.
(gimple_expand_vec_cond_exprs): Rename to ...
(gimple_expand_vec_exprs): ... this and call
gimple_expand_vec_set_expr.
* internal-fn.c (vec_set_direct): New define.
(expand_vec_set_optab_fn): New function.
(direct_vec_set_optab_supported_p): New define.
* internal-fn.def (VEC_SET): New DEF_INTERNAL_OPTAB_FN.
* optabs.c (can_vec_set_var_idx_p): New function.
* optabs.h (can_vec_set_var_idx_p): New declaration.
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 184827f..8e844028 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3841,6 +3841,27 @@ can_vcond_compare_p (enum rtx_code code, machine_mode value_mode, && insn_operand_matches (icode, 3, test); } +/* Return whether the backend can emit vector set instructions for inserting + element into vector at variable index position. */ + +bool +can_vec_set_var_idx_p (machine_mode vec_mode) +{ + if (!VECTOR_MODE_P (vec_mode)) + return false; + + machine_mode inner_mode = GET_MODE_INNER (vec_mode); + rtx reg1 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 1); + rtx reg2 = alloca_raw_REG (inner_mode, LAST_VIRTUAL_REGISTER + 2); + rtx reg3 = alloca_raw_REG (VOIDmode, LAST_VIRTUAL_REGISTER + 3); + + enum insn_code icode = optab_handler (vec_set_optab, vec_mode); + + return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1) + && insn_operand_matches (icode, 1, reg2) + && insn_operand_matches (icode, 2, reg3); +} + /* This function is called when we are going to emit a compare instruction that compares the values found in X and Y, using the rtl operator COMPARISON. |