[llvm] [PowerPC] Rework AMO load with Compare and Swap Not Equal to use post-RA pseudo expansion (PR #190698)

Maryam Moghadas via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 09:42:55 PDT 2026


https://github.com/maryammo updated https://github.com/llvm/llvm-project/pull/190698

>From 7969f12895b2159021518c81e278164354a51639 Mon Sep 17 00:00:00 2001
From: Maryam Moghadas <maryammo at ca.ibm.com>
Date: Mon, 6 Apr 2026 20:54:26 +0000
Subject: [PATCH 1/3] [PowerPC] Rework AMO load with Compare and Swap Not Equal
 to use post-RA pseudo expansion

Replace the dummy call lowering with a PPCPostRAExpPseudo that hardcodes
X3/X4/X5 post-RA to satisfy the 3 consecutive register constraint for
lwat/ldat FC=16, addressing reviewer feedback.
---
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp   |  21 ----
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp |  45 +--------
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |   1 -
 llvm/lib/Target/PowerPC/PPCInstr64Bit.td    |  13 +++
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp    |  60 +++++++++++
 llvm/lib/Target/PowerPC/PPCInstrInfo.h      |   1 +
 llvm/lib/Target/PowerPC/PPCInstrInfo.td     |  13 +++
 llvm/test/CodeGen/PowerPC/amo-enable.ll     | 104 ++++++++++----------
 8 files changed, 138 insertions(+), 120 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 6d1ee6bb111fe..7294a2dc48cdb 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -1703,27 +1703,6 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
     EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
     return;
   }
-  case PPC::BL8:
-  case PPC::BL8_NOP: {
-    const MachineOperand &MO = MI->getOperand(0);
-    if (MO.isSymbol()) {
-      StringRef Name = MO.getSymbolName();
-      Name.consume_front(".");
-      Name.consume_back("[PR]");
-      bool IsLWAT = Name == "__lwat_csne_pseudo";
-      bool IsLDAT = Name == "__ldat_csne_pseudo";
-      if (IsLWAT || IsLDAT) {
-        EmitToStreamer(*OutStreamer,
-                       MCInstBuilder(IsLWAT ? PPC::LWAT : PPC::LDAT)
-                           .addReg(PPC::X3)
-                           .addReg(PPC::X3)
-                           .addReg(PPC::X6)
-                           .addImm(16));
-        return;
-      }
-    }
-    break;
-  }
   }
 
   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 753306a8d365b..fc66d6a49f05b 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11528,49 +11528,6 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
   return Flags;
 }
 
-SDValue PPCTargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
-                                                  SelectionDAG &DAG) const {
-  unsigned IntrinsicID = Op.getConstantOperandVal(1);
-  SDLoc dl(Op);
-  switch (IntrinsicID) {
-  case Intrinsic::ppc_amo_lwat_csne:
-  case Intrinsic::ppc_amo_ldat_csne:
-    SDValue Chain = Op.getOperand(0);
-    SDValue Ptr = Op.getOperand(2);
-    SDValue CmpVal = Op.getOperand(3);
-    SDValue NewVal = Op.getOperand(4);
-
-    EVT VT = IntrinsicID == Intrinsic::ppc_amo_ldat_csne ? MVT::i64 : MVT::i32;
-    Type *Ty = VT.getTypeForEVT(*DAG.getContext());
-    Type *IntPtrTy = DAG.getDataLayout().getIntPtrType(*DAG.getContext());
-
-    TargetLowering::ArgListTy Args;
-    Args.emplace_back(DAG.getUNDEF(MVT::i64),
-                      Type::getInt64Ty(*DAG.getContext()));
-    Args.emplace_back(CmpVal, Ty);
-    Args.emplace_back(NewVal, Ty);
-    Args.emplace_back(Ptr, IntPtrTy);
-
-    // Lower to dummy call to use ABI for consecutive register allocation.
-    // Places return value, compare value, and new value in X3/X4/X5 as required
-    // by lwat/ldat FC=16, avoiding a new register class for 3 adjacent
-    // registers.
-    const char *SymName = IntrinsicID == Intrinsic::ppc_amo_ldat_csne
-                              ? "__ldat_csne_pseudo"
-                              : "__lwat_csne_pseudo";
-    SDValue Callee =
-        DAG.getExternalSymbol(SymName, getPointerTy(DAG.getDataLayout()));
-
-    TargetLowering::CallLoweringInfo CLI(DAG);
-    CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(CallingConv::C, Ty, Callee,
-                                                     std::move(Args));
-
-    auto Result = LowerCallTo(CLI);
-    return DAG.getMergeValues({Result.first, Result.second}, dl);
-  }
-  return SDValue();
-}
-
 SDValue PPCTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
                                                SelectionDAG &DAG) const {
   // SelectionDAGBuilder::visitTargetIntrinsic may insert one extra chain to
@@ -12788,7 +12745,7 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
 
   // For counter-based loop handling.
   case ISD::INTRINSIC_W_CHAIN:
-    return LowerINTRINSIC_W_CHAIN(Op, DAG);
+    return SDValue();
 
   case ISD::BITCAST:            return LowerBITCAST(Op, DAG);
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index cfcc6b5f03edc..4e816790b3f02 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -736,7 +736,6 @@ namespace llvm {
                        EVT VT, SDValue V1, SDValue V2) const;
     SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
-    SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index a973654c22c38..af3b3ebf6d94c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -332,6 +332,12 @@ def LDAT : X_RD5_RS5_IM5<31, 614, (outs g8prc:$RST), (ins g8prc:$RSTi, ptr_rc_no
                          "ldat $RST, $RA, $RB", IIC_LdStLoad>, isPPC64,
            Requires<[IsISA3_0]>,
            RegConstraint<"$RSTi = $RST">;
+
+let Uses = [X4, X5], Defs = [X3], hasExtraSrcRegAllocReq = 1,
+      mayStore = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in
+def LDAT_CSNE : X_RD5_RS5_IM5<31, 614, (outs g8rc:$RST), (ins ptr_rc_nor0:$RA, u5imm:$RB),
+                         "ldat $RST, $RA, $RB", IIC_LdStLoad>,
+           Requires<[IsISA3_0]>;
 }
 
 def LDAT_PSEUDO : PPCCustomInserterPseudo<
@@ -348,6 +354,13 @@ def LDAT_COND_PSEUDO : PPCCustomInserterPseudo <
     [(set i64:$dst, (int_ppc_amo_ldat_cond ptr_rc_nor0:$ptr,
                                             u5imm_timm:$fc))]>;
 
+let Defs = [X3, X4, X5] in
+def LDAT_CSNE_PSEUDO : PPCPostRAExpPseudo<
+    (outs g8rc:$dst),
+    (ins ptr_rc_nor0:$ptr, g8rc:$cmp_val, g8rc:$new_val),
+    "#LDAT_CSNE_PSEUDO",
+    [(set i64:$dst, (int_ppc_amo_ldat_csne ptr_rc_nor0:$ptr, g8rc:$cmp_val, g8rc:$new_val))]>;
+
 let Defs = [CR0], mayStore = 1, mayLoad = 1, hasSideEffects = 1 in {
 def STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$RST, (memrr $RA, $RB):$addr),
                           "stdcx. $RST, $addr", IIC_LdStSTDCX, []>, isRecordForm;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 6d95314d4b019..7e5144d86235b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -3339,6 +3339,9 @@ bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
     MI.removeOperand(0);
     return true;
   }
+  case PPC::LWAT_CSNE_PSEUDO:
+  case PPC::LDAT_CSNE_PSEUDO:
+    return expandAMOCSNEPseudo(MI);
   }
   return false;
 }
@@ -5892,3 +5895,60 @@ bool PPCInstrInfo::areMemAccessesTriviallyDisjoint(
   }
   return false;
 }
+
+// Expands LWAT_CSNE_PSEUDO/LDAT_CSNE_PSEUDO post register allocation.
+// lwat/ldat FC=16 requires 3 consecutive registers. X3/X4/X5 are
+// hardcoded post-RA to satisfy this constraint without a dedicated
+// register class.
+bool PPCInstrInfo::expandAMOCSNEPseudo(MachineInstr &MI) const {
+  MachineBasicBlock &MBB = *MI.getParent();
+  DebugLoc DL = MI.getDebugLoc();
+  bool IsLDAT = MI.getOpcode() == PPC::LDAT_CSNE_PSEUDO;
+
+  Register DstReg = MI.getOperand(0).getReg();
+  Register PtrReg = MI.getOperand(1).getReg();
+  Register CmpReg = MI.getOperand(2).getReg();
+  Register NewReg = MI.getOperand(3).getReg();
+
+  const TargetRegisterInfo *TRI = &getRegisterInfo();
+  Register CmpReg64 = CmpReg;
+  Register NewReg64 = NewReg;
+  if (!IsLDAT) {
+    CmpReg64 =
+        TRI->getMatchingSuperReg(CmpReg, PPC::sub_32, &PPC::G8RCRegClass);
+    NewReg64 =
+        TRI->getMatchingSuperReg(NewReg, PPC::sub_32, &PPC::G8RCRegClass);
+  }
+  if (CmpReg64 != PPC::X4)
+    BuildMI(MBB, MI, DL, get(PPC::OR8), PPC::X4)
+        .addReg(CmpReg64)
+        .addReg(CmpReg64);
+  if (NewReg64 != PPC::X5)
+    BuildMI(MBB, MI, DL, get(PPC::OR8), PPC::X5)
+        .addReg(NewReg64)
+        .addReg(NewReg64);
+
+  Register ScratchReg = PtrReg;
+  if (PtrReg == PPC::X3 || PtrReg == PPC::X4 || PtrReg == PPC::X5) {
+    RegScavenger RS;
+    RS.enterBasicBlockEnd(MBB);
+    RS.backward(std::next(MI.getIterator()));
+    ScratchReg = RS.scavengeRegisterBackwards(
+        PPC::G8RCRegClass, MI.getIterator(), false, 0, false);
+    BuildMI(MBB, MI, DL, get(PPC::OR8), ScratchReg)
+        .addReg(PtrReg)
+        .addReg(PtrReg);
+  }
+
+  BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::LDAT_CSNE : PPC::LWAT_CSNE), PPC::X3)
+      .addReg(ScratchReg)
+      .addImm(16);
+
+  if (DstReg != (IsLDAT ? PPC::X3 : PPC::R3)) {
+    BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::OR8 : PPC::OR), DstReg)
+        .addReg(IsLDAT ? PPC::X3 : PPC::R3)
+        .addReg(IsLDAT ? PPC::X3 : PPC::R3);
+  }
+  MI.eraseFromParent();
+  return true;
+}
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
index adfae11d4cac4..c8a747ac829ec 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h
@@ -716,6 +716,7 @@ class PPCInstrInfo : public PPCGenInstrInfo {
 
   // Lower pseudo instructions after register allocation.
   bool expandPostRAPseudo(MachineInstr &MI) const override;
+  bool expandAMOCSNEPseudo(MachineInstr &MI) const;
 
   const TargetRegisterClass *updatedRC(const TargetRegisterClass *RC) const;
   static int getRecordFormOpcode(unsigned Opcode);
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index e3240a72a113f..7bd98b5dbd734 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2164,6 +2164,12 @@ def LWAT : X_RD5_RS5_IM5<31, 582, (outs g8prc:$RST), (ins g8prc:$RSTi, ptr_rc_no
            Requires<[IsISA3_0]>,
            RegConstraint<"$RSTi = $RST">;
 
+let Uses = [X4, X5], Defs = [X3], hasExtraSrcRegAllocReq = 1, mayLoad = 1,
+       mayStore = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in
+def LWAT_CSNE : X_RD5_RS5_IM5<31, 582, (outs g8rc:$RST), (ins ptr_rc_nor0:$RA, u5imm:$RB),
+                         "lwat $RST, $RA, $RB", IIC_LdStLoad>,
+           Requires<[IsISA3_0]>;
+
 def LWAT_PSEUDO : PPCCustomInserterPseudo<
     (outs gprc:$dst),
     (ins ptr_rc_nor0:$ptr, gprc:$val, u5imm:$fc),
@@ -2176,6 +2182,13 @@ def LWAT_COND_PSEUDO : PPCCustomInserterPseudo <
     "#LWAT_COND_PSEUDO",
     [(set i32:$dst, (int_ppc_amo_lwat_cond ptr_rc_nor0:$ptr, u5imm_timm:$fc))]>;
 
+let Defs = [R3, R4, R5] in
+def LWAT_CSNE_PSEUDO : PPCPostRAExpPseudo<
+    (outs gprc:$dst),
+    (ins ptr_rc_nor0:$ptr, gprc:$cmp_val, gprc:$new_val),
+    "#LWAT_CSNE_PSEUDO",
+    [(set i32:$dst, (int_ppc_amo_lwat_csne ptr_rc_nor0:$ptr, gprc:$cmp_val, gprc:$new_val))]>;
+
 let Defs = [CR0], mayStore = 1, mayLoad = 1, hasSideEffects = 1 in {
 def STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
                     "stbcx. $RST, $addr", IIC_LdStSTWCX, []>,
diff --git a/llvm/test/CodeGen/PowerPC/amo-enable.ll b/llvm/test/CodeGen/PowerPC/amo-enable.ll
index e8d8122897903..4af15661155ff 100644
--- a/llvm/test/CodeGen/PowerPC/amo-enable.ll
+++ b/llvm/test/CodeGen/PowerPC/amo-enable.ll
@@ -115,80 +115,76 @@ entry:
 define void @test_lwat_csne(ptr noundef %ptr, i32 noundef %value1, i32 noundef %value2, ptr nocapture %resp) nounwind {
 ; CHECK-LABEL: test_lwat_csne:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    mflr r0
-; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
-; CHECK-NEXT:    stdu r1, -48(r1)
-; CHECK-NEXT:    mr r30, r6
-; CHECK-NEXT:    clrldi r4, r4, 32
-; CHECK-NEXT:    clrldi r5, r5, 32
-; CHECK-NEXT:    mr r6, r3
-; CHECK-NEXT:    std r0, 64(r1)
-; CHECK-NEXT:    lwat r3, r6, 16
-; CHECK-NEXT:    stw r3, 0(r30)
-; CHECK-NEXT:    addi r1, r1, 48
-; CHECK-NEXT:    ld r0, 16(r1)
-; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
-; CHECK-NEXT:    mtlr r0
+; CHECK-NEXT:    mr r9, r3
+; CHECK-NEXT:    mr r7, r3
+; CHECK-NEXT:    lwat r3, r9, 16
+; CHECK-NEXT:    li r4, 44
+; CHECK-NEXT:    mr r8, r3
+; CHECK-NEXT:    li r3, 55
+; CHECK-NEXT:    mr r5, r3
+; CHECK-NEXT:    stw r8, 0(r6)
+; CHECK-NEXT:    lwat r3, r7, 16
+; CHECK-NEXT:    mr r7, r3
+; CHECK-NEXT:    stw r7, 0(r6)
 ; CHECK-NEXT:    blr
 ;
 ; CHECK-BE-LABEL: test_lwat_csne:
 ; CHECK-BE:       # %bb.0: # %entry
-; CHECK-BE-NEXT:    mflr r0
-; CHECK-BE-NEXT:    stdu r1, -128(r1)
-; CHECK-BE-NEXT:    std r0, 144(r1)
-; CHECK-BE-NEXT:    std r31, 120(r1) # 8-byte Folded Spill
-; CHECK-BE-NEXT:    mr r31, r6
-; CHECK-BE-NEXT:    mr r6, r3
-; CHECK-BE-NEXT:    clrldi r4, r4, 32
-; CHECK-BE-NEXT:    clrldi r5, r5, 32
-; CHECK-BE-NEXT:    lwat r3, r6, 16
-; CHECK-BE-NEXT:    stw r3, 0(r31)
-; CHECK-BE-NEXT:    ld r31, 120(r1) # 8-byte Folded Reload
-; CHECK-BE-NEXT:    addi r1, r1, 128
-; CHECK-BE-NEXT:    ld r0, 16(r1)
-; CHECK-BE-NEXT:    mtlr r0
+; CHECK-BE-NEXT:    mr r9, r3
+; CHECK-BE-NEXT:    mr r7, r3
+; CHECK-BE-NEXT:    lwat r3, r9, 16
+; CHECK-BE-NEXT:    li r4, 44
+; CHECK-BE-NEXT:    mr r8, r3
+; CHECK-BE-NEXT:    li r3, 55
+; CHECK-BE-NEXT:    mr r5, r3
+; CHECK-BE-NEXT:    stw r8, 0(r6)
+; CHECK-BE-NEXT:    lwat r3, r7, 16
+; CHECK-BE-NEXT:    mr r7, r3
+; CHECK-BE-NEXT:    stw r7, 0(r6)
 ; CHECK-BE-NEXT:    blr
 entry:
-  %0 = tail call i32 @llvm.ppc.amo.lwat.csne(ptr %ptr, i32 %value1, i32 %value2)
+  %0 = call i32 @llvm.ppc.amo.lwat.csne(ptr %ptr, i32 %value1, i32 %value2)
   store i32 %0, ptr %resp, align 4
+  %1 = tail call i32 @llvm.ppc.amo.lwat.csne(ptr %ptr, i32 44, i32 55)
+  store i32 %1, ptr %resp, align 4
   ret void
 }
 
 define void @test_ldat_csne(ptr noundef %ptr, i64 noundef %value1, i64 noundef %value2, ptr nocapture %resp) nounwind {
 ; CHECK-LABEL: test_ldat_csne:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    mflr r0
-; CHECK-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
-; CHECK-NEXT:    stdu r1, -48(r1)
-; CHECK-NEXT:    mr r30, r6
-; CHECK-NEXT:    mr r6, r3
-; CHECK-NEXT:    std r0, 64(r1)
-; CHECK-NEXT:    ldat r3, r6, 16
-; CHECK-NEXT:    std r3, 0(r30)
-; CHECK-NEXT:    addi r1, r1, 48
-; CHECK-NEXT:    ld r0, 16(r1)
-; CHECK-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
-; CHECK-NEXT:    mtlr r0
+; CHECK-NEXT:    mr r9, r3
+; CHECK-NEXT:    mr r7, r3
+; CHECK-NEXT:    ldat r3, r9, 16
+; CHECK-NEXT:    li r4, 44
+; CHECK-NEXT:    mr r8, r3
+; CHECK-NEXT:    li r3, 55
+; CHECK-NEXT:    mr r5, r3
+; CHECK-NEXT:    std r8, 0(r6)
+; CHECK-NEXT:    ldat r3, r7, 16
+; CHECK-NEXT:    mr r7, r3
+; CHECK-NEXT:    std r7, 0(r6)
 ; CHECK-NEXT:    blr
 ;
 ; CHECK-BE-LABEL: test_ldat_csne:
 ; CHECK-BE:       # %bb.0: # %entry
-; CHECK-BE-NEXT:    mflr r0
-; CHECK-BE-NEXT:    stdu r1, -128(r1)
-; CHECK-BE-NEXT:    std r0, 144(r1)
-; CHECK-BE-NEXT:    std r31, 120(r1) # 8-byte Folded Spill
-; CHECK-BE-NEXT:    mr r31, r6
-; CHECK-BE-NEXT:    mr r6, r3
-; CHECK-BE-NEXT:    ldat r3, r6, 16
-; CHECK-BE-NEXT:    std r3, 0(r31)
-; CHECK-BE-NEXT:    ld r31, 120(r1) # 8-byte Folded Reload
-; CHECK-BE-NEXT:    addi r1, r1, 128
-; CHECK-BE-NEXT:    ld r0, 16(r1)
-; CHECK-BE-NEXT:    mtlr r0
+; CHECK-BE-NEXT:    mr r9, r3
+; CHECK-BE-NEXT:    mr r7, r3
+; CHECK-BE-NEXT:    ldat r3, r9, 16
+; CHECK-BE-NEXT:    li r4, 44
+; CHECK-BE-NEXT:    mr r8, r3
+; CHECK-BE-NEXT:    li r3, 55
+; CHECK-BE-NEXT:    mr r5, r3
+; CHECK-BE-NEXT:    std r8, 0(r6)
+; CHECK-BE-NEXT:    ldat r3, r7, 16
+; CHECK-BE-NEXT:    mr r7, r3
+; CHECK-BE-NEXT:    std r7, 0(r6)
 ; CHECK-BE-NEXT:    blr
 entry:
-  %0 = tail call i64 @llvm.ppc.amo.ldat.csne(ptr %ptr, i64 %value1, i64 %value2)
+  %0 = call i64 @llvm.ppc.amo.ldat.csne(ptr %ptr, i64 %value1, i64 %value2)
   store i64 %0, ptr %resp, align 8
+  %1 = tail call i64 @llvm.ppc.amo.ldat.csne(ptr %ptr, i64 44, i64 55)
+  store i64 %1, ptr %resp, align 8
   ret void
 }
 

>From 9fd6506bfc65bb8af1746a0379fbb5022cd50f39 Mon Sep 17 00:00:00 2001
From: Maryam Moghadas <maryammo at ca.ibm.com>
Date: Wed, 8 Apr 2026 22:28:45 +0000
Subject: [PATCH 2/3] Address review comments

---
 llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 10 +++++-----
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 24 +++---------------------
 llvm/lib/Target/PowerPC/PPCInstrInfo.td  |  8 ++++----
 llvm/test/CodeGen/PowerPC/amo-enable.ll  | 16 ++++++++--------
 4 files changed, 20 insertions(+), 38 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index af3b3ebf6d94c..8b2fbd057228d 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -333,8 +333,8 @@ def LDAT : X_RD5_RS5_IM5<31, 614, (outs g8prc:$RST), (ins g8prc:$RSTi, ptr_rc_no
            Requires<[IsISA3_0]>,
            RegConstraint<"$RSTi = $RST">;
 
-let Uses = [X4, X5], Defs = [X3], hasExtraSrcRegAllocReq = 1,
-      mayStore = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in
+let hasExtraSrcRegAllocReq = 1, mayStore = 1,
+      isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in
 def LDAT_CSNE : X_RD5_RS5_IM5<31, 614, (outs g8rc:$RST), (ins ptr_rc_nor0:$RA, u5imm:$RB),
                          "ldat $RST, $RA, $RB", IIC_LdStLoad>,
            Requires<[IsISA3_0]>;
@@ -354,12 +354,12 @@ def LDAT_COND_PSEUDO : PPCCustomInserterPseudo <
     [(set i64:$dst, (int_ppc_amo_ldat_cond ptr_rc_nor0:$ptr,
                                             u5imm_timm:$fc))]>;
 
-let Defs = [X3, X4, X5] in
+let Defs = [X3, X4, X5], Uses = [X4, X5] in
 def LDAT_CSNE_PSEUDO : PPCPostRAExpPseudo<
     (outs g8rc:$dst),
-    (ins ptr_rc_nor0:$ptr, g8rc:$cmp_val, g8rc:$new_val),
+    (ins ptr_rc_nor0:$ptr),
     "#LDAT_CSNE_PSEUDO",
-    [(set i64:$dst, (int_ppc_amo_ldat_csne ptr_rc_nor0:$ptr, g8rc:$cmp_val, g8rc:$new_val))]>;
+    [(set i64:$dst, (int_ppc_amo_ldat_csne ptr_rc_nor0:$ptr, X4, X5))]>;
 
 let Defs = [CR0], mayStore = 1, mayLoad = 1, hasSideEffects = 1 in {
 def STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$RST, (memrr $RA, $RB):$addr),
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 7e5144d86235b..206e42b6a3289 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -5907,26 +5907,6 @@ bool PPCInstrInfo::expandAMOCSNEPseudo(MachineInstr &MI) const {
 
   Register DstReg = MI.getOperand(0).getReg();
   Register PtrReg = MI.getOperand(1).getReg();
-  Register CmpReg = MI.getOperand(2).getReg();
-  Register NewReg = MI.getOperand(3).getReg();
-
-  const TargetRegisterInfo *TRI = &getRegisterInfo();
-  Register CmpReg64 = CmpReg;
-  Register NewReg64 = NewReg;
-  if (!IsLDAT) {
-    CmpReg64 =
-        TRI->getMatchingSuperReg(CmpReg, PPC::sub_32, &PPC::G8RCRegClass);
-    NewReg64 =
-        TRI->getMatchingSuperReg(NewReg, PPC::sub_32, &PPC::G8RCRegClass);
-  }
-  if (CmpReg64 != PPC::X4)
-    BuildMI(MBB, MI, DL, get(PPC::OR8), PPC::X4)
-        .addReg(CmpReg64)
-        .addReg(CmpReg64);
-  if (NewReg64 != PPC::X5)
-    BuildMI(MBB, MI, DL, get(PPC::OR8), PPC::X5)
-        .addReg(NewReg64)
-        .addReg(NewReg64);
 
   Register ScratchReg = PtrReg;
   if (PtrReg == PPC::X3 || PtrReg == PPC::X4 || PtrReg == PPC::X5) {
@@ -5942,7 +5922,9 @@ bool PPCInstrInfo::expandAMOCSNEPseudo(MachineInstr &MI) const {
 
   BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::LDAT_CSNE : PPC::LWAT_CSNE), PPC::X3)
       .addReg(ScratchReg)
-      .addImm(16);
+      .addImm(16)
+      .addReg(PPC::X4, RegState::Implicit)
+      .addReg(PPC::X5, RegState::Implicit);
 
   if (DstReg != (IsLDAT ? PPC::X3 : PPC::R3)) {
     BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::OR8 : PPC::OR), DstReg)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 7bd98b5dbd734..7507c7fcf484d 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2164,7 +2164,7 @@ def LWAT : X_RD5_RS5_IM5<31, 582, (outs g8prc:$RST), (ins g8prc:$RSTi, ptr_rc_no
            Requires<[IsISA3_0]>,
            RegConstraint<"$RSTi = $RST">;
 
-let Uses = [X4, X5], Defs = [X3], hasExtraSrcRegAllocReq = 1, mayLoad = 1,
+let hasExtraSrcRegAllocReq = 1, mayLoad = 1,
        mayStore = 1, isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in
 def LWAT_CSNE : X_RD5_RS5_IM5<31, 582, (outs g8rc:$RST), (ins ptr_rc_nor0:$RA, u5imm:$RB),
                          "lwat $RST, $RA, $RB", IIC_LdStLoad>,
@@ -2182,12 +2182,12 @@ def LWAT_COND_PSEUDO : PPCCustomInserterPseudo <
     "#LWAT_COND_PSEUDO",
     [(set i32:$dst, (int_ppc_amo_lwat_cond ptr_rc_nor0:$ptr, u5imm_timm:$fc))]>;
 
-let Defs = [R3, R4, R5] in
+let Defs = [R3, R4, R5], Uses = [R4, R5] in
 def LWAT_CSNE_PSEUDO : PPCPostRAExpPseudo<
     (outs gprc:$dst),
-    (ins ptr_rc_nor0:$ptr, gprc:$cmp_val, gprc:$new_val),
+    (ins ptr_rc_nor0:$ptr),
     "#LWAT_CSNE_PSEUDO",
-    [(set i32:$dst, (int_ppc_amo_lwat_csne ptr_rc_nor0:$ptr, gprc:$cmp_val, gprc:$new_val))]>;
+    [(set i32:$dst, (int_ppc_amo_lwat_csne ptr_rc_nor0:$ptr, R4, R5))]>;
 
 let Defs = [CR0], mayStore = 1, mayLoad = 1, hasSideEffects = 1 in {
 def STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
diff --git a/llvm/test/CodeGen/PowerPC/amo-enable.ll b/llvm/test/CodeGen/PowerPC/amo-enable.ll
index 4af15661155ff..7346199461f67 100644
--- a/llvm/test/CodeGen/PowerPC/amo-enable.ll
+++ b/llvm/test/CodeGen/PowerPC/amo-enable.ll
@@ -117,11 +117,12 @@ define void @test_lwat_csne(ptr noundef %ptr, i32 noundef %value1, i32 noundef %
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    mr r9, r3
 ; CHECK-NEXT:    mr r7, r3
+; CHECK-NEXT:    # kill: def $r4 killed $r4 killed $x4
+; CHECK-NEXT:    # kill: def $r5 killed $r5 killed $x5
 ; CHECK-NEXT:    lwat r3, r9, 16
 ; CHECK-NEXT:    li r4, 44
+; CHECK-NEXT:    li r5, 55
 ; CHECK-NEXT:    mr r8, r3
-; CHECK-NEXT:    li r3, 55
-; CHECK-NEXT:    mr r5, r3
 ; CHECK-NEXT:    stw r8, 0(r6)
 ; CHECK-NEXT:    lwat r3, r7, 16
 ; CHECK-NEXT:    mr r7, r3
@@ -132,11 +133,12 @@ define void @test_lwat_csne(ptr noundef %ptr, i32 noundef %value1, i32 noundef %
 ; CHECK-BE:       # %bb.0: # %entry
 ; CHECK-BE-NEXT:    mr r9, r3
 ; CHECK-BE-NEXT:    mr r7, r3
+; CHECK-BE-NEXT:    # kill: def $r4 killed $r4 killed $x4
+; CHECK-BE-NEXT:    # kill: def $r5 killed $r5 killed $x5
 ; CHECK-BE-NEXT:    lwat r3, r9, 16
 ; CHECK-BE-NEXT:    li r4, 44
+; CHECK-BE-NEXT:    li r5, 55
 ; CHECK-BE-NEXT:    mr r8, r3
-; CHECK-BE-NEXT:    li r3, 55
-; CHECK-BE-NEXT:    mr r5, r3
 ; CHECK-BE-NEXT:    stw r8, 0(r6)
 ; CHECK-BE-NEXT:    lwat r3, r7, 16
 ; CHECK-BE-NEXT:    mr r7, r3
@@ -157,9 +159,8 @@ define void @test_ldat_csne(ptr noundef %ptr, i64 noundef %value1, i64 noundef %
 ; CHECK-NEXT:    mr r7, r3
 ; CHECK-NEXT:    ldat r3, r9, 16
 ; CHECK-NEXT:    li r4, 44
+; CHECK-NEXT:    li r5, 55
 ; CHECK-NEXT:    mr r8, r3
-; CHECK-NEXT:    li r3, 55
-; CHECK-NEXT:    mr r5, r3
 ; CHECK-NEXT:    std r8, 0(r6)
 ; CHECK-NEXT:    ldat r3, r7, 16
 ; CHECK-NEXT:    mr r7, r3
@@ -172,9 +173,8 @@ define void @test_ldat_csne(ptr noundef %ptr, i64 noundef %value1, i64 noundef %
 ; CHECK-BE-NEXT:    mr r7, r3
 ; CHECK-BE-NEXT:    ldat r3, r9, 16
 ; CHECK-BE-NEXT:    li r4, 44
+; CHECK-BE-NEXT:    li r5, 55
 ; CHECK-BE-NEXT:    mr r8, r3
-; CHECK-BE-NEXT:    li r3, 55
-; CHECK-BE-NEXT:    mr r5, r3
 ; CHECK-BE-NEXT:    std r8, 0(r6)
 ; CHECK-BE-NEXT:    ldat r3, r7, 16
 ; CHECK-BE-NEXT:    mr r7, r3

>From c3095558802137834f515c6f3e3ab33155f1ac4b Mon Sep 17 00:00:00 2001
From: Maryam Moghadas <maryammo at ca.ibm.com>
Date: Tue, 14 Apr 2026 16:39:31 +0000
Subject: [PATCH 3/3] Use R8/R9/R10 and  scratch for AMO CSNE pseudo expansion

---
 llvm/lib/Target/PowerPC/PPCInstr64Bit.td |   4 +-
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp |  36 +++---
 llvm/lib/Target/PowerPC/PPCInstrInfo.td  |   4 +-
 llvm/test/CodeGen/PowerPC/amo-enable.ll  | 144 ++++++++++++++++-------
 4 files changed, 122 insertions(+), 66 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 8b2fbd057228d..282e70f481982 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -354,12 +354,12 @@ def LDAT_COND_PSEUDO : PPCCustomInserterPseudo <
     [(set i64:$dst, (int_ppc_amo_ldat_cond ptr_rc_nor0:$ptr,
                                             u5imm_timm:$fc))]>;
 
-let Defs = [X3, X4, X5], Uses = [X4, X5] in
+let Defs = [X8, X9, X10], Uses = [X9, X10] in
 def LDAT_CSNE_PSEUDO : PPCPostRAExpPseudo<
     (outs g8rc:$dst),
     (ins ptr_rc_nor0:$ptr),
     "#LDAT_CSNE_PSEUDO",
-    [(set i64:$dst, (int_ppc_amo_ldat_csne ptr_rc_nor0:$ptr, X4, X5))]>;
+    [(set i64:$dst, (int_ppc_amo_ldat_csne ptr_rc_nor0:$ptr, X9, X10))]>;
 
 let Defs = [CR0], mayStore = 1, mayLoad = 1, hasSideEffects = 1 in {
 def STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$RST, (memrr $RA, $RB):$addr),
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 206e42b6a3289..d458c0005f99b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -5897,7 +5897,7 @@ bool PPCInstrInfo::areMemAccessesTriviallyDisjoint(
 }
 
 // Expands LWAT_CSNE_PSEUDO/LDAT_CSNE_PSEUDO post register allocation.
-// lwat/ldat FC=16 requires 3 consecutive registers. X3/X4/X5 are
+// lwat/ldat FC=16 requires 3 consecutive registers. X8/X9/X10 are
 // hardcoded post-RA to satisfy this constraint without a dedicated
 // register class.
 bool PPCInstrInfo::expandAMOCSNEPseudo(MachineInstr &MI) const {
@@ -5909,27 +5909,27 @@ bool PPCInstrInfo::expandAMOCSNEPseudo(MachineInstr &MI) const {
   Register PtrReg = MI.getOperand(1).getReg();
 
   Register ScratchReg = PtrReg;
-  if (PtrReg == PPC::X3 || PtrReg == PPC::X4 || PtrReg == PPC::X5) {
-    RegScavenger RS;
-    RS.enterBasicBlockEnd(MBB);
-    RS.backward(std::next(MI.getIterator()));
-    ScratchReg = RS.scavengeRegisterBackwards(
-        PPC::G8RCRegClass, MI.getIterator(), false, 0, false);
-    BuildMI(MBB, MI, DL, get(PPC::OR8), ScratchReg)
-        .addReg(PtrReg)
-        .addReg(PtrReg);
-  }
-
-  BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::LDAT_CSNE : PPC::LWAT_CSNE), PPC::X3)
+  if (PtrReg == PPC::X8 || PtrReg == PPC::X9 || PtrReg == PPC::X10) {
+    // If ptr is in X8/X9/X10, use $dst as scratch to move ptr away from
+    // X8/X9/X10 since lwat FC=16 always writes its result to X8. After lwat
+    // copy X8 into $dst.
+    Register DstReg64 = IsLDAT ? DstReg
+                               : Register(getRegisterInfo().getMatchingSuperReg(
+                                     DstReg, PPC::sub_32, &PPC::G8RCRegClass));
+    BuildMI(MBB, MI, DL, get(PPC::OR8), DstReg64).addReg(PtrReg).addReg(PtrReg);
+    ScratchReg = DstReg64;
+  }
+
+  BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::LDAT_CSNE : PPC::LWAT_CSNE), PPC::X8)
       .addReg(ScratchReg)
       .addImm(16)
-      .addReg(PPC::X4, RegState::Implicit)
-      .addReg(PPC::X5, RegState::Implicit);
+      .addReg(PPC::X9, RegState::Implicit)
+      .addReg(PPC::X10, RegState::Implicit);
 
-  if (DstReg != (IsLDAT ? PPC::X3 : PPC::R3)) {
+  if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
     BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::OR8 : PPC::OR), DstReg)
-        .addReg(IsLDAT ? PPC::X3 : PPC::R3)
-        .addReg(IsLDAT ? PPC::X3 : PPC::R3);
+        .addReg(IsLDAT ? PPC::X8 : PPC::R8)
+        .addReg(IsLDAT ? PPC::X8 : PPC::R8);
   }
   MI.eraseFromParent();
   return true;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 7507c7fcf484d..b9f1778cd9ac8 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2182,12 +2182,12 @@ def LWAT_COND_PSEUDO : PPCCustomInserterPseudo <
     "#LWAT_COND_PSEUDO",
     [(set i32:$dst, (int_ppc_amo_lwat_cond ptr_rc_nor0:$ptr, u5imm_timm:$fc))]>;
 
-let Defs = [R3, R4, R5], Uses = [R4, R5] in
+let Defs = [R8, R9, R10], Uses = [R9, R10] in
 def LWAT_CSNE_PSEUDO : PPCPostRAExpPseudo<
     (outs gprc:$dst),
     (ins ptr_rc_nor0:$ptr),
     "#LWAT_CSNE_PSEUDO",
-    [(set i32:$dst, (int_ppc_amo_lwat_csne ptr_rc_nor0:$ptr, R4, R5))]>;
+    [(set i32:$dst, (int_ppc_amo_lwat_csne ptr_rc_nor0:$ptr, R9, R10))]>;
 
 let Defs = [CR0], mayStore = 1, mayLoad = 1, hasSideEffects = 1 in {
 def STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
diff --git a/llvm/test/CodeGen/PowerPC/amo-enable.ll b/llvm/test/CodeGen/PowerPC/amo-enable.ll
index 7346199461f67..b4923797b590c 100644
--- a/llvm/test/CodeGen/PowerPC/amo-enable.ll
+++ b/llvm/test/CodeGen/PowerPC/amo-enable.ll
@@ -115,34 +115,30 @@ entry:
 define void @test_lwat_csne(ptr noundef %ptr, i32 noundef %value1, i32 noundef %value2, ptr nocapture %resp) nounwind {
 ; CHECK-LABEL: test_lwat_csne:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    mr r9, r3
-; CHECK-NEXT:    mr r7, r3
-; CHECK-NEXT:    # kill: def $r4 killed $r4 killed $x4
-; CHECK-NEXT:    # kill: def $r5 killed $r5 killed $x5
-; CHECK-NEXT:    lwat r3, r9, 16
-; CHECK-NEXT:    li r4, 44
-; CHECK-NEXT:    li r5, 55
-; CHECK-NEXT:    mr r8, r3
-; CHECK-NEXT:    stw r8, 0(r6)
-; CHECK-NEXT:    lwat r3, r7, 16
-; CHECK-NEXT:    mr r7, r3
-; CHECK-NEXT:    stw r7, 0(r6)
+; CHECK-NEXT:    mr r9, r4
+; CHECK-NEXT:    mr r10, r5
+; CHECK-NEXT:    lwat r8, r3, 16
+; CHECK-NEXT:    li r9, 44
+; CHECK-NEXT:    li r10, 55
+; CHECK-NEXT:    mr r4, r8
+; CHECK-NEXT:    stw r4, 0(r6)
+; CHECK-NEXT:    lwat r8, r3, 16
+; CHECK-NEXT:    mr r3, r8
+; CHECK-NEXT:    stw r3, 0(r6)
 ; CHECK-NEXT:    blr
 ;
 ; CHECK-BE-LABEL: test_lwat_csne:
 ; CHECK-BE:       # %bb.0: # %entry
-; CHECK-BE-NEXT:    mr r9, r3
-; CHECK-BE-NEXT:    mr r7, r3
-; CHECK-BE-NEXT:    # kill: def $r4 killed $r4 killed $x4
-; CHECK-BE-NEXT:    # kill: def $r5 killed $r5 killed $x5
-; CHECK-BE-NEXT:    lwat r3, r9, 16
-; CHECK-BE-NEXT:    li r4, 44
-; CHECK-BE-NEXT:    li r5, 55
-; CHECK-BE-NEXT:    mr r8, r3
-; CHECK-BE-NEXT:    stw r8, 0(r6)
-; CHECK-BE-NEXT:    lwat r3, r7, 16
-; CHECK-BE-NEXT:    mr r7, r3
-; CHECK-BE-NEXT:    stw r7, 0(r6)
+; CHECK-BE-NEXT:    mr r9, r4
+; CHECK-BE-NEXT:    mr r10, r5
+; CHECK-BE-NEXT:    lwat r8, r3, 16
+; CHECK-BE-NEXT:    li r9, 44
+; CHECK-BE-NEXT:    li r10, 55
+; CHECK-BE-NEXT:    mr r4, r8
+; CHECK-BE-NEXT:    stw r4, 0(r6)
+; CHECK-BE-NEXT:    lwat r8, r3, 16
+; CHECK-BE-NEXT:    mr r3, r8
+; CHECK-BE-NEXT:    stw r3, 0(r6)
 ; CHECK-BE-NEXT:    blr
 entry:
   %0 = call i32 @llvm.ppc.amo.lwat.csne(ptr %ptr, i32 %value1, i32 %value2)
@@ -155,30 +151,30 @@ entry:
 define void @test_ldat_csne(ptr noundef %ptr, i64 noundef %value1, i64 noundef %value2, ptr nocapture %resp) nounwind {
 ; CHECK-LABEL: test_ldat_csne:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    mr r9, r3
-; CHECK-NEXT:    mr r7, r3
-; CHECK-NEXT:    ldat r3, r9, 16
-; CHECK-NEXT:    li r4, 44
-; CHECK-NEXT:    li r5, 55
-; CHECK-NEXT:    mr r8, r3
-; CHECK-NEXT:    std r8, 0(r6)
-; CHECK-NEXT:    ldat r3, r7, 16
-; CHECK-NEXT:    mr r7, r3
-; CHECK-NEXT:    std r7, 0(r6)
+; CHECK-NEXT:    mr r9, r4
+; CHECK-NEXT:    mr r10, r5
+; CHECK-NEXT:    ldat r8, r3, 16
+; CHECK-NEXT:    li r9, 44
+; CHECK-NEXT:    li r10, 55
+; CHECK-NEXT:    mr r4, r8
+; CHECK-NEXT:    std r4, 0(r6)
+; CHECK-NEXT:    ldat r8, r3, 16
+; CHECK-NEXT:    mr r3, r8
+; CHECK-NEXT:    std r3, 0(r6)
 ; CHECK-NEXT:    blr
 ;
 ; CHECK-BE-LABEL: test_ldat_csne:
 ; CHECK-BE:       # %bb.0: # %entry
-; CHECK-BE-NEXT:    mr r9, r3
-; CHECK-BE-NEXT:    mr r7, r3
-; CHECK-BE-NEXT:    ldat r3, r9, 16
-; CHECK-BE-NEXT:    li r4, 44
-; CHECK-BE-NEXT:    li r5, 55
-; CHECK-BE-NEXT:    mr r8, r3
-; CHECK-BE-NEXT:    std r8, 0(r6)
-; CHECK-BE-NEXT:    ldat r3, r7, 16
-; CHECK-BE-NEXT:    mr r7, r3
-; CHECK-BE-NEXT:    std r7, 0(r6)
+; CHECK-BE-NEXT:    mr r9, r4
+; CHECK-BE-NEXT:    mr r10, r5
+; CHECK-BE-NEXT:    ldat r8, r3, 16
+; CHECK-BE-NEXT:    li r9, 44
+; CHECK-BE-NEXT:    li r10, 55
+; CHECK-BE-NEXT:    mr r4, r8
+; CHECK-BE-NEXT:    std r4, 0(r6)
+; CHECK-BE-NEXT:    ldat r8, r3, 16
+; CHECK-BE-NEXT:    mr r3, r8
+; CHECK-BE-NEXT:    std r3, 0(r6)
 ; CHECK-BE-NEXT:    blr
 entry:
   %0 = call i64 @llvm.ppc.amo.ldat.csne(ptr %ptr, i64 %value1, i64 %value2)
@@ -188,6 +184,66 @@ entry:
   ret void
 }
 
+define void @test_lwat_csne_ptr_conflict(ptr %input_ptr) nounwind {
+; CHECK-LABEL: test_lwat_csne_ptr_conflict:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    mr r8, r3
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    mr r3, r8
+; CHECK-NEXT:    li r9, 11
+; CHECK-NEXT:    li r10, 22
+; CHECK-NEXT:    lwat r8, r3, 16
+; CHECK-NEXT:    mr r3, r8
+; CHECK-NEXT:    blr
+;
+; CHECK-BE-LABEL: test_lwat_csne_ptr_conflict:
+; CHECK-BE:       # %bb.0: # %entry
+; CHECK-BE-NEXT:    #APP
+; CHECK-BE-NEXT:    mr r8, r3
+; CHECK-BE-NEXT:    #NO_APP
+; CHECK-BE-NEXT:    mr r3, r8
+; CHECK-BE-NEXT:    li r9, 11
+; CHECK-BE-NEXT:    li r10, 22
+; CHECK-BE-NEXT:    lwat r8, r3, 16
+; CHECK-BE-NEXT:    mr r3, r8
+; CHECK-BE-NEXT:    blr
+entry:
+  %ptr = call ptr asm "mr $0, $1", "={r8},{r3}"(ptr %input_ptr)
+  %result = call i32 @llvm.ppc.amo.lwat.csne(ptr %ptr, i32 11, i32 22)
+  ret void
+}
+
+define void @test_ldat_csne_ptr_conflict(ptr %input_ptr) nounwind {
+; CHECK-LABEL: test_ldat_csne_ptr_conflict:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    mr r8, r3
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    mr r3, r8
+; CHECK-NEXT:    li r9, 11
+; CHECK-NEXT:    li r10, 22
+; CHECK-NEXT:    ldat r8, r3, 16
+; CHECK-NEXT:    mr r3, r8
+; CHECK-NEXT:    blr
+;
+; CHECK-BE-LABEL: test_ldat_csne_ptr_conflict:
+; CHECK-BE:       # %bb.0: # %entry
+; CHECK-BE-NEXT:    #APP
+; CHECK-BE-NEXT:    mr r8, r3
+; CHECK-BE-NEXT:    #NO_APP
+; CHECK-BE-NEXT:    mr r3, r8
+; CHECK-BE-NEXT:    li r9, 11
+; CHECK-BE-NEXT:    li r10, 22
+; CHECK-BE-NEXT:    ldat r8, r3, 16
+; CHECK-BE-NEXT:    mr r3, r8
+; CHECK-BE-NEXT:    blr
+entry:
+  %ptr = call ptr asm "mr $0, $1", "={r8},{r3}"(ptr %input_ptr)
+  %result = call i64 @llvm.ppc.amo.ldat.csne(ptr %ptr, i64 11, i64 22)
+  ret void
+}
+
 declare i64 @llvm.ppc.amo.ldat(ptr, i64, i32 immarg)
 declare i32 @llvm.ppc.amo.lwat(ptr, i32, i32 immarg)
 declare i64 @llvm.ppc.amo.ldat.cond(ptr, i32 immarg)



More information about the llvm-commits mailing list