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 ?