re PR tree-optimization/27460 (Does not vectorize statements with mixed type COND_EXPRs)
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. From-SVN: r178480
This commit is contained in:
parent
aa547a51da
commit
e9e1d143b5
15 changed files with 182 additions and 85 deletions
|
@ -1,3 +1,42 @@
|
|||
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.
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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$))",
|
||||
|
|
37
gcc/optabs.c
37
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)
|
||||
expand_vec_cond_expr_p (tree value_type, tree cmp_op_type)
|
||||
{
|
||||
if (get_vcond_icode (type, vmode) == CODE_FOR_nothing)
|
||||
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;
|
||||
|
||||
icode = get_vcond_icode (vec_cond_type, mode);
|
||||
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 (mode, cmp_op_mode, unsignedp);
|
||||
if (icode == CODE_FOR_nothing)
|
||||
return 0;
|
||||
|
||||
|
|
14
gcc/optabs.h
14
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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue