summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-02 13:53:32 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-02 13:53:32 +0000
commitd6b19f6bc6c71621f8c894b07706e14e1301cb39 (patch)
treea60e543826617c5a8adf334f075bb61da4cc0003 /gcc/optabs.c
parentd066d69aa5fa551244d8e2aa3479e3404480721a (diff)
downloadgcc-d6b19f6bc6c71621f8c894b07706e14e1301cb39.tar.gz
2011-09-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/27460 PR middle-end/29269 * doc/md.texi (vcond): Document. * genopinit.c (optabs): Turn vcond{,u}_optab into a conversion optab with two modes. * optabs.h (enum convert_optab_index): Add COI_vcond, COI_vcondu. (enum direct_optab_index): Remove DOI_vcond, DOI_vcondu. (vcond_optab): Adjust. (vcondu_optab): Likewise. (expand_vec_cond_expr_p): Adjust prototype. * optabs.c (get_vcond_icode): Adjust. (expand_vec_cond_expr_p): Likewise. (expand_vec_cond_expr): Likewise. * tree-vect-stmts.c (vect_is_simple_cond): Return the comparison vector type. (vectorizable_condition): Allow differing types for comparison and result. * config/i386/i386.c (ix86_expand_sse_cmp): Use proper mode for the comparison. * config/i386/sse.md (vcond<mode>): Split to vcond<V_256:mode><VF_256:mode>, vcond<V_128:mode><VF_128:mode>, vcond<V_128:mode><VI124_128:mode> and vcondu<V_128:mode><VI124_128:mode>. (vcondv2di): Change to vcond<VI8F_128:mode>v2di. (vconduv2di): Likewise. * config/arm/neon.md (vcond<mode>): Change to vcond*<mode><mode>. (vcondu<mode>): Likewise. * config/ia64/vect.md (vcond<mode>): Likewise. (vcondu<mode>): Likewise. (vcondv2sf): Likewise. * config/mips/mips-ps-3d.md (vcondv2sf): Likewise. * config/rs6000/paired.md (vcondv2sf): Likewise. * config/rs6000/vector.md (vcond<mode>): Likewise. (vcondu<mode>): Likewise. * config/spu/spu.md (vcond<mode>): Likewise. (vcondu<mode>): Likewise. * gcc.dg/vect/vect-cond-7.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178480 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 886b259ce34..5cdcd95f12a 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6620,27 +6620,33 @@ vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
}
-/* Return insn code for TYPE, the type of a VEC_COND_EXPR. */
+/* Return insn code for a conditional operator with a comparison in
+ mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
static inline enum insn_code
-get_vcond_icode (tree type, enum machine_mode mode)
+get_vcond_icode (enum machine_mode vmode, enum machine_mode cmode, bool uns)
{
enum insn_code icode = CODE_FOR_nothing;
-
- if (TYPE_UNSIGNED (type))
- icode = direct_optab_handler (vcondu_optab, mode);
+ if (uns)
+ icode = convert_optab_handler (vcondu_optab, vmode, cmode);
else
- icode = direct_optab_handler (vcond_optab, mode);
+ icode = convert_optab_handler (vcond_optab, vmode, cmode);
return icode;
}
/* Return TRUE iff, appropriate vector insns are available
- for vector cond expr with type TYPE in VMODE mode. */
+ for vector cond expr with vector type VALUE_TYPE and a comparison
+ with operand vector types in CMP_OP_TYPE. */
bool
-expand_vec_cond_expr_p (tree type, enum machine_mode vmode)
-{
- if (get_vcond_icode (type, vmode) == CODE_FOR_nothing)
+expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
+{
+ enum machine_mode value_mode = TYPE_MODE (value_type);
+ enum machine_mode cmp_op_mode = TYPE_MODE (cmp_op_type);
+ if (GET_MODE_SIZE (value_mode) != GET_MODE_SIZE (cmp_op_mode)
+ || GET_MODE_NUNITS (value_mode) != GET_MODE_NUNITS (cmp_op_mode)
+ || get_vcond_icode (TYPE_MODE (value_type), TYPE_MODE (cmp_op_type),
+ TYPE_UNSIGNED (cmp_op_type)) == CODE_FOR_nothing)
return false;
return true;
}
@@ -6656,9 +6662,18 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
enum insn_code icode;
rtx comparison, rtx_op1, rtx_op2;
enum machine_mode mode = TYPE_MODE (vec_cond_type);
- bool unsignedp = TYPE_UNSIGNED (vec_cond_type);
+ enum machine_mode cmp_op_mode;
+ bool unsignedp;
+
+ gcc_assert (COMPARISON_CLASS_P (op0));
+
+ unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)));
+ cmp_op_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0)));
+
+ gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
+ && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
- icode = get_vcond_icode (vec_cond_type, mode);
+ icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
if (icode == CODE_FOR_nothing)
return 0;