]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[RISC-V][PR target/121213] Avoid unnecessary sign extension in amoswap sequence
authorAustin Law <austinklaw@gmail.com>
Wed, 3 Sep 2025 16:41:17 +0000 (10:41 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 3 Sep 2025 16:41:17 +0000 (10:41 -0600)
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.

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.

gcc/config/riscv/sync.md
gcc/testsuite/gcc.target/riscv/amo/pr121213.c

index e47bb41adcc2c10abfb663aa60aa9de7e2261d6d..ab6f43066f10db752e107dc1d00c56b7c3207a2d 100644 (file)
    (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
   [(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
index 3b2d694f991480a9c44acb5eca43a7fbbf49b919..6dd59c09462e97b6190c64a9551866dc319e127d 100644 (file)
@@ -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" } } */