https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111337
--- Comment #7 from JuzheZhong <juzhe.zhong at rivai dot ai> --- (In reply to rguent...@suse.de from comment #6) > On Tue, 12 Sep 2023, juzhe.zhong at rivai dot ai wrote: > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111337 > > > > --- Comment #5 from JuzheZhong <juzhe.zhong at rivai dot ai> --- > > Oh. I see. > > > > > > (define_expand "@vcond_mask_<mode><mode>" > > [(match_operand:VB 0 "register_operand") > > (match_operand:VB 3 "register_operand") > > (match_operand:VB 1 "nonmemory_operand") > > (match_operand:VB 2 "register_operand")] > > "TARGET_VECTOR" > > { > > printf ("vcond_mask\n"); > > }) > > > > I implemented this pattern which can address this issue.... > > > > Note that VB is VECTR_BOOL... > > > > So, this is a more reasonable way to do. Is that right? > > Ah, I suppose ISEL could special-case VECTOR_BOOLEAN_P COND_EXPR > to expand to bitwise ops - it already does this, but only for > non-vector-mode masks: > > /* 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_BOOLEAN_TYPE_P (TREE_TYPE (lhs)) > && !VECTOR_MODE_P (mode)) > { > 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); > } > > that could be a viable expansion strathegy when the rest fails, > but as you can see we need four stmts for this. If you can > think of a smarter, maybe even single-instruction, way for riscv > then yes, handling the above pattern looks good. > > I wonder whether SVE/GCN have those. I have supported this pattern but also need 4 instructions: (define_expand "@vcond_mask_<mode><mode>" [(match_operand:VB 0 "register_operand") (match_operand:VB 1 "register_operand") (match_operand:VB 2 "register_operand") (match_operand:VB 3 "register_operand")] "TARGET_VECTOR" { /* mask1 = operands[3] & operands[1]. */ rtx mask1 = expand_binop (<MODE>mode, and_optab, operands[1], operands[3], NULL_RTX, 0, OPTAB_DIRECT); /* mask2 = ~operands[3] & operands[2]. */ rtx inverse = expand_unop (<MODE>mode, one_cmpl_optab, operands[3], NULL_RTX, OPTAB_DIRECT); rtx mask2 = expand_binop (<MODE>mode, and_optab, operands[2], inverse, NULL_RTX, 0, OPTAB_DIRECT); /* result = mask1 | mask2. */ rtx result = expand_binop (<MODE>mode, ior_optab, mask1, mask2, NULL_RTX, 0, OPTAB_DIRECT); emit_move_insn (operands[0], result); DONE; })