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 | |
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
-rw-r--r-- | gcc/ChangeLog | 39 | ||||
-rw-r--r-- | gcc/config/arm/neon.md | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 17 | ||||
-rw-r--r-- | gcc/config/i386/sse.md | 83 | ||||
-rw-r--r-- | gcc/config/ia64/vect.md | 6 | ||||
-rw-r--r-- | gcc/config/mips/mips-ps-3d.md | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/paired.md | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/vector.md | 6 | ||||
-rw-r--r-- | gcc/config/spu/spu.md | 4 | ||||
-rw-r--r-- | gcc/doc/md.texi | 11 | ||||
-rw-r--r-- | gcc/genopinit.c | 4 | ||||
-rw-r--r-- | gcc/optabs.c | 39 | ||||
-rw-r--r-- | gcc/optabs.h | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 32 |
15 files changed, 183 insertions, 86 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b79a96441e8..a54f1d13895 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,44 @@ 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. + +2011-09-02 Richard Guenther <rguenther@suse.de> + * pretty-print.h (pp_unsigned_wide_integer): New. * tree-pretty-print.c (dump_generic_node): Print unsigned host-wide-int fitting INTEGER_CSTs with pp_unsigned_wide_integer. diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 24dd9419bec..c91b0cdb931 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1600,7 +1600,7 @@ ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed ;; element-wise. -(define_expand "vcond<mode>" +(define_expand "vcond<mode><mode>" [(set (match_operand:VDQW 0 "s_register_operand" "") (if_then_else:VDQW (match_operator 3 "arm_comparison_operator" @@ -1680,7 +1680,7 @@ DONE; }) -(define_expand "vcondu<mode>" +(define_expand "vcondu<mode><mode>" [(set (match_operand:VDQIW 0 "s_register_operand" "") (if_then_else:VDQIW (match_operator 3 "arm_comparison_operator" 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); diff --git a/gcc/config/ia64/vect.md b/gcc/config/ia64/vect.md index 1684c8092c2..2f068ebcb60 100644 --- a/gcc/config/ia64/vect.md +++ b/gcc/config/ia64/vect.md @@ -661,7 +661,7 @@ DONE; }) -(define_expand "vcond<mode>" +(define_expand "vcond<mode><mode>" [(set (match_operand:VECINT 0 "gr_register_operand" "") (if_then_else:VECINT (match_operator 3 "" @@ -675,7 +675,7 @@ DONE; }) -(define_expand "vcondu<mode>" +(define_expand "vcondu<mode><mode>" [(set (match_operand:VECINT 0 "gr_register_operand" "") (if_then_else:VECINT (match_operator 3 "" @@ -1382,7 +1382,7 @@ DONE; }) -(define_expand "vcondv2sf" +(define_expand "vcondv2sfv2sf" [(set (match_operand:V2SF 0 "fr_register_operand" "") (if_then_else:V2SF (match_operator 3 "" diff --git a/gcc/config/mips/mips-ps-3d.md b/gcc/config/mips/mips-ps-3d.md index 8e942307cb9..504f43ce46c 100644 --- a/gcc/config/mips/mips-ps-3d.md +++ b/gcc/config/mips/mips-ps-3d.md @@ -597,7 +597,7 @@ [(set_attr "type" "frdiv2") (set_attr "mode" "<UNITMODE>")]) -(define_expand "vcondv2sf" +(define_expand "vcondv2sfv2sf" [(set (match_operand:V2SF 0 "register_operand") (if_then_else:V2SF (match_operator 3 "" diff --git a/gcc/config/rs6000/paired.md b/gcc/config/rs6000/paired.md index d1b0e8e45f2..f0bf7f9a5e3 100644 --- a/gcc/config/rs6000/paired.md +++ b/gcc/config/rs6000/paired.md @@ -507,7 +507,7 @@ DONE; }) -(define_expand "vcondv2sf" +(define_expand "vcondv2sfv2sf" [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") (if_then_else:V2SF (match_operator 3 "gpc_reg_operand" diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index 4799ff29e0a..0179cd9df90 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -370,7 +370,7 @@ ;; Vector comparisons -(define_expand "vcond<mode>" +(define_expand "vcond<mode><mode>" [(set (match_operand:VEC_F 0 "vfloat_operand" "") (if_then_else:VEC_F (match_operator 3 "comparison_operator" @@ -388,7 +388,7 @@ FAIL; }") -(define_expand "vcond<mode>" +(define_expand "vcond<mode><mode>" [(set (match_operand:VEC_I 0 "vint_operand" "") (if_then_else:VEC_I (match_operator 3 "comparison_operator" @@ -406,7 +406,7 @@ FAIL; }") -(define_expand "vcondu<mode>" +(define_expand "vcondu<mode><mode>" [(set (match_operand:VEC_I 0 "vint_operand" "") (if_then_else:VEC_I (match_operator 3 "comparison_operator" diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index 5742e0d96c1..676d54e8de0 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -3874,7 +3874,7 @@ selb\t%0,%4,%0,%3" ;; vector conditional compare patterns -(define_expand "vcond<mode>" +(define_expand "vcond<mode><mode>" [(set (match_operand:VCMP 0 "spu_reg_operand" "=r") (if_then_else:VCMP (match_operator 3 "comparison_operator" @@ -3891,7 +3891,7 @@ selb\t%0,%4,%0,%3" FAIL; }) -(define_expand "vcondu<mode>" +(define_expand "vcondu<mode><mode>" [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r") (if_then_else:VCMPU (match_operator 3 "comparison_operator" diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 7fc1a5ee2cc..1aa8552c5d4 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4017,6 +4017,17 @@ and input vectors should have the same modes (@code{N} elements). The low Initialize the vector to given values. Operand 0 is the vector to initialize and operand 1 is parallel containing values for individual fields. +@cindex @code{vcond@var{m}@var{n}} instruction pattern +@item @samp{vcond@var{m}@var{n}} +Output a conditional vector move. Operand 0 is the destination to +receive a combination of operand 1 and operand 2, which are of mode @var{m}, +dependent on the outcome of the predicate in operand 3 which is a +vector comparison with operands of mode @var{n} in operands 4 and 5. The +modes @var{m} and @var{n} should have the same size. Operand 0 +will be set to the value @var{op1} & @var{msk} | @var{op2} & ~@var{msk} +where @var{msk} is computed by element-wise evaluation of the vector +comparison with a truth value of all-ones and a false value of all-zeros. + @cindex @code{push@var{m}1} instruction pattern @item @samp{push@var{m}1} Output a push instruction. Operand 0 is value to push. Used only when diff --git a/gcc/genopinit.c b/gcc/genopinit.c index 4855e5ae3cd..ec4a4733c1d 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -253,8 +253,8 @@ static const char * const optabs[] = "set_optab_handler (vec_shl_optab, $A, CODE_FOR_$(vec_shl_$a$))", "set_optab_handler (vec_shr_optab, $A, CODE_FOR_$(vec_shr_$a$))", "set_optab_handler (vec_realign_load_optab, $A, CODE_FOR_$(vec_realign_load_$a$))", - "set_direct_optab_handler (vcond_optab, $A, CODE_FOR_$(vcond$a$))", - "set_direct_optab_handler (vcondu_optab, $A, CODE_FOR_$(vcondu$a$))", + "set_convert_optab_handler (vcond_optab, $A, $B, CODE_FOR_$(vcond$a$b$))", + "set_convert_optab_handler (vcondu_optab, $A, $B, CODE_FOR_$(vcondu$a$b$))", "set_optab_handler (ssum_widen_optab, $A, CODE_FOR_$(widen_ssum$I$a3$))", "set_optab_handler (usum_widen_optab, $A, CODE_FOR_$(widen_usum$I$a3$))", "set_optab_handler (udot_prod_optab, $A, CODE_FOR_$(udot_prod$I$a$))", 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; diff --git a/gcc/optabs.h b/gcc/optabs.h index cf5a659647b..56df6718462 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -589,6 +589,10 @@ enum convert_optab_index COI_vec_load_lanes, COI_vec_store_lanes, + /* Vector conditional operations. */ + COI_vcond, + COI_vcondu, + COI_MAX }; @@ -611,6 +615,8 @@ enum convert_optab_index #define satfractuns_optab (&convert_optab_table[COI_satfractuns]) #define vec_load_lanes_optab (&convert_optab_table[COI_vec_load_lanes]) #define vec_store_lanes_optab (&convert_optab_table[COI_vec_store_lanes]) +#define vcond_optab (&convert_optab_table[(int) COI_vcond]) +#define vcondu_optab (&convert_optab_table[(int) COI_vcondu]) /* Contains the optab used for each rtx code. */ extern optab code_to_optab[NUM_RTX_CODE + 1]; @@ -632,10 +638,6 @@ enum direct_optab_index DOI_reload_in, DOI_reload_out, - /* Vector conditional operations. */ - DOI_vcond, - DOI_vcondu, - /* Block move operation. */ DOI_movmem, @@ -699,8 +701,6 @@ typedef struct direct_optab_d *direct_optab; #endif #define reload_in_optab (&direct_optab_table[(int) DOI_reload_in]) #define reload_out_optab (&direct_optab_table[(int) DOI_reload_out]) -#define vcond_optab (&direct_optab_table[(int) DOI_vcond]) -#define vcondu_optab (&direct_optab_table[(int) DOI_vcondu]) #define movmem_optab (&direct_optab_table[(int) DOI_movmem]) #define setmem_optab (&direct_optab_table[(int) DOI_setmem]) #define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr]) @@ -877,7 +877,7 @@ extern bool expand_sfix_optab (rtx, rtx, convert_optab); extern rtx expand_widening_mult (enum machine_mode, rtx, rtx, rtx, int, optab); /* Return tree if target supports vector operations for COND_EXPR. */ -bool expand_vec_cond_expr_p (tree, enum machine_mode); +bool expand_vec_cond_expr_p (tree, tree); /* Generate code for VEC_COND_EXPR. */ extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 629176d5206..1584cff6427 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-09-02 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/27460 + PR middle-end/29269 + * gcc.dg/vect/vect-cond-7.c: New testcase. + 2011-09-02 Martin Jambor <mjambor@suse.cz> * g++.dg/ipa/devirt-3.C: Added a distraction method. diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 2a1318195e5..2c770919a2a 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -4680,15 +4680,19 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, LOOP - the loop that is being vectorized. COND - Condition that is checked for simple use. + Output: + *COMP_VECTYPE - the vector type for the comparison. + Returns whether a COND can be vectorized. Checks whether condition operands are supportable using vec_is_simple_use. */ static bool -vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo) +vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo, tree *comp_vectype) { tree lhs, rhs; tree def; enum vect_def_type dt; + tree vectype1 = NULL_TREE, vectype2 = NULL_TREE; if (!COMPARISON_CLASS_P (cond)) return false; @@ -4699,8 +4703,8 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo) if (TREE_CODE (lhs) == SSA_NAME) { gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs); - if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def, - &dt)) + if (!vect_is_simple_use_1 (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def, + &dt, &vectype1)) return false; } else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST @@ -4710,14 +4714,15 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo) if (TREE_CODE (rhs) == SSA_NAME) { gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs); - if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def, - &dt)) + if (!vect_is_simple_use_1 (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def, + &dt, &vectype2)) return false; } else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST && TREE_CODE (rhs) != FIXED_CST) return false; + *comp_vectype = vectype1 ? vectype1 : vectype2; return true; } @@ -4743,12 +4748,12 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, tree cond_expr, then_clause, else_clause; stmt_vec_info stmt_info = vinfo_for_stmt (stmt); tree vectype = STMT_VINFO_VECTYPE (stmt_info); + tree comp_vectype; tree vec_cond_lhs = NULL_TREE, vec_cond_rhs = NULL_TREE; tree vec_then_clause = NULL_TREE, vec_else_clause = NULL_TREE; tree vec_compare, vec_cond_expr; tree new_temp; loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); - enum machine_mode vec_mode; tree def; enum vect_def_type dt, dts[4]; int nunits = TYPE_VECTOR_SUBPARTS (vectype); @@ -4797,13 +4802,8 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, then_clause = gimple_assign_rhs2 (stmt); else_clause = gimple_assign_rhs3 (stmt); - if (!vect_is_simple_cond (cond_expr, loop_vinfo)) - return false; - - /* We do not handle two different vector types for the condition - and the values. */ - if (!types_compatible_p (TREE_TYPE (TREE_OPERAND (cond_expr, 0)), - TREE_TYPE (vectype))) + if (!vect_is_simple_cond (cond_expr, loop_vinfo, &comp_vectype) + || !comp_vectype) return false; if (TREE_CODE (then_clause) == SSA_NAME) @@ -4830,14 +4830,10 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi, && TREE_CODE (else_clause) != FIXED_CST) return false; - - vec_mode = TYPE_MODE (vectype); - if (!vec_stmt) { STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type; - return expand_vec_cond_expr_p (TREE_TYPE (gimple_assign_lhs (stmt)), - vec_mode); + return expand_vec_cond_expr_p (vectype, comp_vectype); } /* Transform */ |