On 9/9/26 3:00 AM, 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.

A sext.w would fix that, but ctzw+bclr+sext.w is no shorter than
ctzw+addiw+and and one instruction deeper, so leave the 32 bit case
alone.

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): Skip a decrement wrapped in
        a SIGN_EXTEND.

gcc/testsuite/
        * gcc.target/riscv/bclr-lowest-set-bit-1.c: Expect addi+and for
        the unsigned int cases on rv64.
        * gcc.target/riscv/bclr-lowest-set-bit-2.c: New test.

Signed-off-by: Sun Yuechi <[email protected]>
---

v2: skip the SIGN_EXTEND case instead of extending the result, and
update bclr-lowest-set-bit-1.c for rv64.

Regtested on riscv64-linux-gnu (16.1.0 tree), no regressions.
So I was looking at this in more detail today.  The more I look at it, the more I think that supporting the form with addiw just isn't going to work.

You've already show the code as-is is buggy.  But the explicit sign extension approach doesn't work either.  The key is we have to preserve the semantics of that DI mode AND.

Consider the value 0x1234567880000001.  The result of the original sequence with that input value is 0x1234567880000000.  With the trailing sign extension it would be 0xffffffff80000000.  Clearly not right.


As much as I don't want to lose the optimization in the case where we have the addiw form, I don't see a good way to preserve semantics without doing more nonzero bit testing.  Too bad, this does show up in deepsjeng IIRC.

Jeff

Reply via email to