This is Austin's work to remove the redundant sign extension seen in
pr121213.
--
The .w form of amoswap will sign extend its result from 32 to 64 bits,
thus any explicit sign extension insn doing the same is redundant.
This uses Jivan's approach of allocating a DI temporary for an extended
result and using a promoted subreg extraction to get that result into
the final destination.
Tested with no regressions on riscv32-elf and riscv64-elf and
bootstrapped on the BPI and pioneer systems.
--
Jeff
PR target/121213
gcc/
* config/riscv/sync.md (amo_atomic_exchange_extended<mode>):
Separate insn with sign extension for 64 bit targets.
gcc/testsuite
* gcc.target/riscv/amo/pr121213.c: Remove xfail.
diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index e47bb41adcc..ab6f43066f1 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -376,7 +376,19 @@ (define_expand "atomic_exchange<mode>"
(match_operand:SI 3 "const_int_operand")] ;; model
"TARGET_ZAAMO || TARGET_ZALRSC"
{
- if (TARGET_ZAAMO)
+ if (TARGET_ZAAMO && TARGET_64BIT && <MODE>mode == SImode)
+ {
+ rtx t = gen_reg_rtx (DImode);
+ emit_insn (gen_amo_atomic_exchange_extended (t,
+ operands[1],
+ operands[2],
+ operands[3]));
+ t = gen_lowpart (SImode, t);
+ SUBREG_PROMOTED_VAR_P (t) = 1;
+ SUBREG_PROMOTED_SET (t, SRP_SIGNED);
+ emit_move_insn (operands[0], t);
+ }
+ else if (TARGET_ZAAMO)
emit_insn (gen_amo_atomic_exchange<mode> (operands[0], operands[1],
operands[2], operands[3]));
else
@@ -398,6 +410,19 @@ (define_insn "amo_atomic_exchange<mode>"
[(set_attr "type" "atomic")
(set (attr "length") (const_int 4))])
+(define_insn "amo_atomic_exchange_extended"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (unspec_volatile:SI
+ [(match_operand:SI 1 "memory_operand" "+A")
+ (match_operand:SI 3 "const_int_operand")] ;; model
+ UNSPEC_SYNC_EXCHANGE)))
+ (set (match_dup 1)
+ (match_operand:SI 2 "reg_or_0_operand" "rJ"))]
+ "TARGET_64BIT && TARGET_ZAAMO"
+ "amoswap.w%A3\t%0,%z2,%1"
+ [(set_attr "type" "atomic")
+ (set (attr "length") (const_int 4))])
+
(define_insn "lrsc_atomic_exchange<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&r")
(unspec_volatile:GPR
diff --git a/gcc/testsuite/gcc.target/riscv/amo/pr121213.c
b/gcc/testsuite/gcc.target/riscv/amo/pr121213.c
index 3b2d694f991..6dd59c09462 100644
--- a/gcc/testsuite/gcc.target/riscv/amo/pr121213.c
+++ b/gcc/testsuite/gcc.target/riscv/amo/pr121213.c
@@ -13,5 +13,5 @@ void test1(unsigned* lock) {
/* { 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 *-*-* } } } */
+/* { dg-final { scan-assembler-not "\tsext" } } */