https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126074
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jeff Law <[email protected]>: https://gcc.gnu.org/g:f95a1c7f4e4b1f4c41e40d2eab8cbde258292962 commit r17-4462-gf95a1c7f4e4b1f4c41e40d2eab8cbde258292962 Author: Milan Tripkovic <[email protected]> Date: Sat Sep 19 07:55:27 2026 -0600 [PATCH] RISC-V: PR target/126074 - Missing cases for constant synthesis on RISC-V This patch implements the shNadd.uw case from the PR. The instruction shNadd.uw a0, a0, a0 computes: ((a0 & 0xffffffff) << N) + a0 If a0 holds a value sign extended from bit 31, with u being its low 32 bits, this formula evaluates to: u * (2^N + 1) - 2^32 This allows us to build certain 64-bit constants using just a lui and a single shNadd.uw. To find u, riscv_build_integer_1 reverses the formula: it adds 2^32 to the constant and divide it by 3, 5, or 9. If the quotient fits in 32 bits with bit 31 set, and the new sequence is cheaper, we emit an FMA entry with use_uw set. For 0x180005000, before: ââââââli a0,1572864 ââââââaddi t0,a0,5 ââââââslli a0,t0,12 after: ââââââliââââa0,-715821056 ââââââsh1add.uwâââa0,a0,a0 Finally, in riscv_move_integer, the FMA check is moved above the use_uw check. Since our shNadd.uw case sets use_uw = true, checking use_uw first would mistakenly treat the operation as a plain zero-extended shift instead of shNadd.uw. PR target/126074 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_build_integer_1): Add logic to synthesize constants using shNadd.uw. (riscv_move_integer): Handle FMA with use_uw for RTL emission. gcc/testsuite/ChangeLog: * gcc.target/riscv/pr126074.c: New test.
