[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