Skip to content

[PowerPC] Add code to spill and restore DMRp registers #142443

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,7 +1926,7 @@ unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
} else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
llvm_unreachable("TODO: Implement spill DMRROWp regclass!");
} else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
llvm_unreachable("TODO: Implement spill DMRp regclass!");
OpcodeIndex = SOK_DMRpSpill;
} else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
OpcodeIndex = SOK_DMRSpill;
} else {
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ enum SpillOpcodeKey {
SOK_AccumulatorSpill,
SOK_UAccumulatorSpill,
SOK_WAccumulatorSpill,
SOK_DMRpSpill,
SOK_DMRSpill,
SOK_SPESpill,
SOK_PairedG8Spill,
Expand Down Expand Up @@ -119,6 +120,7 @@ enum PPCMachineCombinerPattern : unsigned {
NoInstr, \
NoInstr, \
NoInstr, \
NoInstr, \
PPC::EVLDD, \
PPC::RESTORE_QUADWORD}

Expand All @@ -140,6 +142,7 @@ enum PPCMachineCombinerPattern : unsigned {
NoInstr, \
NoInstr, \
NoInstr, \
NoInstr, \
PPC::RESTORE_QUADWORD}

#define Pwr10LoadOpcodes \
Expand All @@ -160,6 +163,7 @@ enum PPCMachineCombinerPattern : unsigned {
NoInstr, \
NoInstr, \
NoInstr, \
NoInstr, \
PPC::RESTORE_QUADWORD}

#define FutureLoadOpcodes \
Expand All @@ -178,6 +182,7 @@ enum PPCMachineCombinerPattern : unsigned {
PPC::RESTORE_ACC, \
PPC::RESTORE_UACC, \
PPC::RESTORE_WACC, \
PPC::RESTORE_DMRP, \
PPC::RESTORE_DMR, \
NoInstr, \
PPC::RESTORE_QUADWORD}
Expand All @@ -199,6 +204,7 @@ enum PPCMachineCombinerPattern : unsigned {
NoInstr, \
NoInstr, \
NoInstr, \
NoInstr, \
PPC::EVSTDD, \
PPC::SPILL_QUADWORD}

Expand All @@ -220,6 +226,7 @@ enum PPCMachineCombinerPattern : unsigned {
NoInstr, \
NoInstr, \
NoInstr, \
NoInstr, \
PPC::SPILL_QUADWORD}

#define Pwr10StoreOpcodes \
Expand All @@ -240,6 +247,7 @@ enum PPCMachineCombinerPattern : unsigned {
NoInstr, \
NoInstr, \
NoInstr, \
NoInstr, \
PPC::SPILL_QUADWORD}

#define FutureStoreOpcodes \
Expand All @@ -258,6 +266,7 @@ enum PPCMachineCombinerPattern : unsigned {
PPC::SPILL_ACC, \
PPC::SPILL_UACC, \
PPC::SPILL_WACC, \
PPC::SPILL_DMRP, \
PPC::SPILL_DMR, \
NoInstr, \
PPC::SPILL_QUADWORD}
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/PowerPC/PPCInstrMMA.td
Original file line number Diff line number Diff line change
Expand Up @@ -565,12 +565,16 @@ let Predicates = [MMA, IsISAFuture], isCodeGenOnly = 1 in {
let mayStore = 1 in {
def SPILL_WACC: PPCEmitTimePseudo<(outs), (ins wacc:$AT, memrix16:$dst),
"#SPILL_WACC", []>;
def SPILL_DMRP: PPCEmitTimePseudo<(outs), (ins dmrp:$AT, memrix16:$dst),
"#SPILL_DMRP", []>;
def SPILL_DMR: PPCEmitTimePseudo<(outs), (ins dmr:$AT, memrix16:$dst),
"#SPILL_DMR", []>;
}
let mayLoad = 1, hasSideEffects = 0 in {
def RESTORE_WACC: PPCEmitTimePseudo<(outs wacc:$AT), (ins memrix16:$src),
"#RESTORE_WACC", []>;
def RESTORE_DMRP: PPCEmitTimePseudo<(outs dmrp:$AT), (ins memrix16:$src),
"#RESTORE_DMRP", []>;
def RESTORE_DMR: PPCEmitTimePseudo<(outs dmr:$AT), (ins memrix16:$src),
"#RESTORE_DMR", []>;
}
Expand Down
107 changes: 55 additions & 52 deletions llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1519,33 +1519,32 @@ void PPCRegisterInfo::lowerDMRSpilling(MachineBasicBlock::iterator II,
// DMR is made up of WACC and WACC_HI, so DMXXEXTFDMR512 to spill
// the corresponding 512 bits.
const TargetRegisterClass *RC = &PPC::VSRpRCRegClass;
Register SrcReg = MI.getOperand(0).getReg();

Register VSRpReg0 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg1 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg2 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg3 = MF.getRegInfo().createVirtualRegister(RC);
auto spillDMR = [&](Register SrcReg, int BEIdx, int LEIdx) {
auto spillWACC = [&](unsigned Opc, unsigned RegIdx, int IdxBE, int IdxLE) {
Register VSRpReg0 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg1 = MF.getRegInfo().createVirtualRegister(RC);

BuildMI(MBB, II, DL, TII.get(Opc), VSRpReg0)
.addDef(VSRpReg1)
.addReg(TargetRegisterInfo::getSubReg(SrcReg, RegIdx));

addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
.addReg(VSRpReg0, RegState::Kill),
FrameIndex, IsLittleEndian ? IdxLE : IdxBE);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
.addReg(VSRpReg1, RegState::Kill),
FrameIndex, IsLittleEndian ? IdxLE - 32 : IdxBE + 32);
};
spillWACC(PPC::DMXXEXTFDMR512, PPC::sub_wacc_lo, BEIdx, LEIdx);
spillWACC(PPC::DMXXEXTFDMR512_HI, PPC::sub_wacc_hi, BEIdx + 64, LEIdx - 64);
};

BuildMI(MBB, II, DL, TII.get(PPC::DMXXEXTFDMR512_HI), VSRpReg2)
.addDef(VSRpReg3)
.addReg(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_wacc_hi));

BuildMI(MBB, II, DL, TII.get(PPC::DMXXEXTFDMR512), VSRpReg0)
.addDef(VSRpReg1)
.addReg(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_wacc_lo));

addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
.addReg(VSRpReg0, RegState::Kill),
FrameIndex, IsLittleEndian ? 96 : 0);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
.addReg(VSRpReg1, RegState::Kill),
FrameIndex, IsLittleEndian ? 64 : 32);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
.addReg(VSRpReg2, RegState::Kill),
FrameIndex, IsLittleEndian ? 32 : 64);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::STXVP))
.addReg(VSRpReg3, RegState::Kill),
FrameIndex, IsLittleEndian ? 0 : 96);
Register SrcReg = MI.getOperand(0).getReg();
if (MI.getOpcode() == PPC::SPILL_DMRP) {
spillDMR(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_dmr1), 0, 96);
spillDMR(TargetRegisterInfo::getSubReg(SrcReg, PPC::sub_dmr0), 128, 224);
} else
spillDMR(SrcReg, 0, 96);

// Discard the pseudo instruction.
MBB.erase(II);
Expand All @@ -1554,7 +1553,7 @@ void PPCRegisterInfo::lowerDMRSpilling(MachineBasicBlock::iterator II,
/// lowerDMRRestore - Generate the code to restore the DMR register.
void PPCRegisterInfo::lowerDMRRestore(MachineBasicBlock::iterator II,
unsigned FrameIndex) const {
MachineInstr &MI = *II; // <DestReg> = RESTORE_WACC <offset>
MachineInstr &MI = *II; // <DestReg> = RESTORE_DMR[P] <offset>
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
Expand All @@ -1563,32 +1562,34 @@ void PPCRegisterInfo::lowerDMRRestore(MachineBasicBlock::iterator II,
bool IsLittleEndian = Subtarget.isLittleEndian();

const TargetRegisterClass *RC = &PPC::VSRpRCRegClass;
Register DestReg = MI.getOperand(0).getReg();

Register VSRpReg0 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg1 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg2 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg3 = MF.getRegInfo().createVirtualRegister(RC);
auto restoreDMR = [&](Register DestReg, int BEIdx, int LEIdx) {
auto restoreWACC = [&](unsigned Opc, unsigned RegIdx, int IdxBE,
int IdxLE) {
Register VSRpReg0 = MF.getRegInfo().createVirtualRegister(RC);
Register VSRpReg1 = MF.getRegInfo().createVirtualRegister(RC);

addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), VSRpReg0),
FrameIndex, IsLittleEndian ? IdxLE : IdxBE);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), VSRpReg1),
FrameIndex, IsLittleEndian ? IdxLE - 32 : IdxBE + 32);

// Kill virtual registers (killedRegState::Killed).
BuildMI(MBB, II, DL, TII.get(Opc),
TargetRegisterInfo::getSubReg(DestReg, RegIdx))
.addReg(VSRpReg0, RegState::Kill)
.addReg(VSRpReg1, RegState::Kill);
};
restoreWACC(PPC::DMXXINSTDMR512, PPC::sub_wacc_lo, BEIdx, LEIdx);
restoreWACC(PPC::DMXXINSTDMR512_HI, PPC::sub_wacc_hi, BEIdx + 64,
LEIdx - 64);
};

addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), VSRpReg0),
FrameIndex, IsLittleEndian ? 96 : 0);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), VSRpReg1),
FrameIndex, IsLittleEndian ? 64 : 32);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), VSRpReg2),
FrameIndex, IsLittleEndian ? 32 : 64);
addFrameReference(BuildMI(MBB, II, DL, TII.get(PPC::LXVP), VSRpReg3),
FrameIndex, IsLittleEndian ? 0 : 96);

// Kill virtual registers (killedRegState::Killed).
BuildMI(MBB, II, DL, TII.get(PPC::DMXXINSTDMR512_HI),
TargetRegisterInfo::getSubReg(DestReg, PPC::sub_wacc_hi))
.addReg(VSRpReg2, RegState::Kill)
.addReg(VSRpReg3, RegState::Kill);

BuildMI(MBB, II, DL, TII.get(PPC::DMXXINSTDMR512),
TargetRegisterInfo::getSubReg(DestReg, PPC::sub_wacc_lo))
.addReg(VSRpReg0, RegState::Kill)
.addReg(VSRpReg1, RegState::Kill);
Register DestReg = MI.getOperand(0).getReg();
if (MI.getOpcode() == PPC::RESTORE_DMRP) {
restoreDMR(TargetRegisterInfo::getSubReg(DestReg, PPC::sub_dmr1), 0, 96);
restoreDMR(TargetRegisterInfo::getSubReg(DestReg, PPC::sub_dmr0), 128, 224);
} else
restoreDMR(DestReg, 0, 96);

// Discard the pseudo instruction.
MBB.erase(II);
Expand Down Expand Up @@ -1756,9 +1757,11 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
case PPC::RESTORE_WACC:
lowerWACCRestore(II, FrameIndex);
return true;
case PPC::SPILL_DMRP:
case PPC::SPILL_DMR:
lowerDMRSpilling(II, FrameIndex);
return true;
case PPC::RESTORE_DMRP:
case PPC::RESTORE_DMR:
lowerDMRRestore(II, FrameIndex);
return true;
Expand Down
36 changes: 18 additions & 18 deletions llvm/test/CodeGen/PowerPC/dmr-spill.ll
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ define void @spillDMRreg(ptr %vop, ptr %vpp, ptr %vcp, ptr %resp) nounwind {
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv vs0, 0(r5)
; CHECK-NEXT: dmxvbf16gerx2pp dmr0, vsp34, vs0
; CHECK-NEXT: dmxxextfdmr512 vsp36, vsp34, wacc0, 0
; CHECK-NEXT: stxvp vsp36, 128(r1)
; CHECK-NEXT: stxvp vsp34, 96(r1)
; CHECK-NEXT: dmxxextfdmr512 vsp36, vsp34, wacc_hi0, 1
; CHECK-NEXT: dmxxextfdmr512 vsp38, vsp32, wacc0, 0
; CHECK-NEXT: stxvp vsp38, 128(r1)
; CHECK-NEXT: stxvp vsp32, 96(r1)
; CHECK-NEXT: stxvp vsp36, 64(r1)
; CHECK-NEXT: stxvp vsp34, 32(r1)
; CHECK-NEXT: bl dummy_func@notoc
; CHECK-NEXT: lxvp vsp34, 128(r1)
; CHECK-NEXT: lxvp vsp36, 96(r1)
; CHECK-NEXT: lxvp vsp32, 64(r1)
; CHECK-NEXT: lxvp vsp38, 32(r1)
; CHECK-NEXT: dmxxinstdmr512 wacc_hi0, vsp32, vsp38, 1
; CHECK-NEXT: dmxxinstdmr512 wacc0, vsp34, vsp36, 0
; CHECK-NEXT: lxvp vsp34, 64(r1)
; CHECK-NEXT: lxvp vsp36, 32(r1)
; CHECK-NEXT: dmxxinstdmr512 wacc_hi0, vsp34, vsp36, 1
; CHECK-NEXT: dmxxextfdmr512 vsp34, vsp36, wacc0, 0
; CHECK-NEXT: stxvp vsp34, 96(r30)
; CHECK-NEXT: stxvp vsp36, 64(r30)
Expand Down Expand Up @@ -72,20 +72,20 @@ define void @spillDMRreg(ptr %vop, ptr %vpp, ptr %vcp, ptr %resp) nounwind {
; AIX-NEXT: lxv v3, 16(r4)
; AIX-NEXT: lxv vs0, 0(r5)
; AIX-NEXT: dmxvbf16gerx2pp dmr0, vsp34, vs0
; AIX-NEXT: dmxxextfdmr512 vsp36, vsp34, wacc0, 0
; AIX-NEXT: stxvp vsp36, 112(r1)
; AIX-NEXT: stxvp vsp34, 144(r1)
; AIX-NEXT: dmxxextfdmr512 vsp36, vsp34, wacc_hi0, 1
; AIX-NEXT: dmxxextfdmr512 vsp38, vsp32, wacc0, 0
; AIX-NEXT: stxvp vsp38, 112(r1)
; AIX-NEXT: stxvp vsp32, 144(r1)
; AIX-NEXT: stxvp vsp36, 176(r1)
; AIX-NEXT: stxvp vsp34, 208(r1)
; AIX-NEXT: bl .dummy_func[PR]
; AIX-NEXT: nop
; AIX-NEXT: lxvp vsp34, 112(r1)
; AIX-NEXT: lxvp vsp36, 144(r1)
; AIX-NEXT: lxvp vsp32, 176(r1)
; AIX-NEXT: lxvp vsp38, 208(r1)
; AIX-NEXT: dmxxinstdmr512 wacc_hi0, vsp32, vsp38, 1
; AIX-NEXT: dmxxinstdmr512 wacc0, vsp34, vsp36, 0
; AIX-NEXT: lxvp vsp34, 176(r1)
; AIX-NEXT: lxvp vsp36, 208(r1)
; AIX-NEXT: dmxxinstdmr512 wacc_hi0, vsp34, vsp36, 1
; AIX-NEXT: dmxxextfdmr512 vsp34, vsp36, wacc_hi0, 1
; AIX-NEXT: stxvp vsp36, 96(r31)
; AIX-NEXT: stxvp vsp34, 64(r31)
Expand Down Expand Up @@ -115,20 +115,20 @@ define void @spillDMRreg(ptr %vop, ptr %vpp, ptr %vcp, ptr %resp) nounwind {
; AIX32-NEXT: lxv v3, 16(r4)
; AIX32-NEXT: lxv vs0, 0(r5)
; AIX32-NEXT: dmxvbf16gerx2pp dmr0, vsp34, vs0
; AIX32-NEXT: dmxxextfdmr512 vsp36, vsp34, wacc0, 0
; AIX32-NEXT: stxvp vsp36, 64(r1)
; AIX32-NEXT: stxvp vsp34, 96(r1)
; AIX32-NEXT: dmxxextfdmr512 vsp36, vsp34, wacc_hi0, 1
; AIX32-NEXT: dmxxextfdmr512 vsp38, vsp32, wacc0, 0
; AIX32-NEXT: stxvp vsp38, 64(r1)
; AIX32-NEXT: stxvp vsp32, 96(r1)
; AIX32-NEXT: stxvp vsp36, 128(r1)
; AIX32-NEXT: stxvp vsp34, 160(r1)
; AIX32-NEXT: bl .dummy_func[PR]
; AIX32-NEXT: nop
; AIX32-NEXT: lxvp vsp34, 64(r1)
; AIX32-NEXT: lxvp vsp36, 96(r1)
; AIX32-NEXT: lxvp vsp32, 128(r1)
; AIX32-NEXT: lxvp vsp38, 160(r1)
; AIX32-NEXT: dmxxinstdmr512 wacc_hi0, vsp32, vsp38, 1
; AIX32-NEXT: dmxxinstdmr512 wacc0, vsp34, vsp36, 0
; AIX32-NEXT: lxvp vsp34, 128(r1)
; AIX32-NEXT: lxvp vsp36, 160(r1)
; AIX32-NEXT: dmxxinstdmr512 wacc_hi0, vsp34, vsp36, 1
; AIX32-NEXT: dmxxextfdmr512 vsp34, vsp36, wacc_hi0, 1
; AIX32-NEXT: stxvp vsp36, 96(r31)
; AIX32-NEXT: stxvp vsp34, 64(r31)
Expand Down
Loading
Loading