Skip to content
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

[RISCV] Use any_extend for type legalizing atomic_compare_swap with Zacas. #77669

Merged
merged 1 commit into from
Jan 10, 2024

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Jan 10, 2024

With Zacas we will use amocas.w which doesn't require the input to be sign extended.

Stacked on #77666 please review only the second commit which removes some sext.w instructions.

@llvmbot
Copy link
Collaborator

llvmbot commented Jan 10, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

With Zacas we will use amocas.w which doesn't require the input to be sign extended.

Stacked on #77666 please review only the second commit


Patch is 122.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/77669.diff

7 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+1)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+5)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+1-3)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoA.td (+8-6)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZa.td (+51)
  • (modified) llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll (+217-57)
  • (modified) llvm/test/CodeGen/RISCV/atomic-cmpxchg.ll (+1681-124)
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index bb7a3291085d43..279509575bb52a 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -736,6 +736,7 @@ def FeatureStdExtZacas
 def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">,
                                AssemblerPredicate<(all_of FeatureStdExtZacas),
                                "'Zacas' (Atomic Compare-And-Swap Instructions)">;
+def NoStdExtZacas : Predicate<"!Subtarget->hasStdExtZacas()">;
 
 //===----------------------------------------------------------------------===//
 // Vendor extensions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 90d648dab2ae81..cb9ffabc41236e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -19364,6 +19364,11 @@ bool RISCVTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
   return false;
 }
 
+ISD::NodeType RISCVTargetLowering::getExtendForAtomicCmpSwapArg() const {
+  // Zacas will use amocas.w which does not require extension.
+  return Subtarget.hasStdExtZacas() ? ISD::ANY_EXTEND : ISD::SIGN_EXTEND;
+}
+
 Register RISCVTargetLowering::getExceptionPointerRegister(
     const Constant *PersonalityFn) const {
   return RISCV::X10;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 0d14e5b757bdd1..c65953e37b1710 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -633,9 +633,7 @@ class RISCVTargetLowering : public TargetLowering {
     return ISD::SIGN_EXTEND;
   }
 
-  ISD::NodeType getExtendForAtomicCmpSwapArg() const override {
-    return ISD::SIGN_EXTEND;
-  }
+  ISD::NodeType getExtendForAtomicCmpSwapArg() const override;
 
   bool shouldTransformSignedTruncationCheck(EVT XVT,
                                             unsigned KeptBits) const override;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
index 1ff5189260a9c7..44552c00c62e55 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
@@ -333,11 +333,17 @@ multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,
             (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
 }
 
-let Predicates = [HasStdExtA] in {
-
+let Predicates = [HasStdExtA, NoStdExtZacas] in {
 def PseudoCmpXchg32 : PseudoCmpXchg;
 defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>;
+}
+
+let Predicates = [HasStdExtA, NoStdExtZacas, IsRV64] in {
+def PseudoCmpXchg64 : PseudoCmpXchg;
+defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>;
+}
 
+let Predicates = [HasStdExtA] in {
 def PseudoMaskedCmpXchg32
     : Pseudo<(outs GPR:$res, GPR:$scratch),
              (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
@@ -356,10 +362,6 @@ def : Pat<(int_riscv_masked_cmpxchg_i32
 } // Predicates = [HasStdExtA]
 
 let Predicates = [HasStdExtA, IsRV64] in {
-
-def PseudoCmpXchg64 : PseudoCmpXchg;
-defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>;
-
 def : Pat<(int_riscv_masked_cmpxchg_i64
             GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering),
           (PseudoMaskedCmpXchg32
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
index ea8046d119d042..ffcdd001074938 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
@@ -67,6 +67,57 @@ defm AMOCAS_D_RV64 : AMO_cas_aq_rl<0b00101, 0b011, "amocas.d", GPR>;
 defm AMOCAS_Q : AMO_cas_aq_rl<0b00101, 0b100, "amocas.q", GPRPairRV64>;
 } // Predicates = [HasStdExtZacas, IsRV64]
 
+multiclass AMOCASPat<string AtomicOp, string BaseInst, ValueType vt = XLenVT,
+                     list<Predicate> ExtraPreds = []> {
+  let Predicates = !listconcat([HasStdExtZacas, NotHasStdExtZtso], ExtraPreds) in {
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_monotonic") (vt GPR:$addr),
+                                                     (vt GPR:$cmp),
+                                                     (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_acquire") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst#"_AQ") GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_release") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst#"_RL") GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_acq_rel") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst#"_AQ_RL") GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_seq_cst") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst#"_AQ_RL") GPR:$cmp, GPR:$addr, GPR:$new)>;
+  } // Predicates = !listconcat([HasStdExtZacas, NotHasStdExtZtso], ExtraPreds)
+  let Predicates = !listconcat([HasStdExtZacas, HasStdExtZtso], ExtraPreds) in {
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_monotonic") (vt GPR:$addr),
+                                                     (vt GPR:$cmp),
+                                                     (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_acquire") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_release") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_acq_rel") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
+    def : Pat<(!cast<PatFrag>(AtomicOp#"_seq_cst") (vt GPR:$addr),
+                                                   (vt GPR:$cmp),
+                                                   (vt GPR:$new)),
+              (!cast<RVInst>(BaseInst) GPR:$cmp, GPR:$addr, GPR:$new)>;
+  } // Predicates = !listconcat([HasStdExtZacas, HasStdExtZtso], ExtraPreds)
+}
+
+defm : AMOCASPat<"atomic_cmp_swap_32", "AMOCAS_W">;
+defm : AMOCASPat<"atomic_cmp_swap_64", "AMOCAS_D_RV64", i64, [IsRV64]>;
+
 //===----------------------------------------------------------------------===//
 // Zawrs (Wait-on-Reservation-Set)
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll b/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll
index 651f58d324422f..a8477cc550fe6a 100644
--- a/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll
+++ b/llvm/test/CodeGen/RISCV/atomic-cmpxchg-branch-on-result.ll
@@ -1,30 +1,44 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=riscv32 -mattr=+a -verify-machineinstrs < %s \
-; RUN:   | FileCheck -check-prefixes=CHECK,RV32IA %s
+; RUN:   | FileCheck -check-prefixes=NOZACAS,RV32IA %s
+; RUN: llc -mtriple=riscv32 -mattr=+a,+experimental-zacas -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefixes=ZACAS,RV32IA-ZACAS %s
 ; RUN: llc -mtriple=riscv64 -mattr=+a -verify-machineinstrs < %s \
-; RUN:   | FileCheck -check-prefixes=CHECK,RV64IA %s
+; RUN:   | FileCheck -check-prefixes=NOZACAS,RV64IA %s
+; RUN: llc -mtriple=riscv64 -mattr=+a,+experimental-zacas -verify-machineinstrs < %s \
+; RUN:   | FileCheck -check-prefixes=ZACAS,RV64IA-ZACAS %s
 
 ; Test cmpxchg followed by a branch on the cmpxchg success value to see if the
 ; branch is folded into the cmpxchg expansion.
 
 define void @cmpxchg_and_branch1(ptr %ptr, i32 signext %cmp, i32 signext %val) nounwind {
-; CHECK-LABEL: cmpxchg_and_branch1:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:  .LBB0_1: # %do_cmpxchg
-; CHECK-NEXT:    # =>This Loop Header: Depth=1
-; CHECK-NEXT:    # Child Loop BB0_3 Depth 2
-; CHECK-NEXT:  .LBB0_3: # %do_cmpxchg
-; CHECK-NEXT:    # Parent Loop BB0_1 Depth=1
-; CHECK-NEXT:    # => This Inner Loop Header: Depth=2
-; CHECK-NEXT:    lr.w.aqrl a3, (a0)
-; CHECK-NEXT:    bne a3, a1, .LBB0_1
-; CHECK-NEXT:  # %bb.4: # %do_cmpxchg
-; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=2
-; CHECK-NEXT:    sc.w.rl a4, a2, (a0)
-; CHECK-NEXT:    bnez a4, .LBB0_3
-; CHECK-NEXT:  # %bb.5: # %do_cmpxchg
-; CHECK-NEXT:  # %bb.2: # %exit
-; CHECK-NEXT:    ret
+; NOZACAS-LABEL: cmpxchg_and_branch1:
+; NOZACAS:       # %bb.0: # %entry
+; NOZACAS-NEXT:  .LBB0_1: # %do_cmpxchg
+; NOZACAS-NEXT:    # =>This Loop Header: Depth=1
+; NOZACAS-NEXT:    # Child Loop BB0_3 Depth 2
+; NOZACAS-NEXT:  .LBB0_3: # %do_cmpxchg
+; NOZACAS-NEXT:    # Parent Loop BB0_1 Depth=1
+; NOZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; NOZACAS-NEXT:    lr.w.aqrl a3, (a0)
+; NOZACAS-NEXT:    bne a3, a1, .LBB0_1
+; NOZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; NOZACAS-NEXT:    # in Loop: Header=BB0_3 Depth=2
+; NOZACAS-NEXT:    sc.w.rl a4, a2, (a0)
+; NOZACAS-NEXT:    bnez a4, .LBB0_3
+; NOZACAS-NEXT:  # %bb.5: # %do_cmpxchg
+; NOZACAS-NEXT:  # %bb.2: # %exit
+; NOZACAS-NEXT:    ret
+;
+; ZACAS-LABEL: cmpxchg_and_branch1:
+; ZACAS:       # %bb.0: # %entry
+; ZACAS-NEXT:  .LBB0_1: # %do_cmpxchg
+; ZACAS-NEXT:    # =>This Inner Loop Header: Depth=1
+; ZACAS-NEXT:    mv a3, a1
+; ZACAS-NEXT:    amocas.w.aqrl a3, a2, (a0)
+; ZACAS-NEXT:    bne a3, a1, .LBB0_1
+; ZACAS-NEXT:  # %bb.2: # %exit
+; ZACAS-NEXT:    ret
 entry:
   br label %do_cmpxchg
 do_cmpxchg:
@@ -36,25 +50,35 @@ exit:
 }
 
 define void @cmpxchg_and_branch2(ptr %ptr, i32 signext %cmp, i32 signext %val) nounwind {
-; CHECK-LABEL: cmpxchg_and_branch2:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:  .LBB1_1: # %do_cmpxchg
-; CHECK-NEXT:    # =>This Loop Header: Depth=1
-; CHECK-NEXT:    # Child Loop BB1_3 Depth 2
-; CHECK-NEXT:  .LBB1_3: # %do_cmpxchg
-; CHECK-NEXT:    # Parent Loop BB1_1 Depth=1
-; CHECK-NEXT:    # => This Inner Loop Header: Depth=2
-; CHECK-NEXT:    lr.w.aqrl a3, (a0)
-; CHECK-NEXT:    bne a3, a1, .LBB1_5
-; CHECK-NEXT:  # %bb.4: # %do_cmpxchg
-; CHECK-NEXT:    # in Loop: Header=BB1_3 Depth=2
-; CHECK-NEXT:    sc.w.rl a4, a2, (a0)
-; CHECK-NEXT:    bnez a4, .LBB1_3
-; CHECK-NEXT:  .LBB1_5: # %do_cmpxchg
-; CHECK-NEXT:    # in Loop: Header=BB1_1 Depth=1
-; CHECK-NEXT:    beq a3, a1, .LBB1_1
-; CHECK-NEXT:  # %bb.2: # %exit
-; CHECK-NEXT:    ret
+; NOZACAS-LABEL: cmpxchg_and_branch2:
+; NOZACAS:       # %bb.0: # %entry
+; NOZACAS-NEXT:  .LBB1_1: # %do_cmpxchg
+; NOZACAS-NEXT:    # =>This Loop Header: Depth=1
+; NOZACAS-NEXT:    # Child Loop BB1_3 Depth 2
+; NOZACAS-NEXT:  .LBB1_3: # %do_cmpxchg
+; NOZACAS-NEXT:    # Parent Loop BB1_1 Depth=1
+; NOZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; NOZACAS-NEXT:    lr.w.aqrl a3, (a0)
+; NOZACAS-NEXT:    bne a3, a1, .LBB1_5
+; NOZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; NOZACAS-NEXT:    # in Loop: Header=BB1_3 Depth=2
+; NOZACAS-NEXT:    sc.w.rl a4, a2, (a0)
+; NOZACAS-NEXT:    bnez a4, .LBB1_3
+; NOZACAS-NEXT:  .LBB1_5: # %do_cmpxchg
+; NOZACAS-NEXT:    # in Loop: Header=BB1_1 Depth=1
+; NOZACAS-NEXT:    beq a3, a1, .LBB1_1
+; NOZACAS-NEXT:  # %bb.2: # %exit
+; NOZACAS-NEXT:    ret
+;
+; ZACAS-LABEL: cmpxchg_and_branch2:
+; ZACAS:       # %bb.0: # %entry
+; ZACAS-NEXT:  .LBB1_1: # %do_cmpxchg
+; ZACAS-NEXT:    # =>This Inner Loop Header: Depth=1
+; ZACAS-NEXT:    mv a3, a1
+; ZACAS-NEXT:    amocas.w.aqrl a3, a2, (a0)
+; ZACAS-NEXT:    beq a3, a1, .LBB1_1
+; ZACAS-NEXT:  # %bb.2: # %exit
+; ZACAS-NEXT:    ret
 entry:
   br label %do_cmpxchg
 do_cmpxchg:
@@ -96,6 +120,36 @@ define void @cmpxchg_masked_and_branch1(ptr %ptr, i8 signext %cmp, i8 signext %v
 ; RV32IA-NEXT:  # %bb.2: # %exit
 ; RV32IA-NEXT:    ret
 ;
+; RV32IA-ZACAS-LABEL: cmpxchg_masked_and_branch1:
+; RV32IA-ZACAS:       # %bb.0: # %entry
+; RV32IA-ZACAS-NEXT:    andi a3, a0, -4
+; RV32IA-ZACAS-NEXT:    slli a4, a0, 3
+; RV32IA-ZACAS-NEXT:    li a0, 255
+; RV32IA-ZACAS-NEXT:    sll a0, a0, a4
+; RV32IA-ZACAS-NEXT:    andi a1, a1, 255
+; RV32IA-ZACAS-NEXT:    sll a1, a1, a4
+; RV32IA-ZACAS-NEXT:    andi a2, a2, 255
+; RV32IA-ZACAS-NEXT:    sll a2, a2, a4
+; RV32IA-ZACAS-NEXT:  .LBB2_1: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # =>This Loop Header: Depth=1
+; RV32IA-ZACAS-NEXT:    # Child Loop BB2_3 Depth 2
+; RV32IA-ZACAS-NEXT:  .LBB2_3: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # Parent Loop BB2_1 Depth=1
+; RV32IA-ZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; RV32IA-ZACAS-NEXT:    lr.w.aqrl a4, (a3)
+; RV32IA-ZACAS-NEXT:    and a5, a4, a0
+; RV32IA-ZACAS-NEXT:    bne a5, a1, .LBB2_1
+; RV32IA-ZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # in Loop: Header=BB2_3 Depth=2
+; RV32IA-ZACAS-NEXT:    xor a5, a4, a2
+; RV32IA-ZACAS-NEXT:    and a5, a5, a0
+; RV32IA-ZACAS-NEXT:    xor a5, a4, a5
+; RV32IA-ZACAS-NEXT:    sc.w.rl a5, a5, (a3)
+; RV32IA-ZACAS-NEXT:    bnez a5, .LBB2_3
+; RV32IA-ZACAS-NEXT:  # %bb.5: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:  # %bb.2: # %exit
+; RV32IA-ZACAS-NEXT:    ret
+;
 ; RV64IA-LABEL: cmpxchg_masked_and_branch1:
 ; RV64IA:       # %bb.0: # %entry
 ; RV64IA-NEXT:    andi a3, a0, -4
@@ -125,6 +179,36 @@ define void @cmpxchg_masked_and_branch1(ptr %ptr, i8 signext %cmp, i8 signext %v
 ; RV64IA-NEXT:  # %bb.5: # %do_cmpxchg
 ; RV64IA-NEXT:  # %bb.2: # %exit
 ; RV64IA-NEXT:    ret
+;
+; RV64IA-ZACAS-LABEL: cmpxchg_masked_and_branch1:
+; RV64IA-ZACAS:       # %bb.0: # %entry
+; RV64IA-ZACAS-NEXT:    andi a3, a0, -4
+; RV64IA-ZACAS-NEXT:    slli a4, a0, 3
+; RV64IA-ZACAS-NEXT:    li a0, 255
+; RV64IA-ZACAS-NEXT:    sllw a0, a0, a4
+; RV64IA-ZACAS-NEXT:    andi a1, a1, 255
+; RV64IA-ZACAS-NEXT:    sllw a1, a1, a4
+; RV64IA-ZACAS-NEXT:    andi a2, a2, 255
+; RV64IA-ZACAS-NEXT:    sllw a2, a2, a4
+; RV64IA-ZACAS-NEXT:  .LBB2_1: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # =>This Loop Header: Depth=1
+; RV64IA-ZACAS-NEXT:    # Child Loop BB2_3 Depth 2
+; RV64IA-ZACAS-NEXT:  .LBB2_3: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # Parent Loop BB2_1 Depth=1
+; RV64IA-ZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; RV64IA-ZACAS-NEXT:    lr.w.aqrl a4, (a3)
+; RV64IA-ZACAS-NEXT:    and a5, a4, a0
+; RV64IA-ZACAS-NEXT:    bne a5, a1, .LBB2_1
+; RV64IA-ZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # in Loop: Header=BB2_3 Depth=2
+; RV64IA-ZACAS-NEXT:    xor a5, a4, a2
+; RV64IA-ZACAS-NEXT:    and a5, a5, a0
+; RV64IA-ZACAS-NEXT:    xor a5, a4, a5
+; RV64IA-ZACAS-NEXT:    sc.w.rl a5, a5, (a3)
+; RV64IA-ZACAS-NEXT:    bnez a5, .LBB2_3
+; RV64IA-ZACAS-NEXT:  # %bb.5: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:  # %bb.2: # %exit
+; RV64IA-ZACAS-NEXT:    ret
 entry:
   br label %do_cmpxchg
 do_cmpxchg:
@@ -169,6 +253,39 @@ define void @cmpxchg_masked_and_branch2(ptr %ptr, i8 signext %cmp, i8 signext %v
 ; RV32IA-NEXT:  # %bb.2: # %exit
 ; RV32IA-NEXT:    ret
 ;
+; RV32IA-ZACAS-LABEL: cmpxchg_masked_and_branch2:
+; RV32IA-ZACAS:       # %bb.0: # %entry
+; RV32IA-ZACAS-NEXT:    andi a3, a0, -4
+; RV32IA-ZACAS-NEXT:    slli a4, a0, 3
+; RV32IA-ZACAS-NEXT:    li a0, 255
+; RV32IA-ZACAS-NEXT:    sll a0, a0, a4
+; RV32IA-ZACAS-NEXT:    andi a1, a1, 255
+; RV32IA-ZACAS-NEXT:    sll a1, a1, a4
+; RV32IA-ZACAS-NEXT:    andi a2, a2, 255
+; RV32IA-ZACAS-NEXT:    sll a2, a2, a4
+; RV32IA-ZACAS-NEXT:  .LBB3_1: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # =>This Loop Header: Depth=1
+; RV32IA-ZACAS-NEXT:    # Child Loop BB3_3 Depth 2
+; RV32IA-ZACAS-NEXT:  .LBB3_3: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # Parent Loop BB3_1 Depth=1
+; RV32IA-ZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; RV32IA-ZACAS-NEXT:    lr.w.aqrl a4, (a3)
+; RV32IA-ZACAS-NEXT:    and a5, a4, a0
+; RV32IA-ZACAS-NEXT:    bne a5, a1, .LBB3_5
+; RV32IA-ZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # in Loop: Header=BB3_3 Depth=2
+; RV32IA-ZACAS-NEXT:    xor a5, a4, a2
+; RV32IA-ZACAS-NEXT:    and a5, a5, a0
+; RV32IA-ZACAS-NEXT:    xor a5, a4, a5
+; RV32IA-ZACAS-NEXT:    sc.w.rl a5, a5, (a3)
+; RV32IA-ZACAS-NEXT:    bnez a5, .LBB3_3
+; RV32IA-ZACAS-NEXT:  .LBB3_5: # %do_cmpxchg
+; RV32IA-ZACAS-NEXT:    # in Loop: Header=BB3_1 Depth=1
+; RV32IA-ZACAS-NEXT:    and a4, a4, a0
+; RV32IA-ZACAS-NEXT:    beq a1, a4, .LBB3_1
+; RV32IA-ZACAS-NEXT:  # %bb.2: # %exit
+; RV32IA-ZACAS-NEXT:    ret
+;
 ; RV64IA-LABEL: cmpxchg_masked_and_branch2:
 ; RV64IA:       # %bb.0: # %entry
 ; RV64IA-NEXT:    andi a3, a0, -4
@@ -201,6 +318,39 @@ define void @cmpxchg_masked_and_branch2(ptr %ptr, i8 signext %cmp, i8 signext %v
 ; RV64IA-NEXT:    beq a1, a4, .LBB3_1
 ; RV64IA-NEXT:  # %bb.2: # %exit
 ; RV64IA-NEXT:    ret
+;
+; RV64IA-ZACAS-LABEL: cmpxchg_masked_and_branch2:
+; RV64IA-ZACAS:       # %bb.0: # %entry
+; RV64IA-ZACAS-NEXT:    andi a3, a0, -4
+; RV64IA-ZACAS-NEXT:    slli a4, a0, 3
+; RV64IA-ZACAS-NEXT:    li a0, 255
+; RV64IA-ZACAS-NEXT:    sllw a0, a0, a4
+; RV64IA-ZACAS-NEXT:    andi a1, a1, 255
+; RV64IA-ZACAS-NEXT:    sllw a1, a1, a4
+; RV64IA-ZACAS-NEXT:    andi a2, a2, 255
+; RV64IA-ZACAS-NEXT:    sllw a2, a2, a4
+; RV64IA-ZACAS-NEXT:  .LBB3_1: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # =>This Loop Header: Depth=1
+; RV64IA-ZACAS-NEXT:    # Child Loop BB3_3 Depth 2
+; RV64IA-ZACAS-NEXT:  .LBB3_3: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # Parent Loop BB3_1 Depth=1
+; RV64IA-ZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; RV64IA-ZACAS-NEXT:    lr.w.aqrl a4, (a3)
+; RV64IA-ZACAS-NEXT:    and a5, a4, a0
+; RV64IA-ZACAS-NEXT:    bne a5, a1, .LBB3_5
+; RV64IA-ZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # in Loop: Header=BB3_3 Depth=2
+; RV64IA-ZACAS-NEXT:    xor a5, a4, a2
+; RV64IA-ZACAS-NEXT:    and a5, a5, a0
+; RV64IA-ZACAS-NEXT:    xor a5, a4, a5
+; RV64IA-ZACAS-NEXT:    sc.w.rl a5, a5, (a3)
+; RV64IA-ZACAS-NEXT:    bnez a5, .LBB3_3
+; RV64IA-ZACAS-NEXT:  .LBB3_5: # %do_cmpxchg
+; RV64IA-ZACAS-NEXT:    # in Loop: Header=BB3_1 Depth=1
+; RV64IA-ZACAS-NEXT:    and a4, a4, a0
+; RV64IA-ZACAS-NEXT:    beq a1, a4, .LBB3_1
+; RV64IA-ZACAS-NEXT:  # %bb.2: # %exit
+; RV64IA-ZACAS-NEXT:    ret
 entry:
   br label %do_cmpxchg
 do_cmpxchg:
@@ -212,25 +362,35 @@ exit:
 }
 
 define void @cmpxchg_and_irrelevant_branch(ptr %ptr, i32 signext %cmp, i32 signext %val, i1 zeroext %bool) nounwind {
-; CHECK-LABEL: cmpxchg_and_irrelevant_branch:
-; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:  .LBB4_1: # %do_cmpxchg
-; CHECK-NEXT:    # =>This Loop Header: Depth=1
-; CHECK-NEXT:    # Child Loop BB4_3 Depth 2
-; CHECK-NEXT:  .LBB4_3: # %do_cmpxchg
-; CHECK-NEXT:    # Parent Loop BB4_1 Depth=1
-; CHECK-NEXT:    # => This Inner Loop Header: Depth=2
-; CHECK-NEXT:    lr.w.aqrl a4, (a0)
-; CHECK-NEXT:    bne a4, a1, .LBB4_5
-; CHECK-NEXT:  # %bb.4: # %do_cmpxchg
-; CHECK-NEXT:    # in Loop: Header=BB4_3 Depth=2
-; CHECK-NEXT:    sc.w.rl a5, a2, (a0)
-; CHECK-NEXT:    bnez a5, .LBB4_3
-; CHECK-NEXT:  .LBB4_5: # %do_cmpxchg
-; CHECK-NEXT:    # in Loop: Header=BB4_1 Depth=1
-; CHECK-NEXT:    beqz a3, .LBB4_1
-; CHECK-NEXT:  # %bb.2: # %exit
-; CHECK-NEXT:    ret
+; NOZACAS-LABEL: cmpxchg_and_irrelevant_branch:
+; NOZACAS:       # %bb.0: # %entry
+; NOZACAS-NEXT:  .LBB4_1: # %do_cmpxchg
+; NOZACAS-NEXT:    # =>This Loop Header: Depth=1
+; NOZACAS-NEXT:    # Child Loop BB4_3 Depth 2
+; NOZACAS-NEXT:  .LBB4_3: # %do_cmpxchg
+; NOZACAS-NEXT:    # Parent Loop BB4_1 Depth=1
+; NOZACAS-NEXT:    # => This Inner Loop Header: Depth=2
+; NOZACAS-NEXT:    lr.w.aqrl a4, (a0)
+; NOZACAS-NEXT:    bne a4, a1, .LBB4_5
+; NOZACAS-NEXT:  # %bb.4: # %do_cmpxchg
+; NOZACAS-NEXT:    # in Loop: Header=BB4_3 Depth=2
+; NOZACAS-NEXT:    sc.w.rl a5, a2...
[truncated]

@topperc topperc requested a review from preames January 10, 2024 19:10
Copy link
Member

@dtcxzyw dtcxzyw 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
Collaborator

@preames preames left a comment

Choose a reason for hiding this comment

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

LGTM

…acas.

With Zacas we will use amocas.w which doesn't require the input
to be sign extended.
@topperc topperc merged commit 3378514 into llvm:main Jan 10, 2024
3 of 4 checks passed
@topperc topperc deleted the pr/zacas-sext branch January 10, 2024 20:41
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…acas. (llvm#77669)

With Zacas we will use amocas.w which doesn't require the input to be
sign extended.
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.

None yet

4 participants