summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorScott Linder <scott@scottlinder.com>2018-07-26 19:47:51 +0000
committerScott Linder <scott@scottlinder.com>2018-07-26 19:47:51 +0000
commiteb1f75d561762123224c17b763f68def84a05715 (patch)
treec179aebdeab30fc69f5db24ff1c9bcb711d9fe32 /llvm/lib/Target
parent6d6eab66e0f76c8bb908492dcc863308b66f7771 (diff)
downloadbcm5719-llvm-eb1f75d561762123224c17b763f68def84a05715.tar.gz
bcm5719-llvm-eb1f75d561762123224c17b763f68def84a05715.zip
[AMDGPU] Fix VGPR spills where offset doesn't fit in 12 bits
Scale the offset of VGPR spills by the wave size when it cannot fit in the 12-bit offset immediate field and so is added to the soffset SGPR. This accounts for hardware swizzling of scratch memory. Differential Revision: https://reviews.llvm.org/D49448 llvm-svn: 338060
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp27
1 files changed, 16 insertions, 11 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 5bfe071c00e..624607f6ea5 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -532,22 +532,29 @@ void SIRegisterInfo::buildSpillLoadStore(MachineBasicBlock::iterator MI,
const DebugLoc &DL = MI->getDebugLoc();
bool IsStore = Desc.mayStore();
- bool RanOutOfSGPRs = false;
bool Scavenged = false;
unsigned SOffset = ScratchOffsetReg;
+ const unsigned EltSize = 4;
const TargetRegisterClass *RC = getRegClassForReg(MF->getRegInfo(), ValueReg);
- unsigned NumSubRegs = AMDGPU::getRegBitWidth(RC->getID()) / 32;
- unsigned Size = NumSubRegs * 4;
+ unsigned NumSubRegs = AMDGPU::getRegBitWidth(RC->getID()) / (EltSize * CHAR_BIT);
+ unsigned Size = NumSubRegs * EltSize;
int64_t Offset = InstOffset + MFI.getObjectOffset(Index);
- const int64_t OriginalImmOffset = Offset;
+ int64_t ScratchOffsetRegDelta = 0;
unsigned Align = MFI.getObjectAlignment(Index);
const MachinePointerInfo &BasePtrInfo = MMO->getPointerInfo();
- if (!isUInt<12>(Offset + Size)) {
+ assert((Offset % EltSize) == 0 && "unexpected VGPR spill offset");
+
+ if (!isUInt<12>(Offset + Size - EltSize)) {
SOffset = AMDGPU::NoRegister;
+ // We currently only support spilling VGPRs to EltSize boundaries, meaning
+ // we can simplify the adjustment of Offset here to just scale with
+ // WavefrontSize.
+ Offset *= ST.getWavefrontSize();
+
// We don't have access to the register scavenger if this function is called
// during PEI::scavengeFrameVirtualRegs().
if (RS)
@@ -561,8 +568,8 @@ void SIRegisterInfo::buildSpillLoadStore(MachineBasicBlock::iterator MI,
// add the offset directly to the ScratchOffset register, and then
// subtract the offset after the spill to return ScratchOffset to it's
// original value.
- RanOutOfSGPRs = true;
SOffset = ScratchOffsetReg;
+ ScratchOffsetRegDelta = Offset;
} else {
Scavenged = true;
}
@@ -574,8 +581,6 @@ void SIRegisterInfo::buildSpillLoadStore(MachineBasicBlock::iterator MI,
Offset = 0;
}
- const unsigned EltSize = 4;
-
for (unsigned i = 0, e = NumSubRegs; i != e; ++i, Offset += EltSize) {
unsigned SubReg = NumSubRegs == 1 ?
ValueReg : getSubReg(ValueReg, getSubRegFromChannel(i));
@@ -607,11 +612,11 @@ void SIRegisterInfo::buildSpillLoadStore(MachineBasicBlock::iterator MI,
MIB.addReg(ValueReg, RegState::Implicit | SrcDstRegState);
}
- if (RanOutOfSGPRs) {
+ if (ScratchOffsetRegDelta != 0) {
// Subtract the offset we added to the ScratchOffset register.
BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_SUB_U32), ScratchOffsetReg)
- .addReg(ScratchOffsetReg)
- .addImm(OriginalImmOffset);
+ .addReg(ScratchOffsetReg)
+ .addImm(ScratchOffsetRegDelta);
}
}
OpenPOWER on IntegriCloud