diff options
author | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-10 12:14:19 +0000 |
---|---|---|
committer | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-10 12:14:19 +0000 |
commit | b602a8ec03bbd9f24433b1e0810285d0c00d4111 (patch) | |
tree | 98ceea7a2dde64ee53313efd5b9861e249694e69 /gcc/optabs.c | |
parent | cf5489c1f23e5e430f4d2ed6a0422e75b682f094 (diff) |
gcc/
2015-11-10 Ilya Enkovich <enkovich.gnu@gmail.com>
* optabs-query.h (get_vcond_mask_icode): New.
* optabs-tree.c (expand_vec_cond_expr_p): Use
get_vcond_mask_icode for VEC_COND_EXPR with mask.
* optabs.c (expand_vec_cond_mask_expr): New.
(expand_vec_cond_expr): Use get_vcond_mask_icode
when possible.
* optabs.def (vcond_mask_optab): New.
* tree-vect-patterns.c (vect_recog_bool_pattern): Don't
generate redundant comparison for COND_EXPR.
* tree-vect-stmts.c (vect_is_simple_cond): Allow SSA_NAME
as a condition.
(vectorizable_condition): Likewise.
* tree-vect-slp.c (vect_get_and_check_slp_defs): Allow
cond_exp with no embedded comparison.
(vect_build_slp_tree_1): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230101 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index f9fbfde967d..9b8e95855c9 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5426,6 +5426,38 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target) return tmp; } +/* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its + three operands. */ + +rtx +expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2, + rtx target) +{ + struct expand_operand ops[4]; + machine_mode mode = TYPE_MODE (vec_cond_type); + machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0)); + enum insn_code icode = get_vcond_mask_icode (mode, mask_mode); + rtx mask, rtx_op1, rtx_op2; + + if (icode == CODE_FOR_nothing) + return 0; + + mask = expand_normal (op0); + rtx_op1 = expand_normal (op1); + rtx_op2 = expand_normal (op2); + + mask = force_reg (GET_MODE (mask), mask); + rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1); + + create_output_operand (&ops[0], target, mode); + create_input_operand (&ops[1], rtx_op1, mode); + create_input_operand (&ops[2], rtx_op2, mode); + create_input_operand (&ops[3], mask, mask_mode); + expand_insn (icode, 4, ops); + + return ops[0].value; +} + /* Generate insns for a VEC_COND_EXPR, given its TYPE and its three operands. */ @@ -5450,11 +5482,20 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2, } else { - /* Fake op0 < 0. */ gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0))); - op0a = op0; - op0b = build_zero_cst (TREE_TYPE (op0)); - tcode = LT_EXPR; + if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0))) + != CODE_FOR_nothing) + return expand_vec_cond_mask_expr (vec_cond_type, op0, op1, + op2, target); + /* Fake op0 < 0. */ + else + { + gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0))) + == MODE_VECTOR_INT); + op0a = op0; + op0b = build_zero_cst (TREE_TYPE (op0)); + tcode = LT_EXPR; + } } cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a)); unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a)); |