Skip to content

[LoongArch] Minor refinement to monotonic atomic semantics. #112681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 21, 2024

Conversation

tangaac
Copy link
Contributor

@tangaac tangaac commented Oct 17, 2024

Don't use "_db" version AM instructions for LoongArch atomic memory operations with monotonic semantics.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2024

@llvm/pr-subscribers-backend-loongarch

Author: None (tangaac)

Changes

Support LoongArch atomic memory operations with monotonic semantics.


Full diff: https://github.com/llvm/llvm-project/pull/112681.diff

3 Files Affected:

  • (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (+42)
  • (modified) llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw-minmax.ll (+8-8)
  • (modified) llvm/test/CodeGen/LoongArch/ir-instruction/atomicrmw.ll (+22-22)
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

@tangaac
Copy link
Contributor Author

tangaac commented Oct 17, 2024

Need some suggestions to simplify this td file.

@tangaac tangaac changed the title [LoongArch] fix: Support LoongArch atomic memory operations with monotonic semantics [LoongArch] fix: Support LoongArch atomic memory operations with monotonic semantic Oct 17, 2024
@tangaac tangaac changed the title [LoongArch] fix: Support LoongArch atomic memory operations with monotonic semantic [LoongArch] fix: Support LoongArch atomic memory operations with monotonic semantics Oct 17, 2024
@heiher
Copy link
Member

heiher commented Oct 17, 2024

Need some suggestions to simplify this td file.

defm : LDOPregister_patterns<"LDADD", "atomic_load_add">;
defm : LDOPregister_patterns<"LDSET", "atomic_load_or">;
defm : LDOPregister_patterns<"LDEOR", "atomic_load_xor">;
defm : LDOPregister_patterns<"LDCLR", "atomic_load_clr">;
defm : LDOPregister_patterns<"LDSMAX", "atomic_load_max">;
defm : LDOPregister_patterns<"LDSMIN", "atomic_load_min">;
defm : LDOPregister_patterns<"LDUMAX", "atomic_load_umax">;
defm : LDOPregister_patterns<"LDUMIN", "atomic_load_umin">;
defm : LDOPregister_patterns<"SWP", "atomic_swap">;

// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
// complex DAG for DstRHS.
let Predicates = [HasLSE] in
multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
ValueType vt, dag SrcRHS, dag DstRHS> {
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, SrcRHS),
(!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
}
multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
ValueType vt, dag RHS> {
defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS, RHS>;
}
multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
ValueType vt, dag LHS, dag RHS> {
defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, LHS, RHS>;
}
multiclass LDOPregister_patterns<string inst, string op> {
defm : LDOPregister_patterns_ord<inst, "X", op, i64, (i64 GPR64:$Rm)>;
defm : LDOPregister_patterns_ord<inst, "W", op, i32, (i32 GPR32:$Rm)>;
defm : LDOPregister_patterns_ord<inst, "H", op, i16, (i32 GPR32:$Rm)>;
defm : LDOPregister_patterns_ord<inst, "B", op, i8, (i32 GPR32:$Rm)>;
}

Copy link
Contributor

@SixWeining SixWeining left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@heiher heiher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@SixWeining
Copy link
Contributor

About the title and commit message: I think this is not a "fix" but a fine-grained optimization or tuning.

@SixWeining
Copy link
Contributor

SixWeining commented Oct 21, 2024

About atomic_load_sub, seems we have something to optimize:

testcase:

#include <stdatomic.h>

int *fp2a(int **p) {
  return __atomic_fetch_sub(p, 1, memory_order_relaxed);
}

gcc:

        addi.w  $r13,$r0,-1                     # 0xffffffffffffffff
        or      $r12,$r4,$r0
        amadd.d $r4,$r13,$r12,0

clang:

        ori     $a1, $zero, 1
        sub.d   $a2, $zero, $a1
        amadd.d      $a1, $a2, $a0
        move    $a0, $a1

But this can be done in a separate PR.

@tangaac tangaac changed the title [LoongArch] fix: Support LoongArch atomic memory operations with monotonic semantics [LoongArch] Support LoongArch atomic memory operations with monotonic semantics Oct 21, 2024
@tangaac tangaac changed the title [LoongArch] Support LoongArch atomic memory operations with monotonic semantics [LoongArch] Minor refinement to monotonic atomic semantics. Oct 21, 2024
@SixWeining SixWeining merged commit ba5676c into llvm:main Oct 21, 2024
8 checks passed
Copy link

@tangaac Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

@tangaac tangaac deleted the fix/atomic-insts branch November 19, 2024 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants