summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp45
-rw-r--r--llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp2
-rw-r--r--llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp12
-rw-r--r--llvm/lib/Target/AMDGPU/SIRegisterInfo.h3
-rw-r--r--llvm/test/CodeGen/AMDGPU/exceed-max-sgprs.ll2
-rw-r--r--llvm/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll13
6 files changed, 50 insertions, 27 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 2390fc9b3db..e711a09ccea 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -489,6 +489,22 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
RI->getHWRegIndex(MFI->getScratchRSrcReg());
}
+ // Check the addressable register limit before we add ExtraSGPRs.
+ if (STM.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
+ !STM.hasSGPRInitBug()) {
+ unsigned MaxAddressableNumSGPRs = STM.getMaxNumSGPRs();
+ if (MaxSGPR + 1 > MaxAddressableNumSGPRs) {
+ // This can happen due to a compiler bug or when using inline asm.
+ LLVMContext &Ctx = MF.getFunction()->getContext();
+ DiagnosticInfoResourceLimit Diag(*MF.getFunction(),
+ "addressable scalar registers",
+ MaxSGPR + 1, DS_Error,
+ DK_ResourceLimit, MaxAddressableNumSGPRs);
+ Ctx.diagnose(Diag);
+ MaxSGPR = MaxAddressableNumSGPRs - 1;
+ }
+ }
+
// Account for extra SGPRs and VGPRs reserved for debugger use.
MaxSGPR += ExtraSGPRs;
MaxVGPR += RI->getNumDebuggerReservedVGPRs(STM);
@@ -505,19 +521,22 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
ProgInfo.NumVGPRsForWavesPerEU = std::max(
ProgInfo.NumVGPR, RI->getMinNumVGPRs(MFI->getMaxWavesPerEU()));
- unsigned MaxNumSGPRs = STM.getMaxNumSGPRs();
- if (ProgInfo.NumSGPR > MaxNumSGPRs) {
- // This can happen due to a compiler bug or when using inline asm to use the
- // registers which are usually reserved for vcc etc.
-
- LLVMContext &Ctx = MF.getFunction()->getContext();
- DiagnosticInfoResourceLimit Diag(*MF.getFunction(),
- "scalar registers",
- ProgInfo.NumSGPR, DS_Error,
- DK_ResourceLimit, MaxNumSGPRs);
- Ctx.diagnose(Diag);
- ProgInfo.NumSGPR = MaxNumSGPRs;
- ProgInfo.NumSGPRsForWavesPerEU = MaxNumSGPRs;
+ if (STM.getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS ||
+ STM.hasSGPRInitBug()) {
+ unsigned MaxNumSGPRs = STM.getMaxNumSGPRs();
+ if (ProgInfo.NumSGPR > MaxNumSGPRs) {
+ // This can happen due to a compiler bug or when using inline asm to use the
+ // registers which are usually reserved for vcc etc.
+
+ LLVMContext &Ctx = MF.getFunction()->getContext();
+ DiagnosticInfoResourceLimit Diag(*MF.getFunction(),
+ "scalar registers",
+ ProgInfo.NumSGPR, DS_Error,
+ DK_ResourceLimit, MaxNumSGPRs);
+ Ctx.diagnose(Diag);
+ ProgInfo.NumSGPR = MaxNumSGPRs;
+ ProgInfo.NumSGPRsForWavesPerEU = MaxNumSGPRs;
+ }
}
if (STM.hasSGPRInitBug()) {
diff --git a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
index 2b04d2033ed..2f88033c807 100644
--- a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
@@ -144,7 +144,7 @@ void GCNMaxOccupancySchedStrategy::pickNodeFromQueue(SchedBoundary &Zone,
unsigned VGPRExcessLimit =
Context->RegClassInfo->getNumAllocatableRegs(&AMDGPU::VGPR_32RegClass);
unsigned MaxWaves = getMaxWaves(SGPRPressure, VGPRPressure, DAG->MF);
- unsigned SGPRCriticalLimit = SRI->getMaxNumSGPRs(ST, MaxWaves);
+ unsigned SGPRCriticalLimit = SRI->getMaxNumSGPRs(ST, MaxWaves, true);
unsigned VGPRCriticalLimit = SRI->getMaxNumVGPRs(MaxWaves);
ReadyQueue &Q = Zone.Available;
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 440ce1b4fc4..bdbce8a9dac 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -1211,14 +1211,15 @@ unsigned SIRegisterInfo::getMinNumSGPRs(const SISubtarget &ST,
}
unsigned SIRegisterInfo::getMaxNumSGPRs(const SISubtarget &ST,
- unsigned WavesPerEU) const {
+ unsigned WavesPerEU,
+ bool Addressable) const {
if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) {
switch (WavesPerEU) {
case 0: return 80;
case 10: return 80;
case 9: return 80;
case 8: return 96;
- default: return getNumAddressableSGPRs(ST);
+ default: return Addressable ? getNumAddressableSGPRs(ST) : 112;
}
} else {
switch (WavesPerEU) {
@@ -1243,7 +1244,8 @@ unsigned SIRegisterInfo::getMaxNumSGPRs(const MachineFunction &MF) const {
// Compute maximum number of SGPRs function can use using default/requested
// minimum number of waves per execution unit.
std::pair<unsigned, unsigned> WavesPerEU = MFI.getWavesPerEU();
- unsigned MaxNumSGPRs = getMaxNumSGPRs(ST, WavesPerEU.first);
+ unsigned MaxNumSGPRs = getMaxNumSGPRs(ST, WavesPerEU.first, false);
+ unsigned MaxNumAddressableSGPRs = getMaxNumSGPRs(ST, WavesPerEU.first, true);
// Check if maximum number of SGPRs was explicitly requested using
// "amdgpu-num-sgpr" attribute.
@@ -1268,7 +1270,7 @@ unsigned SIRegisterInfo::getMaxNumSGPRs(const MachineFunction &MF) const {
// Make sure requested value is compatible with values implied by
// default/requested minimum/maximum number of waves per execution unit.
- if (Requested && Requested > getMaxNumSGPRs(ST, WavesPerEU.first))
+ if (Requested && Requested > getMaxNumSGPRs(ST, WavesPerEU.first, false))
Requested = 0;
if (WavesPerEU.second &&
Requested && Requested < getMinNumSGPRs(ST, WavesPerEU.second))
@@ -1281,7 +1283,7 @@ unsigned SIRegisterInfo::getMaxNumSGPRs(const MachineFunction &MF) const {
if (ST.hasSGPRInitBug())
MaxNumSGPRs = SISubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG;
- return MaxNumSGPRs - getNumReservedSGPRs(ST);
+ return std::min(MaxNumSGPRs - getNumReservedSGPRs(ST), MaxNumAddressableSGPRs);
}
unsigned SIRegisterInfo::getNumDebuggerReservedVGPRs(
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index 477d2322b22..ed2d7b41cc0 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -206,7 +206,8 @@ public:
/// \returns Maximum number of SGPRs that meets given number of waves per
/// execution unit requirement for given subtarget.
- unsigned getMaxNumSGPRs(const SISubtarget &ST, unsigned WavesPerEU) const;
+ unsigned getMaxNumSGPRs(const SISubtarget &ST, unsigned WavesPerEU,
+ bool Addressable) const;
/// \returns Maximum number of SGPRs that meets number of waves per execution
/// unit requirement for function \p MF, or number of SGPRs explicitly
diff --git a/llvm/test/CodeGen/AMDGPU/exceed-max-sgprs.ll b/llvm/test/CodeGen/AMDGPU/exceed-max-sgprs.ll
index 1cb26177ecf..d92efdc6f2d 100644
--- a/llvm/test/CodeGen/AMDGPU/exceed-max-sgprs.ll
+++ b/llvm/test/CodeGen/AMDGPU/exceed-max-sgprs.ll
@@ -76,7 +76,7 @@ define void @use_too_many_sgprs_iceland() #2 {
ret void
}
-; ERROR: error: scalar registers limit of 102 exceeded (103) in use_too_many_sgprs_fiji
+; ERROR: error: addressable scalar registers limit of 102 exceeded (103) in use_too_many_sgprs_fiji
define void @use_too_many_sgprs_fiji() #3 {
call void asm sideeffect "", "~{SGPR0_SGPR1_SGPR2_SGPR3_SGPR4_SGPR5_SGPR6_SGPR7}" ()
call void asm sideeffect "", "~{SGPR8_SGPR9_SGPR10_SGPR11_SGPR12_SGPR13_SGPR14_SGPR15}" ()
diff --git a/llvm/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll b/llvm/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll
index 5d03094bb4f..e9a3a7f3fcf 100644
--- a/llvm/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll
+++ b/llvm/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll
@@ -3,8 +3,9 @@
; Make sure this doesn't crash.
; ALL-LABEL: {{^}}test:
-; ALL: s_mov_b32 s92, SCRATCH_RSRC_DWORD0
-; ALL: s_mov_b32 s91, s3
+; ALL: s_mov_b32 s[[LO:[0-9]+]], SCRATCH_RSRC_DWORD0
+; ALL: s_mov_b32 s[[OFF:[0-9]+]], s3
+; ALL: s_mov_b32 s[[HI:[0-9]+]], 0xe80000
; Make sure we are handling hazards correctly.
; SGPR: buffer_load_dword [[VHI:v[0-9]+]], off, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offset:12
@@ -15,11 +16,11 @@
; Make sure scratch wave offset register is correctly incremented and
; then restored.
-; SMEM: s_mov_b32 m0, s91{{$}}
-; SMEM: s_buffer_store_dwordx4 s{{\[[0-9]+:[0-9]+\]}}, s[92:95], m0 ; 16-byte Folded Spill
+; SMEM: s_mov_b32 m0, s[[OFF]]{{$}}
+; SMEM: s_buffer_store_dwordx4 s{{\[[0-9]+:[0-9]+\]}}, s{{\[}}[[LO]]:[[HI]]], m0 ; 16-byte Folded Spill
-; SMEM: s_mov_b32 m0, s91{{$}}
-; SMEM: s_buffer_load_dwordx4 s{{\[[0-9]+:[0-9]+\]}}, s[92:95], m0 ; 16-byte Folded Reload
+; SMEM: s_mov_b32 m0, s[[OFF]]{{$}}
+; SMEM: s_buffer_load_dwordx4 s{{\[[0-9]+:[0-9]+\]}}, s{{\[}}[[LO]]:[[HI]]], m0 ; 16-byte Folded Reload
; SMEM: s_dcache_wb
; ALL: s_endpgm
OpenPOWER on IntegriCloud