diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-02 13:53:32 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-02 13:53:32 +0000 |
commit | d6b19f6bc6c71621f8c894b07706e14e1301cb39 (patch) | |
tree | a60e543826617c5a8adf334f075bb61da4cc0003 /gcc/config/i386 | |
parent | d066d69aa5fa551244d8e2aa3479e3404480721a (diff) | |
download | gcc-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/config/i386')
-rw-r--r-- | gcc/config/i386/i386.c | 17 | ||||
-rw-r--r-- | gcc/config/i386/sse.md | 83 |
2 files changed, 65 insertions, 35 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d0e1be5df4a..a9c0aa750cf 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -18413,19 +18413,26 @@ ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1, rtx op_true, rtx op_false) { enum machine_mode mode = GET_MODE (dest); + enum machine_mode cmp_mode = GET_MODE (cmp_op0); rtx x; - cmp_op0 = force_reg (mode, cmp_op0); - if (!nonimmediate_operand (cmp_op1, mode)) - cmp_op1 = force_reg (mode, cmp_op1); + cmp_op0 = force_reg (cmp_mode, cmp_op0); + if (!nonimmediate_operand (cmp_op1, cmp_mode)) + cmp_op1 = force_reg (cmp_mode, cmp_op1); if (optimize || reg_overlap_mentioned_p (dest, op_true) || reg_overlap_mentioned_p (dest, op_false)) dest = gen_reg_rtx (mode); - x = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); - emit_insn (gen_rtx_SET (VOIDmode, dest, x)); + x = gen_rtx_fmt_ee (code, cmp_mode, cmp_op0, cmp_op1); + if (cmp_mode != mode) + { + x = force_reg (cmp_mode, x); + convert_move (dest, x, false); + } + else + emit_insn (gen_rtx_SET (VOIDmode, dest, x)); return dest; } diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 3678ea824ec..353f4b62a7d 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1402,15 +1402,34 @@ (const_string "0"))) (set_attr "mode" "<MODE>")]) -(define_expand "vcond<mode>" - [(set (match_operand:VF 0 "register_operand" "") - (if_then_else:VF +(define_expand "vcond<V_256:mode><VF_256:mode>" + [(set (match_operand:V_256 0 "register_operand" "") + (if_then_else:V_256 (match_operator 3 "" - [(match_operand:VF 4 "nonimmediate_operand" "") - (match_operand:VF 5 "nonimmediate_operand" "")]) - (match_operand:VF 1 "general_operand" "") - (match_operand:VF 2 "general_operand" "")))] - "TARGET_SSE" + [(match_operand:VF_256 4 "nonimmediate_operand" "") + (match_operand:VF_256 5 "nonimmediate_operand" "")]) + (match_operand:V_256 1 "general_operand" "") + (match_operand:V_256 2 "general_operand" "")))] + "TARGET_AVX + && (GET_MODE_NUNITS (<V_256:MODE>mode) + == GET_MODE_NUNITS (<VF_256:MODE>mode))" +{ + bool ok = ix86_expand_fp_vcond (operands); + gcc_assert (ok); + DONE; +}) + +(define_expand "vcond<V_128:mode><VF_128:mode>" + [(set (match_operand:V_128 0 "register_operand" "") + (if_then_else:V_128 + (match_operator 3 "" + [(match_operand:VF_128 4 "nonimmediate_operand" "") + (match_operand:VF_128 5 "nonimmediate_operand" "")]) + (match_operand:V_128 1 "general_operand" "") + (match_operand:V_128 2 "general_operand" "")))] + "TARGET_SSE + && (GET_MODE_NUNITS (<V_128:MODE>mode) + == GET_MODE_NUNITS (<VF_128:MODE>mode))" { bool ok = ix86_expand_fp_vcond (operands); gcc_assert (ok); @@ -6171,29 +6190,31 @@ (set_attr "prefix" "orig,vex") (set_attr "mode" "TI")]) -(define_expand "vcond<mode>" - [(set (match_operand:VI124_128 0 "register_operand" "") - (if_then_else:VI124_128 +(define_expand "vcond<V_128:mode><VI124_128:mode>" + [(set (match_operand:V_128 0 "register_operand" "") + (if_then_else:V_128 (match_operator 3 "" [(match_operand:VI124_128 4 "nonimmediate_operand" "") (match_operand:VI124_128 5 "nonimmediate_operand" "")]) - (match_operand:VI124_128 1 "general_operand" "") - (match_operand:VI124_128 2 "general_operand" "")))] - "TARGET_SSE2" + (match_operand:V_128 1 "general_operand" "") + (match_operand:V_128 2 "general_operand" "")))] + "TARGET_SSE2 + && (GET_MODE_NUNITS (<V_128:MODE>mode) + == GET_MODE_NUNITS (<VI124_128:MODE>mode))" { bool ok = ix86_expand_int_vcond (operands); gcc_assert (ok); DONE; }) -(define_expand "vcondv2di" - [(set (match_operand:V2DI 0 "register_operand" "") - (if_then_else:V2DI +(define_expand "vcond<VI8F_128:mode>v2di" + [(set (match_operand:VI8F_128 0 "register_operand" "") + (if_then_else:VI8F_128 (match_operator 3 "" [(match_operand:V2DI 4 "nonimmediate_operand" "") (match_operand:V2DI 5 "nonimmediate_operand" "")]) - (match_operand:V2DI 1 "general_operand" "") - (match_operand:V2DI 2 "general_operand" "")))] + (match_operand:VI8F_128 1 "general_operand" "") + (match_operand:VI8F_128 2 "general_operand" "")))] "TARGET_SSE4_2" { bool ok = ix86_expand_int_vcond (operands); @@ -6201,29 +6222,31 @@ DONE; }) -(define_expand "vcondu<mode>" - [(set (match_operand:VI124_128 0 "register_operand" "") - (if_then_else:VI124_128 +(define_expand "vcondu<V_128:mode><VI124_128:mode>" + [(set (match_operand:V_128 0 "register_operand" "") + (if_then_else:V_128 (match_operator 3 "" [(match_operand:VI124_128 4 "nonimmediate_operand" "") (match_operand:VI124_128 5 "nonimmediate_operand" "")]) - (match_operand:VI124_128 1 "general_operand" "") - (match_operand:VI124_128 2 "general_operand" "")))] - "TARGET_SSE2" + (match_operand:V_128 1 "general_operand" "") + (match_operand:V_128 2 "general_operand" "")))] + "TARGET_SSE2 + && (GET_MODE_NUNITS (<V_128:MODE>mode) + == GET_MODE_NUNITS (<VI124_128:MODE>mode))" { bool ok = ix86_expand_int_vcond (operands); gcc_assert (ok); DONE; }) -(define_expand "vconduv2di" - [(set (match_operand:V2DI 0 "register_operand" "") - (if_then_else:V2DI +(define_expand "vcondu<VI8F_128:mode>v2di" + [(set (match_operand:VI8F_128 0 "register_operand" "") + (if_then_else:VI8F_128 (match_operator 3 "" [(match_operand:V2DI 4 "nonimmediate_operand" "") (match_operand:V2DI 5 "nonimmediate_operand" "")]) - (match_operand:V2DI 1 "general_operand" "") - (match_operand:V2DI 2 "general_operand" "")))] + (match_operand:VI8F_128 1 "general_operand" "") + (match_operand:VI8F_128 2 "general_operand" "")))] "TARGET_SSE4_2" { bool ok = ix86_expand_int_vcond (operands); |