https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122769

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Vineet Gupta from comment #3)
> (In reply to Andrew Pinski from comment #2)
> > .
> > 
> >         slti    a0,a0,0
> >         czero.eqz       a0,a3,a0
> >         xor     a0,a0,a1
> > 
> > Which I can get via:
> > ```
> > uint64_t f1(uint64_t val, uint64_t val2, int bits, uint64_t n) {
> >   uint64_t t = -(((int64_t)val) < 0);
> >   val2 ^= (t & n);
> >   return val2;
> > }
> > ```
> > Which does the right thing there ...
> 
> That's because it already expands to a czero
> 
> (insn 11 10 12 2 (set (reg:SI 144 [ _9 ])
>         (if_then_else:SI (ne:DI (reg:DI 145)
>                 (const_int 0 [0]))
>             (reg:SI 146)
>             (const_int 0 [0]))) "test4.c":6:14 40364 {*czero.eqz.sidi}
>      (nil))
> 
> OTOH, llvm seems to be transforming
> 
>   if (val & (1ULL << 63))
>      val2 ^= n;
> 
> to something like (note that @n has actually moved where its been used)
> 
>   uint64_t tmp = (val >> 63) & n;
>   val2 ^= tmp;
> 
>   
> I need some guidance as to where to tackle this ?

In ifcvt.cc is the best place to start. The next place is figuring out how to
hook up some target specific match patterns to phiopt for the late one (you
can/should use fold_before_rtl_expansion_p () function to say it is late).

Reply via email to