https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124741
--- 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:b6bebf2a7326e6b5566f1aa2979233a60e5c8377 commit r17-2556-gb6bebf2a7326e6b5566f1aa2979233a60e5c8377 Author: Shreya Munnangi <[email protected]> Date: Mon Jul 20 07:02:48 2026 -0600 [PATCH][RISC-V][PR target/124741] Improving atomic sequences In PR 124741, we have a testcase: typedef struct { int x; unsigned repr; } atomic_u_t; unsigned atomic_load_u (const atomic_u_t *a) { unsigned result; __atomic_load (&a->repr, &result, 0); return result; } When compiled with rv64, it outputs: addi a5,a0,4 lw a0,0(a5) sext.w a0,a0 ret Here we have a redundant sign extension and inefficient address arithmetic. This can be simplified into two instructions, a load and a return. The lw insn is already doing a sign extension from 32 to 64 bits, making the separate sext.w unnecessary. Adding a copy of the pattern that explicitly shows the sign extension in the RTL, with the modes adjusted accordingly, no longer emits the sext.w insn. I also generalized the pattern to support both sign and zero extension. These changes have been reflected on the total store ordering memory consistency model as well. As Zalrsc doesn't support zero extending load-acquire instructions, I introduced a new iterator, ensuring zero extend is limited to !TARGET_ZALRSC for load. The addi and lw are combined into lw a0,4(a5) by adjusting the memory operand constraint to handle offsets in the load patterns. The validity of the memory operand constraint depends on the value of operand 2 - the memory model. I introduced new constraint alternatives, such that the behavior of the memory operand constraint is triggered on whether the memory model acquire is being used or not and the Zalrsc or non-Zalrsc targets accordingly. Similar changes were made for the store patterns where the inefficient address arithmetic problem was also present. PR target/124741 gcc/ * config/riscv/constraints.md (B1, B2, B3, B4): New constraints for atomic loads with and without ZALASR & MEMMODEL_ACQUIRE. * config/riscv/iterators.md (cond_extend): New iterator to for use in extending atomic loads. * config/riscv/sync-rvwmo.md (atomic_load_rvwmo<mode>): Adjust contraints to enable folding small offsets into memory load. (atomic_store_rvwmo): Likewise. (extending atomic_load_rvwmo): New pattern. * config/riscv/sync-ztso.md (atomic_load_ztso<mode>): Adjust constraints to enable folding small offsets into memory load. (atomic_store_ztso): Likewise. (extending atomic_load_ztso): New pattern. gcc/testsuite/ * gcc.target/riscv/load-zalasr.c: Testcases for atomic load compiled with rv64 and zalasr ext. * gcc.target/riscv/load.c: Testcases for atomic load compiled with rv64. * gcc.target/riscv/load32-zalasr.c: Testcases for atomic load compiled with rv32 and zalasr ext. * gcc.target/riscv/load32.c: Testcases for atomic load compiled with rv32. * gcc.target/riscv/store-zalasr.c: Testcases for atomic store compiled with rv64 and zalasr ext. * gcc.target/riscv/store.c: Testcases for atomic store compiled with rv64. * gcc.target/riscv/store32-zalasr.c: Testcases for atomic store compiled with rv32 and zalasr ext. * gcc.target/riscv/store32.c: Testcases for atomic store compiled with rv32. Co-authored-by: Jeff Law <[email protected]>
