On Wed, 25 Nov 2020, Richard Sandiford wrote:

> Richard Biener <rguent...@suse.de> writes:
> > This makes sure to lower VECTOR_BOOLEAN_TYPE_P typed VEC_COND_EXPRs
> > so we don't try to use vcond to expand those.  That's especially
> > improtant for x86 integer mode boolean vectors but eventually
> > as well for aarch64 / gcn VnBImode ones.
> >
> > Bootstrap and regtest running on x86_64-unknown-linux-gnu.
> >
> > 2020-11-25  Richard Biener  <rguent...@suse.de>
> >
> >     PR middle-end/97579
> >     * gimple-isel.cc (gimple_expand_vec_cond_expr): Lower
> >     VECTOR_BOOLEAN_TYPE_P VEC_COND_EXPRs.
> >
> >     * gcc.dg/pr97579.c: New testcase.
> > ---
> >  gcc/gimple-isel.cc             | 21 +++++++++++++++++++--
> >  gcc/testsuite/gcc.dg/pr97579.c | 31 +++++++++++++++++++++++++++++++
> >  2 files changed, 50 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/pr97579.c
> >
> > diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
> > index b5362cc4b01..eac1f62e1ff 100644
> > --- a/gcc/gimple-isel.cc
> > +++ b/gcc/gimple-isel.cc
> > @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "tree-ssa-dce.h"
> >  #include "memmodel.h"
> >  #include "optabs.h"
> > +#include "gimple-fold.h"
> >  
> >  /* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into calls to
> >     internal function based on vector type of selected expansion.
> > @@ -134,6 +135,24 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
> >    lhs = gimple_assign_lhs (stmt);
> >    machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
> >  
> > +  /* Lower mask typed VEC_COND_EXPRs to bitwise operations.  Those can
> > +     end up generated by folding and at least for integer mode masks
> > +     we cannot expect vcond expanders to exist.  We lower a ? b : c
> > +     to (b & a) | (c & ~a).  */
> 
> I think it is reasonable to provide them for vector modes though.
> E.g. for SVE we have:
> 
> (define_insn "@vcond_mask_<mode><mode>"
>   [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
>       (ior:PRED_ALL
>         (and:PRED_ALL
>           (match_operand:PRED_ALL 3 "register_operand" "Upa")
>           (match_operand:PRED_ALL 1 "register_operand" "Upa"))
>         (and:PRED_ALL
>           (not (match_dup 3))
>           (match_operand:PRED_ALL 2 "register_operand" "Upa"))))]
>   "TARGET_SVE"
>   "sel\t%0.b, %3, %1.b, %2.b"
> )
> 
> So it might better to check for an integer mode as well.

OK, I'll adjust accordingly.  Looks like GCN uses DImode.

(define_expand "vcond_mask_<mode>di"
  [(parallel
    [(set (match_operand:V_ALL 0   "register_operand" "")
          (vec_merge:V_ALL
            (match_operand:V_ALL 1 "gcn_vop3_operand" "")
            (match_operand:V_ALL 2 "gcn_alu_operand" "")
            (match_operand:DI 3              "register_operand" "")))
     (clobber (scratch:<VnDI>))])]
  ""
  "")


Richard.

> Thanks,
> Richard
> 
> > +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
> > +    {
> > +      gcc_assert (types_compatible_p (TREE_TYPE (op0), TREE_TYPE (op1)));
> > +      gimple_seq stmts = NULL;
> > +      tree type = TREE_TYPE (lhs);
> > +      location_t loc = gimple_location (stmt);
> > +      tree tem0 = gimple_build (&stmts, loc, BIT_AND_EXPR, type, op1, op0);
> > +      tree tem1 = gimple_build (&stmts, loc, BIT_NOT_EXPR, type, op0);
> > +      tree tem2 = gimple_build (&stmts, loc, BIT_AND_EXPR, type, op2, 
> > tem1);
> > +      tree tem3 = gimple_build (&stmts, loc, BIT_IOR_EXPR, type, tem0, 
> > tem2);
> > +      gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
> > +      return gimple_build_assign (lhs, tem3);
> > +    }
> > +
> >    gcc_assert (!COMPARISON_CLASS_P (op0));
> >    if (TREE_CODE (op0) == SSA_NAME)
> >      {
> > @@ -198,7 +217,6 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
> >    cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
> >    unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
> >  
> > -
> >    gcc_assert (known_eq (GET_MODE_NUNITS (mode),
> >                     GET_MODE_NUNITS (cmp_op_mode)));
> >  
> > @@ -246,7 +264,6 @@ gimple_expand_vec_exprs (void)
> >     {
> >       gimple *g = gimple_expand_vec_cond_expr (&gsi,
> >                                                &vec_cond_ssa_name_uses);
> > -
> >       if (g != NULL)
> >         {
> >           tree lhs = gimple_assign_lhs (gsi_stmt (gsi));
> > diff --git a/gcc/testsuite/gcc.dg/pr97579.c b/gcc/testsuite/gcc.dg/pr97579.c
> > new file mode 100644
> > index 00000000000..5cd5427a528
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr97579.c
> > @@ -0,0 +1,31 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O3 --param=max-unswitch-insns=1024" } */
> > +/* { dg-additional-options "-mavx512vl" { target x86_64-*-* i?86-*-* } } */
> > +
> > +int bad_odd_rows_0_0, rows_bad_row1, rows_bad_group_okay, calc_rows_row2;
> > +
> > +int
> > +rows_bad() {
> > +  int i, in_zeroes;
> > +  char block;
> > +  i = 0;
> > +  for (; i < 5; i++)
> > +    if (rows_bad_row1 & i)
> > +      in_zeroes = 0;
> > +    else {
> > +      if (!in_zeroes)
> > +        in_zeroes = 1;
> > +      if (block & 1)
> > +        rows_bad_group_okay = 1;
> > +    }
> > +  if (in_zeroes)
> > +    return rows_bad_group_okay;
> > +}
> > +
> > +void
> > +calc_rows() {
> > +  for (; calc_rows_row2; calc_rows_row2++) {
> > +    rows_bad();
> > +    bad_odd_rows_0_0 = rows_bad();
> > +  }
> > +}
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend

Reply via email to