[gcc r17-2934] [PATCH v5] RISC-V: Fix riscv_subword_address for big-endian targets.
Jeff Law via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 14:18:37 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:91dda5028f6a7adcb4bf8f98484dd9fd719011eb commit r17-2934-g91dda5028f6a7adcb4bf8f98484dd9fd719011eb Author: Aleksa Paunovic <[email protected]> Date: Tue Aug 4 08:17:47 2026 -0600 [PATCH v5] RISC-V: Fix riscv_subword_address for big-endian targets. Ensure the proper sub-word address is computed when using built-in atomics on big-endian RISC-V targets. Without this change, multiple tests were failing, including: libatomic.c/atomic-compare-exchange-1.c libatomic.c/atomic-compare-exchange-2.c libatomic.c/atomic-exchange-1.c libatomic.c/atomic-exchange-2.c libatomic.c/atomic-op-1.c libatomic.c/atomic-op-2.c libatomic.c/generic-2.c gcc.target/riscv/amo/inline-atomics-3.c gcc.target/riscv/amo/inline-atomics-4.c gcc.target/riscv/amo/inline-atomics-5.c gcc.target/riscv/amo/inline-atomics-6.c gcc.target/riscv/amo/inline-atomics-7.c gcc.target/riscv/amo/inline-atomics-8.c The patch was tested using QEMU modified to run big-endian RISC-V executables [1]. [1] https://github.com/djtodoro/qemu/tree/riscvbe/current# --- Changes in v5: - Drop -O0 from both tests and add a return value to avoid any potential DCE issues. - Move -mbig-endian to dg-additional-options. - Remove the dg-xfail-if for RVV on big-endian builds. - Link to v4: https://patchwork.sourceware.org/project/gcc/patch/[email protected]/ gcc/ChangeLog: * config/riscv/riscv.cc (riscv_subword_address): Add emit_move_insn for big-endian. gcc/testsuite/ChangeLog: * gcc.target/riscv/amo/big-endian-subword-amo-hi.c: New test. * gcc.target/riscv/amo/big-endian-subword-amo-qi.c: New test. Signed-off-by: Aleksa Paunovic <[email protected]> Diff: --- gcc/config/riscv/riscv.cc | 5 +++++ gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c | 10 ++++++++++ gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c | 10 ++++++++++ 3 files changed, 25 insertions(+) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 83f552c5e468..e319ccaecad0 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -13565,6 +13565,11 @@ riscv_subword_address (rtx mem, rtx *aligned_mem, rtx *shift, rtx *mask, /* Calculate the shift amount. */ emit_move_insn (*shift, gen_rtx_AND (SImode, gen_lowpart (SImode, addr), gen_int_mode (3, SImode))); + if (TARGET_BIG_ENDIAN) + emit_move_insn (*shift, gen_rtx_XOR (SImode, *shift, + gen_int_mode (GET_MODE (mem) == QImode + ? 3 : 2, SImode))); + emit_move_insn (*shift, gen_rtx_ASHIFT (SImode, *shift, gen_int_mode (3, SImode))); diff --git a/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c new file mode 100644 index 000000000000..c5dfe374f403 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-hi.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mbig-endian" } */ +/* Verify that subword atomic operations use XOR for big-endian halfword alignment. */ +/* { dg-final { scan-assembler "xori\\s+\[a-z0-9\]+,\[a-z0-9\]+,2" } } */ + +short atomic_fetch_add_hi(short *ptr, short val) +{ + __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED); + return val; +} diff --git a/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c new file mode 100644 index 000000000000..1c37ececf728 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/amo/big-endian-subword-amo-qi.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-mbig-endian" } */ +/* Verify that subword atomic operations use XOR for big-endian byte alignment. */ +/* { dg-final { scan-assembler "xori\\s+\[a-z0-9\]+,\[a-z0-9\]+,3" } } */ + +char atomic_fetch_add_qi(char *ptr, char val) +{ + __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED); + return val; +}