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

Reply via email to