[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] [PR target/121213] Avoid unnecessary constant load in amoswap
Jeff Law
law@gcc.gnu.org
Sat Sep 13 16:27:10 GMT 2025
https://gcc.gnu.org/g:580cd2fc9fb8c936abcc8514b21843c7ee53cff7
commit 580cd2fc9fb8c936abcc8514b21843c7ee53cff7
Author: Austin Law <austinklaw@gmail.com>
Date: Sun Aug 17 09:03:51 2025 -0600
[PR target/121213] Avoid unnecessary constant load in amoswap
PR 121213 shows an unnecessary "li target,0" in an atomic exchange loop
on RISC-V.
The source operand for an amoswap instruction should allow (const_int 0)
in addition to GPRs. So the operand's predicate is changed to
"reg_or_0_operand". The corresponding constraint is also changed to
allow a reg or the constant 0.
With the source operand no longer tied to the destination operand we do
not need the earlyclobber for the destination, so the destination
operand's constraint is adjusted accordingly.
This patch does not address the unnecessary sign extension reported in
the PR.
Tested with no regressions on riscv32-elf and riscv64-elf.
PR target/121213
gcc/
* config/riscv/sync.md (amo_atomic_exchange<mode>): Allow
(const_int 0) as input operand. Do not tie input to output.
No longer earlyclobber the output.
gcc/testsuite
* gcc.target/riscv/amo/pr121213.c: New test.
(cherry picked from commit 6f63044a7ae63a276a4f6d3108849e093c690bc6)
Diff:
---
gcc/config/riscv/sync.md | 8 ++++----
gcc/testsuite/gcc.target/riscv/amo/pr121213.c | 17 +++++++++++++++++
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index 50ec8b38f723..e47bb41adcc2 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -386,13 +386,13 @@
})
(define_insn "amo_atomic_exchange<mode>"
- [(set (match_operand:GPR 0 "register_operand" "=&r")
+ [(set (match_operand:GPR 0 "register_operand" "=r")
(unspec_volatile:GPR
[(match_operand:GPR 1 "memory_operand" "+A")
(match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_SYNC_EXCHANGE))
(set (match_dup 1)
- (match_operand:GPR 2 "register_operand" "0"))]
+ (match_operand:GPR 2 "reg_or_0_operand" "rJ"))]
"TARGET_ZAAMO"
"amoswap.<amo>%A3\t%0,%z2,%1"
[(set_attr "type" "atomic")
@@ -434,13 +434,13 @@
})
(define_insn "zabha_atomic_exchange<mode>"
- [(set (match_operand:SHORT 0 "register_operand" "=&r")
+ [(set (match_operand:SHORT 0 "register_operand" "=r")
(unspec_volatile:SHORT
[(match_operand:SHORT 1 "memory_operand" "+A")
(match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_SYNC_EXCHANGE_ZABHA))
(set (match_dup 1)
- (match_operand:SHORT 2 "register_operand" "0"))]
+ (match_operand:SHORT 2 "reg_or_0_operand" "rJ"))]
"TARGET_ZABHA"
"amoswap.<amobh>%A3\t%0,%z2,%1"
[(set_attr "type" "atomic")
diff --git a/gcc/testsuite/gcc.target/riscv/amo/pr121213.c b/gcc/testsuite/gcc.target/riscv/amo/pr121213.c
new file mode 100644
index 000000000000..3b2d694f9914
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/amo/pr121213.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64gc -mabi=lp64" { target { rv64 } } } */
+/* { dg-options "-O2 -march=rv32gc -mabi=ilp32" { target { rv32 } } } */
+
+void test0(unsigned long* lock) {
+ while (!__atomic_exchange_n(lock, 0, __ATOMIC_ACQUIRE));
+}
+
+
+void test1(unsigned* lock) {
+ while (!__atomic_exchange_n(lock, 0, __ATOMIC_ACQUIRE));
+}
+
+/* { dg-final { scan-assembler-not "\tli" } } */
+/* { dg-final { scan-assembler-times "\tamoswap...aq\t\[axt\]\[0-9\],zero," 2 } } */
+/* { dg-final { scan-assembler-not "\tsext" { xfail *-*-* } } } */
+
More information about the Gcc-cvs
mailing list