This patch introduces a new RTL pattern for bset + sext + or and Test cases for this pattern.
The patch does not fully resolve the bug itself, but only one specific case of it. The pattern is written this way because the issue only occurs with the bset + sext sequence when the output is a 64-bit value, where the upper 32bits are lost during the sext instruction. Example: dest = 0xFFFFFFFF00000001 a = 29 In the initial implementation, we get: 0xFFFFFFFF00000001 | 0x0000000020000000 which results in: 0xFFFFFFFF20000001 However, with the bset + sext sequence, the behavior is incorrect: after bset : 0xFFFFFFFF20000001 after sext : 0x0000000020000001 So the sign extension is performed incorrectly, causing the upper 32 bits to be discarded and leading to an incorrect final result. The issue is that both long and int cases currently share the same RTL in the combine pass when our pattern matches, so at the moment I do not have a clear way to distinguish between them. As a result, GCC also generates bset + sext + or for the int case, where it should generate only bset + sext. Regression testing on RISC-V trunk completed with no new failures. 2026-05-07 Milan Tripkovic <[email protected]> gcc/ChangeLog: * config/riscv/bitmanip.md (bset_sextw_or): new pattern for bset gcc/testsuite/ChangeLog: * gcc.target/riscv/pr123884-c.c: New test for new pattern CONFIDENTIALITY: The contents of this e-mail are confidential and intended only for the above addressee(s). If you are not the intended recipient, or the person responsible for delivering it to the intended recipient, copying or delivering it to anyone else or using it in any unauthorized manner is prohibited and may be unlawful. If you receive this e-mail by mistake, please notify the sender and the systems administrator at [email protected] immediately.
