From: Richard Guenther <rguenther@suse.de>
To: Uros Bizjak <ubizjak@gmail.com>
Cc: Jakub Jelinek <jakub@redhat.com>,
gcc-patches@gcc.gnu.org, uros@gcc.gnu.org, rth@redhat.com,
artyom.shinkaroff@gmail.com
Subject: Re: [PATCH] Change vcond<mode> to vcond<mode1><mode2>
Date: Tue, 30 Aug 2011 12:11:00 -0000 [thread overview]
Message-ID: <alpine.LNX.2.00.1108301215390.2130@zhemvz.fhfr.qr> (raw)
In-Reply-To: <alpine.LNX.2.00.1108301134000.2130@zhemvz.fhfr.qr>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 33687 bytes --]
On Tue, 30 Aug 2011, Richard Guenther wrote:
> On Tue, 30 Aug 2011, Uros Bizjak wrote:
>
> > On Tue, Aug 30, 2011 at 11:15 AM, Richard Guenther <rguenther@suse.de> wrote:
> >
> > >> >> > Hmm. Â But then I'd have to try emit an insn, right? Â Currently
> > >> >> > the vectorizer simply looks for an optab handler ... the
> > >> >> > operands are not readily available (but their mode is known).
> > >> >> > So I'd create some fake regs, setup operands and call GEN_FCN
> > >> >> > on it? Â If it succeds I'd have to delete emitted insns, etc.
> > >> >> > Or I could add a target hook ...
> > >> >>
> > >> >> Hm... indeed, too much complication...
> > >> >>
> > >> >> I'd say, let's go with modeless operands and a target hook. IMO, this
> > >> >> is much more flexible than checking optab for supported modes.
> > >> >> Existing way is appropriate for single mode patterns, but we have
> > >> >> interdependent modes here, at least on x86.
> > >> >>
> > >> >> The hook would have two input arguments, insn mode and compare mode,
> > >> >> where the hook returns suggested supported compare mode, or no mode,
> > >> >> if it really can't handle requested modes.
> > >> >
> > >> > I think a two mode vcond pattern is in fact much cleaner than
> > >> > a one mode + modeless pattern which gen* will complain about and
> > >> > a target hook.
> > >>
> > >> OK, but in this case, do not use mode iterators too much in order to
> > >> avoid invalid patterns.
> > >
> > > I don't see them as "invalid". Â They will be unused (maybe combine
> > > would create them though?), but they have well-defined semantics
> > > with my proposed documentation. Â And x86 can handle them just fine.
> >
> > OK, let's go this way then... We can clean up this later if at all.
>
> Certainly what I prefer (less work for me now) ;) The smallest
> number of patterns would probably result from using vcond<mode><mode>
> to cover the same-mode cases and then add the 12 other patterns
> with the respective integer / float mode variant. Thus we'd have
> 15 patterns in total (still much for my taste).
>
> Ideally we could have a mode attribute that would map possibly
> to an iterator, thus
>
> (define_mode_attr matching [(V4SF ["V4SF" "V4SI"]) (V8HI "V8HI") ...])
>
> or similar. But I don't feel like adding this sort of mode
> attr that really is a hidden iterator ... ;)
>
> Thus, the following is the combined patch which bootstrapped and
> tested ok on x86_64-unknown-linux-gnu with {,-m32} over night,
> with the documentation for vcond added.
>
> Ok for trunk?
I'm re-testing with the patterns having an extra condition like
&& (GET_MODE_NUNITS (<V_256:MODE>mode)
== GET_MODE_NUNITS (<VF_256:MODE>mode))"
to have the HAVE_vcond* defines easily optimized.
Ok?
Thanks,
Richard.
2011-08-30 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.
Index: trunk/gcc/config/arm/neon.md
===================================================================
*** trunk.orig/gcc/config/arm/neon.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/arm/neon.md 2011-08-30 11:46:51.000000000 +0200
***************
*** 1600,1606 ****
;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
;; element-wise.
! (define_expand "vcond<mode>"
[(set (match_operand:VDQW 0 "s_register_operand" "")
(if_then_else:VDQW
(match_operator 3 "arm_comparison_operator"
--- 1600,1606 ----
;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
;; element-wise.
! (define_expand "vcond<mode><mode>"
[(set (match_operand:VDQW 0 "s_register_operand" "")
(if_then_else:VDQW
(match_operator 3 "arm_comparison_operator"
***************
*** 1680,1686 ****
DONE;
})
! (define_expand "vcondu<mode>"
[(set (match_operand:VDQIW 0 "s_register_operand" "")
(if_then_else:VDQIW
(match_operator 3 "arm_comparison_operator"
--- 1680,1686 ----
DONE;
})
! (define_expand "vcondu<mode><mode>"
[(set (match_operand:VDQIW 0 "s_register_operand" "")
(if_then_else:VDQIW
(match_operator 3 "arm_comparison_operator"
Index: trunk/gcc/config/i386/sse.md
===================================================================
*** trunk.orig/gcc/config/i386/sse.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/i386/sse.md 2011-08-30 12:12:30.000000000 +0200
***************
*** 1405,1419 ****
(const_string "0")))
(set_attr "mode" "<MODE>")])
! (define_expand "vcond<mode>"
! [(set (match_operand:VF 0 "register_operand" "")
! (if_then_else:VF
(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"
{
bool ok = ix86_expand_fp_vcond (operands);
gcc_assert (ok);
--- 1405,1438 ----
(const_string "0")))
(set_attr "mode" "<MODE>")])
! (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_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);
***************
*** 6091,6119 ****
(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
(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"
{
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
(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" "")))]
"TARGET_SSE4_2"
{
bool ok = ix86_expand_int_vcond (operands);
--- 6110,6140 ----
(set_attr "prefix" "orig,vex")
(set_attr "mode" "TI")])
! (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: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 "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:VI8F_128 1 "general_operand" "")
! (match_operand:VI8F_128 2 "general_operand" "")))]
"TARGET_SSE4_2"
{
bool ok = ix86_expand_int_vcond (operands);
***************
*** 6121,6149 ****
DONE;
})
! (define_expand "vcondu<mode>"
! [(set (match_operand:VI124_128 0 "register_operand" "")
! (if_then_else:VI124_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"
{
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
(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" "")))]
"TARGET_SSE4_2"
{
bool ok = ix86_expand_int_vcond (operands);
--- 6142,6172 ----
DONE;
})
! (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: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 "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:VI8F_128 1 "general_operand" "")
! (match_operand:VI8F_128 2 "general_operand" "")))]
"TARGET_SSE4_2"
{
bool ok = ix86_expand_int_vcond (operands);
Index: trunk/gcc/config/ia64/vect.md
===================================================================
*** trunk.orig/gcc/config/ia64/vect.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/ia64/vect.md 2011-08-30 11:46:51.000000000 +0200
***************
*** 661,667 ****
DONE;
})
! (define_expand "vcond<mode>"
[(set (match_operand:VECINT 0 "gr_register_operand" "")
(if_then_else:VECINT
(match_operator 3 ""
--- 661,667 ----
DONE;
})
! (define_expand "vcond<mode><mode>"
[(set (match_operand:VECINT 0 "gr_register_operand" "")
(if_then_else:VECINT
(match_operator 3 ""
***************
*** 675,681 ****
DONE;
})
! (define_expand "vcondu<mode>"
[(set (match_operand:VECINT 0 "gr_register_operand" "")
(if_then_else:VECINT
(match_operator 3 ""
--- 675,681 ----
DONE;
})
! (define_expand "vcondu<mode><mode>"
[(set (match_operand:VECINT 0 "gr_register_operand" "")
(if_then_else:VECINT
(match_operator 3 ""
***************
*** 1382,1388 ****
DONE;
})
! (define_expand "vcondv2sf"
[(set (match_operand:V2SF 0 "fr_register_operand" "")
(if_then_else:V2SF
(match_operator 3 ""
--- 1382,1388 ----
DONE;
})
! (define_expand "vcondv2sfv2sf"
[(set (match_operand:V2SF 0 "fr_register_operand" "")
(if_then_else:V2SF
(match_operator 3 ""
Index: trunk/gcc/config/mips/mips-ps-3d.md
===================================================================
*** trunk.orig/gcc/config/mips/mips-ps-3d.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/mips/mips-ps-3d.md 2011-08-30 11:46:51.000000000 +0200
***************
*** 597,603 ****
[(set_attr "type" "frdiv2")
(set_attr "mode" "<UNITMODE>")])
! (define_expand "vcondv2sf"
[(set (match_operand:V2SF 0 "register_operand")
(if_then_else:V2SF
(match_operator 3 ""
--- 597,603 ----
[(set_attr "type" "frdiv2")
(set_attr "mode" "<UNITMODE>")])
! (define_expand "vcondv2sfv2sf"
[(set (match_operand:V2SF 0 "register_operand")
(if_then_else:V2SF
(match_operator 3 ""
Index: trunk/gcc/config/rs6000/paired.md
===================================================================
*** trunk.orig/gcc/config/rs6000/paired.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/rs6000/paired.md 2011-08-30 11:46:51.000000000 +0200
***************
*** 507,513 ****
DONE;
})
! (define_expand "vcondv2sf"
[(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
(if_then_else:V2SF
(match_operator 3 "gpc_reg_operand"
--- 507,513 ----
DONE;
})
! (define_expand "vcondv2sfv2sf"
[(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
(if_then_else:V2SF
(match_operator 3 "gpc_reg_operand"
Index: trunk/gcc/config/rs6000/vector.md
===================================================================
*** trunk.orig/gcc/config/rs6000/vector.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/rs6000/vector.md 2011-08-30 11:46:51.000000000 +0200
***************
*** 370,376 ****
\f
;; Vector comparisons
! (define_expand "vcond<mode>"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(if_then_else:VEC_F
(match_operator 3 "comparison_operator"
--- 370,376 ----
\f
;; Vector comparisons
! (define_expand "vcond<mode><mode>"
[(set (match_operand:VEC_F 0 "vfloat_operand" "")
(if_then_else:VEC_F
(match_operator 3 "comparison_operator"
***************
*** 388,394 ****
FAIL;
}")
! (define_expand "vcond<mode>"
[(set (match_operand:VEC_I 0 "vint_operand" "")
(if_then_else:VEC_I
(match_operator 3 "comparison_operator"
--- 388,394 ----
FAIL;
}")
! (define_expand "vcond<mode><mode>"
[(set (match_operand:VEC_I 0 "vint_operand" "")
(if_then_else:VEC_I
(match_operator 3 "comparison_operator"
***************
*** 406,412 ****
FAIL;
}")
! (define_expand "vcondu<mode>"
[(set (match_operand:VEC_I 0 "vint_operand" "")
(if_then_else:VEC_I
(match_operator 3 "comparison_operator"
--- 406,412 ----
FAIL;
}")
! (define_expand "vcondu<mode><mode>"
[(set (match_operand:VEC_I 0 "vint_operand" "")
(if_then_else:VEC_I
(match_operator 3 "comparison_operator"
Index: trunk/gcc/config/spu/spu.md
===================================================================
*** trunk.orig/gcc/config/spu/spu.md 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/spu/spu.md 2011-08-30 11:46:51.000000000 +0200
*************** selb\t%0,%4,%0,%3"
*** 3874,3880 ****
\f
;; vector conditional compare patterns
! (define_expand "vcond<mode>"
[(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
(if_then_else:VCMP
(match_operator 3 "comparison_operator"
--- 3874,3880 ----
\f
;; vector conditional compare patterns
! (define_expand "vcond<mode><mode>"
[(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
(if_then_else:VCMP
(match_operator 3 "comparison_operator"
*************** selb\t%0,%4,%0,%3"
*** 3891,3897 ****
FAIL;
})
! (define_expand "vcondu<mode>"
[(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
(if_then_else:VCMPU
(match_operator 3 "comparison_operator"
--- 3891,3897 ----
FAIL;
})
! (define_expand "vcondu<mode><mode>"
[(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
(if_then_else:VCMPU
(match_operator 3 "comparison_operator"
Index: trunk/gcc/genopinit.c
===================================================================
*** trunk.orig/gcc/genopinit.c 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/genopinit.c 2011-08-30 11:46:51.000000000 +0200
*************** static const char * const optabs[] =
*** 253,260 ****
"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_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$))",
--- 253,260 ----
"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_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$))",
Index: trunk/gcc/optabs.c
===================================================================
*** trunk.orig/gcc/optabs.c 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/optabs.c 2011-08-30 11:46:51.000000000 +0200
*************** vector_compare_rtx (tree cond, bool unsi
*** 6620,6646 ****
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. */
static inline enum insn_code
! get_vcond_icode (tree type, enum machine_mode mode)
{
enum insn_code icode = CODE_FOR_nothing;
!
! if (TYPE_UNSIGNED (type))
! icode = direct_optab_handler (vcondu_optab, mode);
else
! icode = direct_optab_handler (vcond_optab, mode);
return icode;
}
/* Return TRUE iff, appropriate vector insns are available
! for vector cond expr with type TYPE in VMODE mode. */
bool
! expand_vec_cond_expr_p (tree type, enum machine_mode vmode)
{
! if (get_vcond_icode (type, vmode) == CODE_FOR_nothing)
return false;
return true;
}
--- 6620,6652 ----
return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
}
! /* 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 (enum machine_mode vmode, enum machine_mode cmode, bool uns)
{
enum insn_code icode = CODE_FOR_nothing;
! if (uns)
! icode = convert_optab_handler (vcondu_optab, vmode, cmode);
else
! icode = convert_optab_handler (vcond_optab, vmode, cmode);
return icode;
}
/* Return TRUE iff, appropriate vector insns are available
! 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 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;
}
*************** expand_vec_cond_expr (tree vec_cond_type
*** 6656,6664 ****
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);
! icode = get_vcond_icode (vec_cond_type, mode);
if (icode == CODE_FOR_nothing)
return 0;
--- 6662,6679 ----
enum insn_code icode;
rtx comparison, rtx_op1, rtx_op2;
enum machine_mode mode = TYPE_MODE (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 (mode, cmp_op_mode, unsignedp);
if (icode == CODE_FOR_nothing)
return 0;
Index: trunk/gcc/optabs.h
===================================================================
*** trunk.orig/gcc/optabs.h 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/optabs.h 2011-08-30 11:46:51.000000000 +0200
*************** enum convert_optab_index
*** 589,594 ****
--- 589,598 ----
COI_vec_load_lanes,
COI_vec_store_lanes,
+ /* Vector conditional operations. */
+ COI_vcond,
+ COI_vcondu,
+
COI_MAX
};
*************** enum convert_optab_index
*** 611,616 ****
--- 615,622 ----
#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];
*************** enum direct_optab_index
*** 632,641 ****
DOI_reload_in,
DOI_reload_out,
- /* Vector conditional operations. */
- DOI_vcond,
- DOI_vcondu,
-
/* Block move operation. */
DOI_movmem,
--- 638,643 ----
*************** typedef struct direct_optab_d *direct_op
*** 699,706 ****
#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])
--- 701,706 ----
*************** extern bool expand_sfix_optab (rtx, rtx,
*** 877,883 ****
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);
/* Generate code for VEC_COND_EXPR. */
extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
--- 877,883 ----
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, tree);
/* Generate code for VEC_COND_EXPR. */
extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
Index: trunk/gcc/tree-vect-stmts.c
===================================================================
*** trunk.orig/gcc/tree-vect-stmts.c 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/tree-vect-stmts.c 2011-08-30 11:46:51.000000000 +0200
*************** vectorizable_load (gimple stmt, gimple_s
*** 4680,4694 ****
LOOP - the loop that is being vectorized.
COND - Condition that is checked for simple use.
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)
{
tree lhs, rhs;
tree def;
enum vect_def_type dt;
if (!COMPARISON_CLASS_P (cond))
return false;
--- 4680,4698 ----
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, 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;
*************** vect_is_simple_cond (tree cond, loop_vec
*** 4699,4706 ****
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))
return false;
}
else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
--- 4703,4710 ----
if (TREE_CODE (lhs) == SSA_NAME)
{
gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
! 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
*************** vect_is_simple_cond (tree cond, loop_vec
*** 4710,4723 ****
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))
return false;
}
else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
&& TREE_CODE (rhs) != FIXED_CST)
return false;
return true;
}
--- 4714,4728 ----
if (TREE_CODE (rhs) == SSA_NAME)
{
gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
! 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;
}
*************** vectorizable_condition (gimple stmt, gim
*** 4744,4755 ****
tree cond_expr, then_clause, else_clause;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
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);
--- 4749,4760 ----
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);
tree def;
enum vect_def_type dt, dts[4];
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
*************** vectorizable_condition (gimple stmt, gim
*** 4800,4812 ****
then_clause = TREE_OPERAND (op, 1);
else_clause = TREE_OPERAND (op, 2);
! 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)))
return false;
if (TREE_CODE (then_clause) == SSA_NAME)
--- 4805,4812 ----
then_clause = TREE_OPERAND (op, 1);
else_clause = TREE_OPERAND (op, 2);
! if (!vect_is_simple_cond (cond_expr, loop_vinfo, &comp_vectype)
! || !comp_vectype)
return false;
if (TREE_CODE (then_clause) == SSA_NAME)
*************** vectorizable_condition (gimple stmt, gim
*** 4833,4845 ****
&& 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 (op), vec_mode);
}
/* Transform */
--- 4833,4842 ----
&& TREE_CODE (else_clause) != FIXED_CST)
return false;
if (!vec_stmt)
{
STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
! return expand_vec_cond_expr_p (vectype, comp_vectype);
}
/* Transform */
Index: trunk/gcc/config/i386/i386.c
===================================================================
*** trunk.orig/gcc/config/i386/i386.c 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/config/i386/i386.c 2011-08-30 11:46:51.000000000 +0200
*************** ix86_expand_sse_cmp (rtx dest, enum rtx_
*** 18412,18430 ****
rtx op_true, rtx op_false)
{
enum machine_mode mode = GET_MODE (dest);
rtx x;
! cmp_op0 = force_reg (mode, cmp_op0);
! if (!nonimmediate_operand (cmp_op1, mode))
! cmp_op1 = force_reg (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));
return dest;
}
--- 18412,18437 ----
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 (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, 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;
}
Index: trunk/gcc/testsuite/gcc.dg/vect/vect-cond-7.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/vect/vect-cond-7.c 2011-08-30 11:46:51.000000000 +0200
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_condition } */
+
+ int vis_type[128];
+ float vs_data[128];
+ void vis_clear_data ()
+ {
+ int i;
+ for (i = 0; i < 128; i++)
+ vs_data[i] = (vis_type[i] == 1);
+ }
+
+ /* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
+ /* { dg-final { cleanup-tree-dump "vect" } } */
Index: trunk/gcc/doc/md.texi
===================================================================
*** trunk.orig/gcc/doc/md.texi 2011-08-30 10:53:47.000000000 +0200
--- trunk/gcc/doc/md.texi 2011-08-30 11:46:51.000000000 +0200
*************** and input vectors should have the same m
*** 4017,4022 ****
--- 4017,4033 ----
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
next prev parent reply other threads:[~2011-08-30 10:17 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-29 15:08 Richard Guenther
2011-08-29 16:36 ` Richard Guenther
2011-08-29 20:47 ` Uros Bizjak
2011-08-29 21:05 ` Richard Guenther
2011-08-30 9:00 ` Uros Bizjak
2011-08-30 9:19 ` Richard Guenther
2011-08-30 9:24 ` Uros Bizjak
2011-08-30 9:29 ` Jakub Jelinek
2011-08-30 9:39 ` Richard Guenther
2011-08-30 9:42 ` Uros Bizjak
2011-08-30 10:17 ` Richard Guenther
2011-08-30 10:48 ` Uros Bizjak
2011-08-30 11:59 ` Richard Guenther
2011-08-30 12:11 ` Richard Guenther [this message]
2011-09-02 9:44 ` Richard Guenther
2011-09-02 12:19 ` Uros Bizjak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LNX.2.00.1108301215390.2130@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=artyom.shinkaroff@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=rth@redhat.com \
--cc=ubizjak@gmail.com \
--cc=uros@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).