I encountered a miscompilation case with zbs, where bseti without sign extension emitted from bsetidisi pattern leads to wrong output. Take pr68648.c as an example, -march=rv64gc_zba_zbb_zbs -O3 did not generate sext.w in int bar (void) and led to a wrong value in a0. It seems that the partial subreg check is wrongly set to the immediate operand. int foo (void): li a0,123 ret int bar (void): addi sp,sp,-16 sd ra,8(sp) call foo # a0 123 li a5,248639488 # a0 123, a5 0xed1f000 addi a5,a5,11 # a0 123, a5 0xed1f00b slli a5,a5,14 # a0 123, a5 0x3b47c02c000 addi a5,a5,-8 # a0 123, a5 0x3b47c02bff8 ld ra,8(sp) or a0,a0,a5 # a0 0x3b47c02bffb, a5 0x3b47c02bff8 bseti a5,zero,32 # a0 0x3b47c02bffb, a5 0x100000000 addi a5,a5,-1 # a0 0x3b47c02bffb, a5 0x0ffffffff xor a0,a0,a5 # a0 0x3b483fd4004, a5 0x0ffffffff bseti a0,a0,0 # a0 0x3b483fd4005, a5 0x0ffffffff addi sp,sp,16 # sext.w a0,a0 is missing jr ra main: addi sp,sp,-16 sd ra,8(sp) call bar li a5,-2080555008 addi a5,a5,5 bne a0,a5,.L8 # a0 0x3b483fd4005, a5 0x83fd4005 ld ra,8(sp) li a0,0 addi sp,sp,16 jr ra .L8: call abort Lin Sinan 于2023年2月28日周二 13:00写道: > From: Lin Sinan > > The partial subreg check should be for subreg operand(operand 1) instead of > the immediate operand(operand 2). This change also fix pr68648.c in zbs. > > gcc/ChangeLog: > > * config/riscv/bitmanip.md: Fix wrong index in the check. > > --- > gcc/config/riscv/bitmanip.md | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md > index 14d18edbe62..58a86bd929f 100644 > --- a/gcc/config/riscv/bitmanip.md > +++ b/gcc/config/riscv/bitmanip.md > @@ -442,7 +442,7 @@ > (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" > "r")) > (match_operand 2 "single_bit_mask_operand" "i")))] > "TARGET_ZBS && TARGET_64BIT > - && !partial_subreg_p (operands[2])" > + && !partial_subreg_p (operands[1])" > "bseti\t%0,%1,%S2" > [(set_attr "type" "bitmanip")]) > > -- > 2.34.1 > >