[llvm] [LoongArch] fix: Support LoongArch atomic memory operations with monotonic semantics (PR #112681)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 23:33:56 PDT 2024


https://github.com/tangaac updated https://github.com/llvm/llvm-project/pull/112681

>From c463953111ba638122b019d61c048eb8bfdd8121 Mon Sep 17 00:00:00 2001
From: tangaac <tangyan01 at loongson.cn>
Date: Wed, 16 Oct 2024 17:43:39 +0800
Subject: [PATCH 1/2] fix: Support LoongArch atomic memory operations with
 monotonic semantics

---
 .../Target/LoongArch/LoongArchInstrInfo.td    | 42 ++++++++++++++++++
 .../ir-instruction/atomicrmw-minmax.ll        | 16 +++----
 .../LoongArch/ir-instruction/atomicrmw.ll     | 44 +++++++++----------
 3 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 15a8f4e3c0755d..a93f552b5a8fe8 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -2076,6 +2076,48 @@ defm atomic_cmp_swap_i32 : ternary_atomic_op_failure_ord;
 defm atomic_cmp_swap_i64 : ternary_atomic_op_failure_ord;
 
 let Predicates = [IsLA64] in {
+
+def : Pat<(atomic_swap_i32_monotonic GPR:$addr, GPR:$incr),
+          (AMSWAP_W GPR:$incr, GPR:$addr)>;
+def : Pat<(atomic_swap_i64_monotonic GPR:$addr, GPR:$incr),
+          (AMSWAP_D GPR:$incr, GPR:$addr)>;
+def : Pat<(atomic_load_add_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMADD_W GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_add_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMADD_D GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_sub_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMADD_W (SUB_W R0, GPR:$rk), GPR:$rj)>;
+def : Pat<(atomic_load_sub_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMADD_D (SUB_D R0, GPR:$rk), GPR:$rj)>;
+def : Pat<(atomic_load_and_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMAND_W GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_and_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMAND_D GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_or_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMOR_W GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_or_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMOR_D GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_xor_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMXOR_W GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_xor_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMXOR_D GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_umin_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMMIN_WU GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_umin_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMMIN_DU GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_umax_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMMAX_WU GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_umax_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMMAX_DU GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_min_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMMIN_W GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_min_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMMIN_D GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_max_i32_monotonic GPR:$rj, GPR:$rk),
+          (AMMAX_W GPR:$rk, GPR:$rj)>;
+def : Pat<(atomic_load_max_i64_monotonic GPR:$rj, GPR:$rk),
+          (AMMAX_D GPR:$rk, GPR:$rj)>;
+
 def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
                 PseudoMaskedAtomicSwap32>;
 def : Pat<(atomic_swap_i32 GPR:$addr, GPR:$incr),
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll
index 2bd29c2670a680..03386514a72c80 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll
@@ -1368,7 +1368,7 @@ define i16 @atomicrmw_umax_i16_monotonic(ptr %a, i16 %b) nounwind {
 define i32 @atomicrmw_umax_i32_monotonic(ptr %a, i32 %b) nounwind {
 ; LA64-LABEL: atomicrmw_umax_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammax_db.wu $a2, $a1, $a0
+; LA64-NEXT:    ammax.wu $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw umax ptr %a, i32 %b monotonic
@@ -1378,7 +1378,7 @@ define i32 @atomicrmw_umax_i32_monotonic(ptr %a, i32 %b) nounwind {
 define i64 @atomicrmw_umax_i64_monotonic(ptr %a, i64 %b) nounwind {
 ; LA64-LABEL: atomicrmw_umax_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammax_db.du $a2, $a1, $a0
+; LA64-NEXT:    ammax.du $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw umax ptr %a, i64 %b monotonic
@@ -1445,7 +1445,7 @@ define i16 @atomicrmw_umin_i16_monotonic(ptr %a, i16 %b) nounwind {
 define i32 @atomicrmw_umin_i32_monotonic(ptr %a, i32 %b) nounwind {
 ; LA64-LABEL: atomicrmw_umin_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammin_db.wu $a2, $a1, $a0
+; LA64-NEXT:    ammin.wu $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw umin ptr %a, i32 %b monotonic
@@ -1455,7 +1455,7 @@ define i32 @atomicrmw_umin_i32_monotonic(ptr %a, i32 %b) nounwind {
 define i64 @atomicrmw_umin_i64_monotonic(ptr %a, i64 %b) nounwind {
 ; LA64-LABEL: atomicrmw_umin_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammin_db.du $a2, $a1, $a0
+; LA64-NEXT:    ammin.du $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw umin ptr %a, i64 %b monotonic
@@ -1531,7 +1531,7 @@ define i16 @atomicrmw_max_i16_monotonic(ptr %a, i16 %b) nounwind {
 define i32 @atomicrmw_max_i32_monotonic(ptr %a, i32 %b) nounwind {
 ; LA64-LABEL: atomicrmw_max_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammax_db.w $a2, $a1, $a0
+; LA64-NEXT:    ammax.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw max ptr %a, i32 %b monotonic
@@ -1541,7 +1541,7 @@ define i32 @atomicrmw_max_i32_monotonic(ptr %a, i32 %b) nounwind {
 define i64 @atomicrmw_max_i64_monotonic(ptr %a, i64 %b) nounwind {
 ; LA64-LABEL: atomicrmw_max_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammax_db.d $a2, $a1, $a0
+; LA64-NEXT:    ammax.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw max ptr %a, i64 %b monotonic
@@ -1617,7 +1617,7 @@ define i16 @atomicrmw_min_i16_monotonic(ptr %a, i16 %b) nounwind {
 define i32 @atomicrmw_min_i32_monotonic(ptr %a, i32 %b) nounwind {
 ; LA64-LABEL: atomicrmw_min_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammin_db.w $a2, $a1, $a0
+; LA64-NEXT:    ammin.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw min ptr %a, i32 %b monotonic
@@ -1627,7 +1627,7 @@ define i32 @atomicrmw_min_i32_monotonic(ptr %a, i32 %b) nounwind {
 define i64 @atomicrmw_min_i64_monotonic(ptr %a, i64 %b) nounwind {
 ; LA64-LABEL: atomicrmw_min_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    ammin_db.d $a2, $a1, $a0
+; LA64-NEXT:    ammin.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw min ptr %a, i64 %b monotonic
diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll
index f2f459ecaa2eca..b1af9c17b60183 100644
--- a/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll
+++ b/llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll
@@ -3982,7 +3982,7 @@ define i8 @atomicrmw_xchg_0_i8_monotonic(ptr %a) nounwind {
 ; LA64-NEXT:    ori $a2, $zero, 255
 ; LA64-NEXT:    sll.w $a2, $a2, $a1
 ; LA64-NEXT:    nor $a2, $a2, $zero
-; LA64-NEXT:    amand_db.w $a3, $a2, $a0
+; LA64-NEXT:    amand.w $a3, $a2, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a1
 ; LA64-NEXT:    ret
   %1 = atomicrmw xchg ptr %a, i8 0 monotonic
@@ -4011,7 +4011,7 @@ define i8 @atomicrmw_xchg_minus_1_i8_monotonic(ptr %a) nounwind {
 ; LA64-NEXT:    bstrins.d $a0, $zero, 1, 0
 ; LA64-NEXT:    ori $a2, $zero, 255
 ; LA64-NEXT:    sll.w $a2, $a2, $a1
-; LA64-NEXT:    amor_db.w $a3, $a2, $a0
+; LA64-NEXT:    amor.w $a3, $a2, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a1
 ; LA64-NEXT:    ret
   %1 = atomicrmw xchg ptr %a, i8 -1 monotonic
@@ -4090,7 +4090,7 @@ define i16 @atomicrmw_xchg_0_i16_monotonic(ptr %a) nounwind {
 ; LA64-NEXT:    ori $a2, $a2, 4095
 ; LA64-NEXT:    sll.w $a2, $a2, $a1
 ; LA64-NEXT:    nor $a2, $a2, $zero
-; LA64-NEXT:    amand_db.w $a3, $a2, $a0
+; LA64-NEXT:    amand.w $a3, $a2, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a1
 ; LA64-NEXT:    ret
   %1 = atomicrmw xchg ptr %a, i16 0 monotonic
@@ -4121,7 +4121,7 @@ define i16 @atomicrmw_xchg_minus_1_i16_monotonic(ptr %a) nounwind {
 ; LA64-NEXT:    lu12i.w $a2, 15
 ; LA64-NEXT:    ori $a2, $a2, 4095
 ; LA64-NEXT:    sll.w $a2, $a2, $a1
-; LA64-NEXT:    amor_db.w $a3, $a2, $a0
+; LA64-NEXT:    amor.w $a3, $a2, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a1
 ; LA64-NEXT:    ret
   %1 = atomicrmw xchg ptr %a, i16 -1 monotonic
@@ -4142,7 +4142,7 @@ define i32 @atomicrmw_xchg_i32_monotonic(ptr %a, i32 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_xchg_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amswap_db.w $a2, $a1, $a0
+; LA64-NEXT:    amswap.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw xchg ptr %a, i32 %b monotonic
@@ -4162,7 +4162,7 @@ define i64 @atomicrmw_xchg_i64_monotonic(ptr %a, i64 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_xchg_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amswap_db.d $a2, $a1, $a0
+; LA64-NEXT:    amswap.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw xchg ptr %a, i64 %b monotonic
@@ -4273,7 +4273,7 @@ define i32 @atomicrmw_add_i32_monotonic(ptr %a, i32 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_add_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amadd_db.w $a2, $a1, $a0
+; LA64-NEXT:    amadd.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw add ptr %a, i32 %b monotonic
@@ -4293,7 +4293,7 @@ define i64 @atomicrmw_add_i64_monotonic(ptr %a, i64 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_add_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amadd_db.d $a2, $a1, $a0
+; LA64-NEXT:    amadd.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw add ptr %a, i64 %b monotonic
@@ -4405,7 +4405,7 @@ define i32 @atomicrmw_sub_i32_monotonic(ptr %a, i32 %b) nounwind {
 ; LA64-LABEL: atomicrmw_sub_i32_monotonic:
 ; LA64:       # %bb.0:
 ; LA64-NEXT:    sub.w $a2, $zero, $a1
-; LA64-NEXT:    amadd_db.w $a1, $a2, $a0
+; LA64-NEXT:    amadd.w $a1, $a2, $a0
 ; LA64-NEXT:    move $a0, $a1
 ; LA64-NEXT:    ret
   %1 = atomicrmw sub ptr %a, i32 %b monotonic
@@ -4426,7 +4426,7 @@ define i64 @atomicrmw_sub_i64_monotonic(ptr %a, i64 %b) nounwind {
 ; LA64-LABEL: atomicrmw_sub_i64_monotonic:
 ; LA64:       # %bb.0:
 ; LA64-NEXT:    sub.d $a2, $zero, $a1
-; LA64-NEXT:    amadd_db.d $a1, $a2, $a0
+; LA64-NEXT:    amadd.d $a1, $a2, $a0
 ; LA64-NEXT:    move $a0, $a1
 ; LA64-NEXT:    ret
   %1 = atomicrmw sub ptr %a, i64 %b monotonic
@@ -4609,7 +4609,7 @@ define i8 @atomicrmw_and_i8_monotonic(ptr %a, i8 %b) nounwind {
 ; LA64-NEXT:    andi $a1, $a1, 255
 ; LA64-NEXT:    sll.w $a1, $a1, $a2
 ; LA64-NEXT:    orn $a1, $a1, $a3
-; LA64-NEXT:    amand_db.w $a3, $a1, $a0
+; LA64-NEXT:    amand.w $a3, $a1, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw and ptr %a, i8 %b monotonic
@@ -4646,7 +4646,7 @@ define i16 @atomicrmw_and_i16_monotonic(ptr %a, i16 %b) nounwind {
 ; LA64-NEXT:    bstrpick.d $a1, $a1, 15, 0
 ; LA64-NEXT:    sll.w $a1, $a1, $a2
 ; LA64-NEXT:    orn $a1, $a1, $a3
-; LA64-NEXT:    amand_db.w $a3, $a1, $a0
+; LA64-NEXT:    amand.w $a3, $a1, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw and ptr %a, i16 %b monotonic
@@ -4667,7 +4667,7 @@ define i32 @atomicrmw_and_i32_monotonic(ptr %a, i32 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_and_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amand_db.w $a2, $a1, $a0
+; LA64-NEXT:    amand.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw and ptr %a, i32 %b monotonic
@@ -4687,7 +4687,7 @@ define i64 @atomicrmw_and_i64_monotonic(ptr %a, i64 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_and_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amand_db.d $a2, $a1, $a0
+; LA64-NEXT:    amand.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw and ptr %a, i64 %b monotonic
@@ -4716,7 +4716,7 @@ define i8 @atomicrmw_or_i8_monotonic(ptr %a, i8 %b) nounwind {
 ; LA64-NEXT:    bstrins.d $a0, $zero, 1, 0
 ; LA64-NEXT:    andi $a1, $a1, 255
 ; LA64-NEXT:    sll.w $a1, $a1, $a2
-; LA64-NEXT:    amor_db.w $a3, $a1, $a0
+; LA64-NEXT:    amor.w $a3, $a1, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw or ptr %a, i8 %b monotonic
@@ -4745,7 +4745,7 @@ define i16 @atomicrmw_or_i16_monotonic(ptr %a, i16 %b) nounwind {
 ; LA64-NEXT:    bstrins.d $a0, $zero, 1, 0
 ; LA64-NEXT:    bstrpick.d $a1, $a1, 15, 0
 ; LA64-NEXT:    sll.w $a1, $a1, $a2
-; LA64-NEXT:    amor_db.w $a3, $a1, $a0
+; LA64-NEXT:    amor.w $a3, $a1, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw or ptr %a, i16 %b monotonic
@@ -4766,7 +4766,7 @@ define i32 @atomicrmw_or_i32_monotonic(ptr %a, i32 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_or_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amor_db.w $a2, $a1, $a0
+; LA64-NEXT:    amor.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw or ptr %a, i32 %b monotonic
@@ -4786,7 +4786,7 @@ define i64 @atomicrmw_or_i64_monotonic(ptr %a, i64 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_or_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amor_db.d $a2, $a1, $a0
+; LA64-NEXT:    amor.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw or ptr %a, i64 %b monotonic
@@ -4815,7 +4815,7 @@ define i8 @atomicrmw_xor_i8_monotonic(ptr %a, i8 %b) nounwind {
 ; LA64-NEXT:    bstrins.d $a0, $zero, 1, 0
 ; LA64-NEXT:    andi $a1, $a1, 255
 ; LA64-NEXT:    sll.w $a1, $a1, $a2
-; LA64-NEXT:    amxor_db.w $a3, $a1, $a0
+; LA64-NEXT:    amxor.w $a3, $a1, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw xor ptr %a, i8 %b monotonic
@@ -4844,7 +4844,7 @@ define i16 @atomicrmw_xor_i16_monotonic(ptr %a, i16 %b) nounwind {
 ; LA64-NEXT:    bstrins.d $a0, $zero, 1, 0
 ; LA64-NEXT:    bstrpick.d $a1, $a1, 15, 0
 ; LA64-NEXT:    sll.w $a1, $a1, $a2
-; LA64-NEXT:    amxor_db.w $a3, $a1, $a0
+; LA64-NEXT:    amxor.w $a3, $a1, $a0
 ; LA64-NEXT:    srl.w $a0, $a3, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw xor ptr %a, i16 %b monotonic
@@ -4865,7 +4865,7 @@ define i32 @atomicrmw_xor_i32_monotonic(ptr %a, i32 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_xor_i32_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amxor_db.w $a2, $a1, $a0
+; LA64-NEXT:    amxor.w $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw xor ptr %a, i32 %b monotonic
@@ -4885,7 +4885,7 @@ define i64 @atomicrmw_xor_i64_monotonic(ptr %a, i64 %b) nounwind {
 ;
 ; LA64-LABEL: atomicrmw_xor_i64_monotonic:
 ; LA64:       # %bb.0:
-; LA64-NEXT:    amxor_db.d $a2, $a1, $a0
+; LA64-NEXT:    amxor.d $a2, $a1, $a0
 ; LA64-NEXT:    move $a0, $a2
 ; LA64-NEXT:    ret
   %1 = atomicrmw xor ptr %a, i64 %b monotonic

>From 8343f081faff7dcbb4cf2b66192210f90cd9909e Mon Sep 17 00:00:00 2001
From: tangaac <tangyan01 at loongson.cn>
Date: Fri, 18 Oct 2024 14:27:55 +0800
Subject: [PATCH 2/2] refactorr the matching pattern of atomic operations

---
 .../Target/LoongArch/LoongArchInstrInfo.td    | 118 ++++++------------
 1 file changed, 40 insertions(+), 78 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index a93f552b5a8fe8..3a2b858c2a7272 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -2075,100 +2075,62 @@ multiclass ternary_atomic_op_failure_ord {
 defm atomic_cmp_swap_i32 : ternary_atomic_op_failure_ord;
 defm atomic_cmp_swap_i64 : ternary_atomic_op_failure_ord;
 
+// Atomic operation with the given atomic ordering for word and double world
+multiclass binaray_atomic_op_ord_wd<string inst, string op, 
+                                string ord, string signed = ""> {
+  def : Pat<(!cast<PatFrag>(op#"_i32_"#ord) GPR:$rj, GPR:$rk),
+            (!cast<Instruction>(inst#"_W"#signed) GPR:$rk, GPR:$rj)>;
+  def : Pat<(!cast<PatFrag>(op#"_i64_"#ord) GPR:$rj, GPR:$rk),
+            (!cast<Instruction>(inst#"_D"#signed) GPR:$rk, GPR:$rj)>;
+}
+
+// Atomic operation for word and double world
+multiclass binaray_atomic_op_wd<string inst, string op, string signed = ""> {
+  def : Pat<(!cast<PatFrag>(op#"_i32") GPR:$rj, GPR:$rk),
+            (!cast<Instruction>(inst#"_W"#signed) GPR:$rk, GPR:$rj)>;
+  def : Pat<(!cast<PatFrag>(op#"_i64") GPR:$rj, GPR:$rk),
+            (!cast<Instruction>(inst#"_D"#signed) GPR:$rk, GPR:$rj)>;
+}
+
 let Predicates = [IsLA64] in {
 
-def : Pat<(atomic_swap_i32_monotonic GPR:$addr, GPR:$incr),
-          (AMSWAP_W GPR:$incr, GPR:$addr)>;
-def : Pat<(atomic_swap_i64_monotonic GPR:$addr, GPR:$incr),
-          (AMSWAP_D GPR:$incr, GPR:$addr)>;
-def : Pat<(atomic_load_add_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMADD_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_add_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMADD_D GPR:$rk, GPR:$rj)>;
+defm : binaray_atomic_op_ord_wd<"AMSWAP", "atomic_swap", "monotonic">;
+defm : binaray_atomic_op_ord_wd<"AMADD", "atomic_load_add", "monotonic">;
+defm : binaray_atomic_op_ord_wd<"AMAND", "atomic_load_and", "monotonic">;
+defm : binaray_atomic_op_ord_wd<"AMOR", "atomic_load_or", "monotonic">;
+defm : binaray_atomic_op_ord_wd<"AMXOR", "atomic_load_xor", "monotonic">;
+defm : binaray_atomic_op_ord_wd<"AMMIN", "atomic_load_umin", "monotonic", "U">;
+defm : binaray_atomic_op_ord_wd<"AMMAX", "atomic_load_umax", "monotonic", "U">;
+defm : binaray_atomic_op_ord_wd<"AMMIN", "atomic_load_min", "monotonic">;
+defm : binaray_atomic_op_ord_wd<"AMMAX", "atomic_load_max", "monotonic">;
 def : Pat<(atomic_load_sub_i32_monotonic GPR:$rj, GPR:$rk),
           (AMADD_W (SUB_W R0, GPR:$rk), GPR:$rj)>;
 def : Pat<(atomic_load_sub_i64_monotonic GPR:$rj, GPR:$rk),
           (AMADD_D (SUB_D R0, GPR:$rk), GPR:$rj)>;
-def : Pat<(atomic_load_and_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMAND_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_and_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMAND_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_or_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMOR_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_or_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMOR_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_xor_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMXOR_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_xor_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMXOR_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umin_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMMIN_WU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umin_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMMIN_DU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umax_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMMAX_WU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umax_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMMAX_DU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_min_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMMIN_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_min_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMMIN_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_max_i32_monotonic GPR:$rj, GPR:$rk),
-          (AMMAX_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_max_i64_monotonic GPR:$rj, GPR:$rk),
-          (AMMAX_D GPR:$rk, GPR:$rj)>;
 
-def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
-                PseudoMaskedAtomicSwap32>;
-def : Pat<(atomic_swap_i32 GPR:$addr, GPR:$incr),
-          (AMSWAP__DB_W GPR:$incr, GPR:$addr)>;
-def : Pat<(atomic_swap_i64 GPR:$addr, GPR:$incr),
-          (AMSWAP__DB_D GPR:$incr, GPR:$addr)>;
-def : Pat<(atomic_load_add_i64 GPR:$rj, GPR:$rk),
-          (AMADD__DB_D GPR:$rk, GPR:$rj)>;
-def : AtomicPat<int_loongarch_masked_atomicrmw_add_i64,
-                PseudoMaskedAtomicLoadAdd32>;
+defm : binaray_atomic_op_wd<"AMSWAP__DB", "atomic_swap">;
+defm : binaray_atomic_op_wd<"AMADD__DB", "atomic_load_add">;
+defm : binaray_atomic_op_wd<"AMAND__DB", "atomic_load_and">;
+defm : binaray_atomic_op_wd<"AMOR__DB", "atomic_load_or">;
+defm : binaray_atomic_op_wd<"AMXOR__DB", "atomic_load_xor">;
+defm : binaray_atomic_op_wd<"AMMIN__DB", "atomic_load_umin", "U">;
+defm : binaray_atomic_op_wd<"AMMAX__DB", "atomic_load_umax", "U">;
+defm : binaray_atomic_op_wd<"AMMIN__DB", "atomic_load_min">;
+defm : binaray_atomic_op_wd<"AMMAX__DB", "atomic_load_max">;
 def : Pat<(atomic_load_sub_i32 GPR:$rj, GPR:$rk),
           (AMADD__DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>;
 def : Pat<(atomic_load_sub_i64 GPR:$rj, GPR:$rk),
           (AMADD__DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>;
+
+def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
+                PseudoMaskedAtomicSwap32>;
+def : AtomicPat<int_loongarch_masked_atomicrmw_add_i64,
+                PseudoMaskedAtomicLoadAdd32>;
 def : AtomicPat<int_loongarch_masked_atomicrmw_sub_i64,
                 PseudoMaskedAtomicLoadSub32>;
 defm : PseudoBinPat<"atomic_load_nand_i64", PseudoAtomicLoadNand64>;
 def : AtomicPat<int_loongarch_masked_atomicrmw_nand_i64,
                 PseudoMaskedAtomicLoadNand32>;
-def : Pat<(atomic_load_add_i32 GPR:$rj, GPR:$rk),
-          (AMADD__DB_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_and_i32 GPR:$rj, GPR:$rk),
-          (AMAND__DB_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_and_i64 GPR:$rj, GPR:$rk),
-          (AMAND__DB_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_or_i32 GPR:$rj, GPR:$rk),
-          (AMOR__DB_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_or_i64 GPR:$rj, GPR:$rk),
-          (AMOR__DB_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_xor_i32 GPR:$rj, GPR:$rk),
-          (AMXOR__DB_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_xor_i64 GPR:$rj, GPR:$rk),
-          (AMXOR__DB_D GPR:$rk, GPR:$rj)>;
-
-def : Pat<(atomic_load_umin_i32 GPR:$rj, GPR:$rk),
-          (AMMIN__DB_WU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umin_i64 GPR:$rj, GPR:$rk),
-          (AMMIN__DB_DU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umax_i32 GPR:$rj, GPR:$rk),
-          (AMMAX__DB_WU GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_umax_i64 GPR:$rj, GPR:$rk),
-          (AMMAX__DB_DU GPR:$rk, GPR:$rj)>;
-
-def : Pat<(atomic_load_min_i32 GPR:$rj, GPR:$rk),
-          (AMMIN__DB_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_min_i64 GPR:$rj, GPR:$rk),
-          (AMMIN__DB_D GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_max_i32 GPR:$rj, GPR:$rk),
-          (AMMAX__DB_W GPR:$rk, GPR:$rj)>;
-def : Pat<(atomic_load_max_i64 GPR:$rj, GPR:$rk),
-          (AMMAX__DB_D GPR:$rk, GPR:$rj)>;
 
 def : AtomicPat<int_loongarch_masked_atomicrmw_umax_i64,
                 PseudoMaskedAtomicLoadUMax32>;



More information about the llvm-commits mailing list