On 9/6/26 8:55 PM, Sun Yuechi wrote:
addi+and keeps a 32 bit object sign extended on rv64, bclr does not:
clearing bit 31 leaves 0xffffffff00000000, so the loop
(m = x; m; m &= m - 1) never terminates.
Wrong code since r16-3984-g4f01f39d021; it hangs rte_softrss() in DPDK
built with -march=rva23u64.
gcc/
* config/riscv/riscv-bclr-lowest-set-bit.cc
(pass_bclr_lowest_set_bit::execute): Sign extend the bclr result
for a sub-word operand.
gcc/testsuite/
* gcc.target/riscv/bclr-lowest-set-bit-2.c: New test.
Thinking more about this, a few things come to mind.
First , we could check nonzero_bits before making the transformation.
That would allow us to avoid the problem case of 0x80000000 when we have
useful data on bit state.
Second, we could run this pass before combine with your change. That
would give combine the chance to eliminate the sign extension in cases
where it knows the upper 32bits aren't needed. It won't always be
possible, but it may help enough to save this optimization in relatively
common cases.
I don't recall the precise reason why I put this after combine.
Anyway, happy to hear your thoughts.
Note if we go with something like your patch and running before combine,
I think your patch can be simplified. We don't need to deal with
arbitrary source modes. The embedded SIGN_EXTEND will only happen for
SI->DI extensions because that's how the W form instructions work in the
ISA. No other SIGN_EXTEND cases are possible.;
Jeff