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

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 15 12:07:54 PDT 2026


Author: Maryam Moghadas
Date: 2026-04-15T15:07:50-04:00
New Revision: 9fb6c65cbb89339f61ce94d25eefa09443ef5eef

URL: https://github.com/llvm/llvm-project/commit/9fb6c65cbb89339f61ce94d25eefa09443ef5eef
DIFF: https://github.com/llvm/llvm-project/commit/9fb6c65cbb89339f61ce94d25eefa09443ef5eef.diff

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

Replace the dummy call lowering with a PPCPostRAExpPseudo that hardcodes
X8/X9/X10 post-RA to satisfy the 3 consecutive register constraint for
lwat/ldat FC=16, addressing reviewer feedback.

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/lib/Target/PowerPC/PPCISelLowering.h
    llvm/lib/Target/PowerPC/PPCInstr64Bit.td
    llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/lib/Target/PowerPC/PPCInstrInfo.h
    llvm/lib/Target/PowerPC/PPCInstrInfo.td
    llvm/test/CodeGen/PowerPC/amo-enable.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index a7389d9bc4fe8..49c54fbae1bf0 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 96c0339603031..ab95213f22c4d 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -11531,49 +11531,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
@@ -12791,7 +12748,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 7077d7fa486e1..afa14ca72ba29 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..282e70f481982 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 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 = [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, 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),
                           "stdcx. $RST, $addr", IIC_LdStSTDCX, []>, isRecordForm;

diff  --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 6d95314d4b019..d458c0005f99b 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,42 @@ bool PPCInstrInfo::areMemAccessesTriviallyDisjoint(
   }
   return false;
 }
+
+// Expands LWAT_CSNE_PSEUDO/LDAT_CSNE_PSEUDO post register allocation.
+// 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 {
+  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 ScratchReg = PtrReg;
+  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::X9, RegState::Implicit)
+      .addReg(PPC::X10, RegState::Implicit);
+
+  if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
+    BuildMI(MBB, MI, DL, get(IsLDAT ? PPC::OR8 : PPC::OR), DstReg)
+        .addReg(IsLDAT ? PPC::X8 : PPC::R8)
+        .addReg(IsLDAT ? PPC::X8 : PPC::R8);
+  }
+  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..b9f1778cd9ac8 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 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 = [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, 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),
                     "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..b4923797b590c 100644
--- a/llvm/test/CodeGen/PowerPC/amo-enable.ll
+++ b/llvm/test/CodeGen/PowerPC/amo-enable.ll
@@ -115,80 +115,132 @@ 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, 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:    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, 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 = 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, 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:    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, 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 = 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
+}
+
+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
 }
 


        


More information about the llvm-commits mailing list