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

--- Comment #3 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
(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 ?

Reply via email to