From: Marek Olsak Date: Fri, 9 Dec 2016 19:49:40 +0000 (+0000) Subject: AMDGPU/SI: Allow using SGPRs 96-101 on VI X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ee082f5e522e44330e36c65b60f0e316eff77784;p=llvm AMDGPU/SI: Allow using SGPRs 96-101 on VI Summary: There is no point in setting SGPRS=104, because VI allocates SGPRs in multiples of 16, so 104 -> 112. That enables us to use all 102 SGPRs for general purposes. Reviewers: tstellarAMD Subscribers: qcolombet, arsenm, kzhuravl, wdng, nhaehnle, yaxunl, tony-tye Differential Revision: https://reviews.llvm.org/D27149 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289260 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp index 2390fc9b3db..e711a09ccea 100644 --- a/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ b/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/lib/Target/AMDGPU/GCNSchedStrategy.cpp b/lib/Target/AMDGPU/GCNSchedStrategy.cpp index 2b04d2033ed..2f88033c807 100644 --- a/lib/Target/AMDGPU/GCNSchedStrategy.cpp +++ b/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/lib/Target/AMDGPU/SIRegisterInfo.cpp b/lib/Target/AMDGPU/SIRegisterInfo.cpp index 440ce1b4fc4..bdbce8a9dac 100644 --- a/lib/Target/AMDGPU/SIRegisterInfo.cpp +++ b/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 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/lib/Target/AMDGPU/SIRegisterInfo.h b/lib/Target/AMDGPU/SIRegisterInfo.h index 477d2322b22..ed2d7b41cc0 100644 --- a/lib/Target/AMDGPU/SIRegisterInfo.h +++ b/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/test/CodeGen/AMDGPU/exceed-max-sgprs.ll b/test/CodeGen/AMDGPU/exceed-max-sgprs.ll index 1cb26177ecf..d92efdc6f2d 100644 --- a/test/CodeGen/AMDGPU/exceed-max-sgprs.ll +++ b/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/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll b/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll index 5d03094bb4f..e9a3a7f3fcf 100644 --- a/test/CodeGen/AMDGPU/si-spill-sgpr-stack.ll +++ b/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