aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorXionghu Luo <luoxhu@linux.ibm.com>2020-09-27 00:27:32 -0500
committerXionghu Luo <luoxhu@linux.ibm.com>2020-09-27 00:27:32 -0500
commit683e55facfd5c1d348796119424d7b3f9e889ffe (patch)
tree182e5ca06d98352268ad98a44f900859843331ec /gcc/optabs.c
parent91dd4a3864110704c921ab8467f568ff42c38e5c (diff)
downloadgcc-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.c21
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.