On Wed, 25 Nov 2020, Richard Biener wrote: > 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>))])] > "" > "")
The following is what I pushed. Richard. >From 6a3223f2a445d5a1872f65cabe922fbe2d86eb1b Mon Sep 17 00:00:00 2001 From: Richard Biener <rguent...@suse.de> Date: Wed, 25 Nov 2020 12:31:54 +0100 Subject: [PATCH] middle-end/97579 - lower VECTOR_BOOLEAN_TYPE_P VEC_COND_EXPRs To: gcc-patches@gcc.gnu.org This makes sure to lower VECTOR_BOOLEAN_TYPE_P typed non-vector mode VEC_COND_EXPRs so we don't try to use vcond to expand those. That's required for x86 and gcn integer mode boolean vectors. 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, non-vector mode VEC_COND_EXPRs. * gcc.dg/pr97579.c: New testcase. --- gcc/gimple-isel.cc | 22 ++++++++++++++++++++-- gcc/testsuite/gcc.dg/pr97579.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 51 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..83281c0cbf9 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,25 @@ 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, non-vector mode 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). */ + if (!VECTOR_MODE_P (mode)) + { + gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)) + && 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 +218,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 +265,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(); + } +} -- 2.26.2