https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93183
--- Comment #3 from prathamesh3492 at gcc dot gnu.org --- (In reply to rsand...@gcc.gnu.org from comment #2) > (In reply to Andrew Pinski from comment #1) > > We get: > > .L3: > > ld1b z0.b, p0/z, [x1, x3] > > movprfx z2, z0 > > and z2.b, z2.b, #0xc0 > > neg z1.b, p1/m, z0.b ;;; <<<< THIS > > cmpeq p2.b, p1/z, z2.b, #0 > > sel z0.b, p2, z0.b, z1.b ;;;; <<<< AND THIS > > st1b z0.b, p0, [x0, x3] > > incb x3 > > whilelo p0.b, w3, w2 > > b.any .L3 > > > > The two instructions marked should be combined. > > The problem is that it isn't a straight combination of the > NEG and SEL, because the condition is the inverse of the one > that we want for predication. IIUC, sel is redundant and we could generate following code instead for the inner loop ? ld1b z0.b, p0/z, [x1, x2] movprfx z2, z0 and z2.b, z2.b, #0xc0 cmpne p2.b, p1/z, z2.b, #0 neg z0.b, p2/m, z0.b st1b z0.b, p0, [x0, x3] incb x3 whilelo p0.b, w3, w2 b.any .L3 > > This is one of the things that the IFN_COND_* functions were > designed to fix. We should probably add unary versions of those. The input to isel pass is: vect__3.11_39 = .MASK_LOAD (_22, 8B, loop_mask_38); vect_t1_15.12_41 = vect__3.11_39 & { 192, ... }; vect_t_12.13_42 = -vect__3.11_39; _44 = vect_t1_15.12_41 == { 0, ... }; vect_iftmp.14_45 = VEC_COND_EXPR <_44, vect__3.11_39, vect_t_12.13_42>; where vect__3.11_39 and vect_t_12.13_42 are negatives of each other. I suppose in isel pass if we come across vec_cond_expr of the form: op2 = vec_cond_expr<cond, op1, -op1> then we could lower it to a new internal function say IFN_COND_NEG. IFN_COND_NEG could use a new optab say cond_neg_optab to expand it to: movprfx op2, op1 set predicate according to inverted cond op2 = predicate/m neg op2 Does this look reasonable ? Thanks, Prathamesh