[llvm] bd85a10 - [AMDGPU] Do not propagate vgpr count in dVGPR mode (#187078)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 06:39:03 PDT 2026
Author: Mirko BrkuĊĦanin
Date: 2026-06-02T15:38:57+02:00
New Revision: bd85a10b0cbfde6e944da773c435b8006130848f
URL: https://github.com/llvm/llvm-project/commit/bd85a10b0cbfde6e944da773c435b8006130848f
DIFF: https://github.com/llvm/llvm-project/commit/bd85a10b0cbfde6e944da773c435b8006130848f.diff
LOG: [AMDGPU] Do not propagate vgpr count in dVGPR mode (#187078)
When dVGPR mode is enabled chain functions should not propagate VGPR
counts from other chain callees. VGPRs are allocated before chaining to
a chain functions. We only propagate counts from non-chain callees.
Added:
llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-direct-chain.ll
llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-indirect.ll
llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation.ll
Modified:
llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.h
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16.ll
llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16_anon.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index f1c015312d9a7..d32cdb6d960fc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -1131,28 +1131,47 @@ void AMDGPUAsmPrinter::emitDVgprSymbol(MachineFunction &MF) {
MF.getFunction().getCallingConv() == CallingConv::AMDGPU_CS_Chain) {
MCContext &Ctx = MF.getContext();
unsigned BlockSize = MFI.getDynamicVGPRBlockSize();
+
+ const MCExpr *EncodedBlocks;
MCValue NumVGPRs;
- if (!CurrentProgramInfo.NumVGPRsForWavesPerEU->evaluateAsRelocatable(
- NumVGPRs, nullptr) ||
- !NumVGPRs.isAbsolute()) {
- llvm_unreachable("unable to resolve NumVGPRs for _dvgpr$ symbol");
+ if (CurrentProgramInfo.NumVGPRsForWavesPerEU->evaluateAsRelocatable(
+ NumVGPRs, nullptr) &&
+ NumVGPRs.isAbsolute()) {
+
+ // Calculate number of VGPR blocks.
+ // Treat 0 VGPRs as 1 VGPR to avoid underflowing.
+ unsigned NumBlocks =
+ divideCeil(std::max(unsigned(NumVGPRs.getConstant()), 1U), BlockSize);
+
+ if (NumBlocks > AMDGPU::IsaInfo::MaxDynamicVGPRBlocks) {
+ OutContext.reportError(
+ {}, "DVGPR block count " + Twine(NumBlocks) +
+ " exceeds maximum of " +
+ Twine(AMDGPU::IsaInfo::MaxDynamicVGPRBlocks) +
+ " for __dvgpr$ symbol for '" +
+ Twine(CurrentFnSym->getName()) + "'");
+ return;
+ }
+ unsigned EncodedNumBlocks = (NumBlocks - 1) << 3;
+ EncodedBlocks = MCConstantExpr::create(EncodedNumBlocks, Ctx);
+ } else {
+ // Value not yet available so build a symbolic MCExpr:
+ // ((alignTo(max(NumVGPRs, 1), BlockSize) / BlockSize - 1) << 3
+ const MCExpr *One = MCConstantExpr::create(1, Ctx);
+ const MCExpr *BlockSizeConst = MCConstantExpr::create(BlockSize, Ctx);
+ const MCExpr *MaxVGPRs = AMDGPUMCExpr::createMax(
+ {CurrentProgramInfo.NumVGPRsForWavesPerEU, One}, Ctx);
+ const MCExpr *NumBlocks = MCBinaryExpr::createDiv(
+ AMDGPUMCExpr::createAlignTo(MaxVGPRs, BlockSizeConst, Ctx),
+ BlockSizeConst, Ctx);
+ EncodedBlocks =
+ MCBinaryExpr::createShl(MCBinaryExpr::createSub(NumBlocks, One, Ctx),
+ MCConstantExpr::create(3, Ctx), Ctx);
}
- // Calculate number of VGPR blocks.
- // Treat 0 VGPRs as 1 VGPR to avoid underflowing.
- unsigned NumBlocks =
- divideCeil(std::max(unsigned(NumVGPRs.getConstant()), 1U), BlockSize);
- if (NumBlocks > 8) {
- OutContext.reportError({},
- "too many DVGPR blocks for _dvgpr$ symbol for '" +
- Twine(CurrentFnSym->getName()) + "'");
- return;
- }
- unsigned EncodedNumBlocks = (NumBlocks - 1) << 3;
// Add to function symbol to create _dvgpr$ symbol.
const MCExpr *DVgprFuncVal = MCBinaryExpr::createAdd(
- MCSymbolRefExpr::create(CurrentFnSym, Ctx),
- MCConstantExpr::create(EncodedNumBlocks, Ctx), Ctx);
+ MCSymbolRefExpr::create(CurrentFnSym, Ctx), EncodedBlocks, Ctx);
MCSymbol *DVgprFuncSym =
Ctx.getOrCreateSymbol(Twine("_dvgpr$") + CurrentFnSym->getName());
OutStreamer->emitAssignment(DVgprFuncSym, DVgprFuncVal);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
index 2d43019a8d66b..1731b0463a099 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "AMDGPUMCResourceInfo.h"
-#include "AMDGPUTargetMachine.h"
+#include "SIMachineFunctionInfo.h"
#include "Utils/AMDGPUBaseInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -256,8 +256,14 @@ void MCResourceInfo::gatherResourceInfo(
MCSymbol *MaxSGPRSym = getMaxSGPRSymbol(OutContext);
MCSymbol *MaxNamedBarrierSym = getMaxNamedBarrierSymbol(OutContext);
- if (!AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv())) {
- addMaxVGPRCandidate(FRI.NumVGPR);
+ CallingConv::ID CC = MF.getFunction().getCallingConv();
+ bool IsChainCC = AMDGPU::isChainCC(CC);
+ bool IsDynamicVGPREnabled =
+ MF.getInfo<SIMachineFunctionInfo>()->isDynamicVGPREnabled();
+
+ if (!AMDGPU::isEntryFunctionCC(CC)) {
+ if (!IsDynamicVGPREnabled || !IsChainCC)
+ addMaxVGPRCandidate(FRI.NumVGPR);
addMaxAGPRCandidate(FRI.NumAGPR);
addMaxSGPRCandidate(FRI.NumExplicitSGPR);
addMaxNamedBarrierCandidate(FRI.NumNamedBarrier);
@@ -319,8 +325,31 @@ void MCResourceInfo::gatherResourceInfo(
};
LLVM_DEBUG(dbgs() << "MCResUse: " << FnSym->getName() << '\n');
- SetMaxReg(MaxVGPRSym, FRI.NumVGPR, RIK_NumVGPR);
- SetMaxReg(MaxAGPRSym, FRI.NumAGPR, RIK_NumAGPR);
+
+ // When DynamicVGPR is enabled, chain functions should not propagate VGPR
+ // counts from other chain callees since each chain function can have its own
+ // VGPR allocation, but should still propagate from non-chain callees.
+ if (IsDynamicVGPREnabled && (IsChainCC || CC == CallingConv::AMDGPU_CS)) {
+ if (FRI.HasNonChainIndirectCall) {
+ // Has indirect calls to non-chain functions. Use max of local count and
+ // module-wide non-chain maximum.
+ MCSymbol *Sym = getSymbol(FnSym->getName(), RIK_NumVGPR, OutContext);
+ Sym->setVariableValue(AMDGPUMCExpr::createMax(
+ {MCConstantExpr::create(FRI.NumVGPR, OutContext),
+ MCSymbolRefExpr::create(MaxVGPRSym, OutContext)},
+ OutContext));
+ SetMaxReg(MaxAGPRSym, FRI.NumAGPR, RIK_NumAGPR);
+ } else {
+ // No indirect calls to non-chain functions. Propagate from direct callees
+ assignResourceInfoExpr(FRI.NumVGPR, RIK_NumVGPR, AMDGPUMCExpr::AGVK_Max,
+ MF, FRI.Callees, OutContext);
+ assignResourceInfoExpr(FRI.NumAGPR, RIK_NumAGPR, AMDGPUMCExpr::AGVK_Max,
+ MF, FRI.Callees, OutContext);
+ }
+ } else {
+ SetMaxReg(MaxVGPRSym, FRI.NumVGPR, RIK_NumVGPR);
+ SetMaxReg(MaxAGPRSym, FRI.NumAGPR, RIK_NumAGPR);
+ }
SetMaxReg(MaxSGPRSym, FRI.NumExplicitSGPR, RIK_NumSGPR);
SetMaxReg(MaxNamedBarrierSym, FRI.NumNamedBarrier, RIK_NumNamedBarrier);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp b/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
index 09d59664f8dd4..aab43f23cf606 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
@@ -275,6 +275,9 @@ AMDGPUResourceUsageAnalysisImpl::analyzeResourceUsage(
bool IsIndirect = !Callee || Callee->isDeclaration();
Info.HasIndirectCall |= IsIndirect;
+ bool IsChainCall = MI.getOpcode() == AMDGPU::SI_TCRETURN_CHAIN;
+ Info.HasNonChainIndirectCall |= (!IsChainCall && IsIndirect);
+
// In object linking mode the linker has the full cross-TU view. It
// propagates resource usage across both direct calls to external
// declarations and true indirect calls. Skip the compile-time
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.h b/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.h
index 9ae3bb3ca048e..2e0a447ebe5c4 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.h
@@ -43,6 +43,7 @@ struct AMDGPUResourceUsageAnalysisImpl {
bool HasDynamicallySizedStack = false;
bool HasRecursion = false;
bool HasIndirectCall = false;
+ bool HasNonChainIndirectCall = false;
SmallVector<const Function *, 16> Callees;
};
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 9954c14a0851d..33df51e8a7e07 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1473,9 +1473,11 @@ unsigned getAddressableNumVGPRs(const MCSubtargetInfo &STI,
if (Features.test(FeatureGFX90AInsts))
return 512;
- if (DynamicVGPRBlockSize != 0)
- // On GFX12 we can allocate at most 8 blocks of VGPRs.
- return 8 * getVGPRAllocGranule(STI, DynamicVGPRBlockSize);
+ if (DynamicVGPRBlockSize != 0) {
+ // On GFX12 we can allocate at most MaxDynamicVGPRBlocks blocks of VGPRs.
+ return MaxDynamicVGPRBlocks *
+ getVGPRAllocGranule(STI, DynamicVGPRBlockSize);
+ }
return getAddressableNumArchVGPRs(STI);
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index d761da4d0d804..1f7084c8d25ae 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -342,6 +342,9 @@ unsigned getArchVGPRAllocGranule();
/// \returns Total number of VGPRs for given subtarget \p STI.
unsigned getTotalNumVGPRs(const MCSubtargetInfo &STI);
+/// Maximum number of VGPR blocks that can be allocated in dynamic VGPR mode.
+static constexpr unsigned MaxDynamicVGPRBlocks = 8;
+
/// \returns Addressable number of architectural VGPRs for a given subtarget \p
/// STI.
unsigned getAddressableNumArchVGPRs(const MCSubtargetInfo &STI);
diff --git a/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-direct-chain.ll b/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-direct-chain.ll
new file mode 100644
index 0000000000000..7b01eec2698c3
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-direct-chain.ll
@@ -0,0 +1,128 @@
+; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 < %s | FileCheck -check-prefix=DVGPR %s
+; RUN: sed 's/"amdgpu-dynamic-vgpr-block-size"="16"/"amdgpu-dynamic-vgpr-block-size"="0"/' %s \
+; RUN: | llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 | FileCheck -check-prefix=NODVGPR %s
+
+; Test a set of functions with mixed use of DVGPR (enabled or disabled). Also
+; test chain functions directly calling other chain functions without going
+; through `first_retry_wrapper` helper. A chain function will not propagate VGPR
+; counts to a directly called chain function, regardless of whether either has
+; DVGPRs enabled or disabled.
+
+; func.2 and func.4 have DVGPRs disabled
+
+; DVGPR: .set .Lgfx_func_a.num_vgpr, 40
+; DVGPR: .set .Lamdgpu_cs_main.num_vgpr, max(42, .Lgfx_func_a.num_vgpr)
+; DVGPR: .set .Lfunc.0.num_vgpr, max(11, .Lgfx_func_a.num_vgpr)
+; DVGPR: .set .Lfunc.1.num_vgpr, 82
+; DVGPR: .set .Lfunc.2.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; DVGPR: .set .Lfunc.3.num_vgpr, 11
+; DVGPR: .set .Lfunc.4.num_vgpr, max(82, amdgpu.max_num_vgpr)
+; DVGPR: .set .Lretry_vgpr_alloc.num_vgpr, 11
+; DVGPR: .set .Lfirst_retry_wrapper.num_vgpr, 11
+; DVGPR: .set amdgpu.max_num_vgpr, 82
+
+; NODVGPR: .set .Lgfx_func_a.num_vgpr, 40
+; NODVGPR: .set .Lamdgpu_cs_main.num_vgpr, max(42, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.0.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.1.num_vgpr, max(82, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.2.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.3.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.4.num_vgpr, max(82, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lretry_vgpr_alloc.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfirst_retry_wrapper.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set amdgpu.max_num_vgpr, 82
+
+; DVGPR: - .hardware_stages:
+; DVGPR: .vgpr_count: 0x2a
+; DVGPR: .shader_functions:
+; DVGPR: func.0:
+; DVGPR: .vgpr_count: 0x28
+; DVGPR: func.1:
+; DVGPR: .vgpr_count: 0x52
+; DVGPR: func.2:
+; DVGPR: .vgpr_count: 0x52
+; DVGPR: func.3:
+; DVGPR: .vgpr_count: 0xb
+; DVGPR: func.4:
+; DVGPR: .vgpr_count: 0x52
+; DVGPR: gfx_func_a:
+; DVGPR: .vgpr_count: 0x28
+
+; NODVGPR: - .hardware_stages:
+; NODVGPR: .vgpr_count: 0x52
+; NODVGPR: .shader_functions:
+; NODVGPR: func.0:
+; NODVGPR: .vgpr_count: 0x52
+; NODVGPR: func.1:
+; NODVGPR: .vgpr_count: 0x52
+; NODVGPR: func.2:
+; NODVGPR: .vgpr_count: 0x52
+; NODVGPR: func.3:
+; NODVGPR: .vgpr_count: 0x52
+; NODVGPR: func.4:
+; NODVGPR: .vgpr_count: 0x52
+; NODVGPR: gfx_func_a:
+; NODVGPR: .vgpr_count: 0x28
+
+define amdgpu_gfx void @gfx_func_a() #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"()
+ ret void
+}
+
+define amdgpu_cs void @amdgpu_cs_main(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call amdgpu_gfx void @gfx_func_a()
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func.1)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func.0(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call amdgpu_gfx void @gfx_func_a()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+; Has direct chain call to func.2 instead of using first_retry_wrapper
+define amdgpu_cs_chain void @func.1(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39},~{v40},~{v41},~{v42},~{v43},~{v44},~{v45},~{v46},~{v47},~{v48},~{v49},~{v50},~{v51},~{v52},~{v53},~{v54},~{v55},~{v56},~{v57},~{v58},~{v59},~{v60},~{v61},~{v62},~{v63},~{v64},~{v65},~{v66},~{v67},~{v68},~{v69},~{v70},~{v71},~{v72},~{v73},~{v74},~{v75},~{v76},~{v77},~{v78},~{v79}"()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func.2)
+ unreachable
+}
+
+; amdgpu-dynamic-vgpr-block-size = 0
+define amdgpu_cs_chain void @func.2(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #1 {
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+; Has direct chain call to func.4 instead of using first_retry_wrapper
+define amdgpu_cs_chain void @func.3(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func.4)
+ unreachable
+}
+
+; amdgpu-dynamic-vgpr-block-size = 0
+define amdgpu_cs_chain void @func.4(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #1 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39},~{v40},~{v41},~{v42},~{v43},~{v44},~{v45},~{v46},~{v47},~{v48},~{v49},~{v50},~{v51},~{v52},~{v53},~{v54},~{v55},~{v56},~{v57},~{v58},~{v59},~{v60},~{v61},~{v62},~{v63},~{v64},~{v65},~{v66},~{v67},~{v68},~{v69},~{v70},~{v71},~{v72},~{v73},~{v74},~{v75},~{v76},~{v77},~{v78},~{v79}"()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+define amdgpu_cs_chain_preserve void @retry_vgpr_alloc(<3 x i32> inreg %sgprs) #0 {
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @retry_vgpr_alloc)
+ unreachable
+}
+
+define amdgpu_cs_chain_preserve void @first_retry_wrapper(<3 x i32> inreg %sgprs) #0 {
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg @retry_vgpr_alloc, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @retry_vgpr_alloc)
+ unreachable
+}
+
+attributes #0 = { "amdgpu-dynamic-vgpr-block-size"="16" }
+attributes #1 = { "amdgpu-dynamic-vgpr-block-size"="0" }
diff --git a/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-indirect.ll b/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-indirect.ll
new file mode 100644
index 0000000000000..f9cf887ac668b
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation-indirect.ll
@@ -0,0 +1,59 @@
+; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 < %s | FileCheck -check-prefix=DVGPR %s
+; RUN: sed 's/"amdgpu-dynamic-vgpr-block-size"="16"/"amdgpu-dynamic-vgpr-block-size"="0"/' %s \
+; RUN: | llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 | FileCheck -check-prefix=NODVGPR %s
+
+; In DVGPR mode, chain functions that have indirect non-chain calls should have
+; their `num_vgpr` count set to the max of their local count and the module-wide
+; max VGPR count of all non-chain functions.
+
+; DVGPR: .set .Lgfx_func_a.num_vgpr, 40
+; DVGPR: .set .Lgfx_func_b.num_vgpr, 80
+; DVGPR: .set .Lfunc_with_indirect_call.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; DVGPR: .set .Lfunc_direct_only.num_vgpr, max(11, .Lgfx_func_a.num_vgpr)
+; DVGPR: .set .Lfunc_chain_only.num_vgpr, 11
+; DVGPR: .set amdgpu.max_num_vgpr, 80
+
+; NODVGPR: .set .Lgfx_func_a.num_vgpr, 40
+; NODVGPR: .set .Lgfx_func_b.num_vgpr, 80
+; NODVGPR: .set .Lfunc_with_indirect_call.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc_direct_only.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc_chain_only.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set amdgpu.max_num_vgpr, 80
+
+define amdgpu_gfx void @gfx_func_a() #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"()
+ ret void
+}
+
+define amdgpu_gfx void @gfx_func_b() #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39},~{v40},~{v41},~{v42},~{v43},~{v44},~{v45},~{v46},~{v47},~{v48},~{v49},~{v50},~{v51},~{v52},~{v53},~{v54},~{v55},~{v56},~{v57},~{v58},~{v59},~{v60},~{v61},~{v62},~{v63},~{v64},~{v65},~{v66},~{v67},~{v68},~{v69},~{v70},~{v71},~{v72},~{v73},~{v74},~{v75},~{v76},~{v77},~{v78},~{v79}"()
+ ret void
+}
+
+define amdgpu_cs_chain void @func_with_indirect_call(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2}"()
+ call amdgpu_gfx void @gfx_func_a()
+ %fptr_gfx = load ptr, ptr inttoptr(i64 8 to ptr)
+ call amdgpu_gfx void %fptr_gfx()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func_chain_only)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func_direct_only(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3}"()
+ call amdgpu_gfx void @gfx_func_a()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func_chain_only)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func_chain_only(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4}"()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func_chain_only)
+ unreachable
+}
+
+declare void @llvm.amdgcn.cs.chain.v3i32(ptr, i32, <3 x i32>, <3 x i32>, i32 immarg, ...)
+attributes #0 = { "amdgpu-dynamic-vgpr-block-size"="16" }
diff --git a/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation.ll b/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation.ll
new file mode 100644
index 0000000000000..7001e23f7002d
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/dvgpr-vgpr-count-propagation.ll
@@ -0,0 +1,154 @@
+; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 < %s | FileCheck -check-prefix=DVGPR %s
+; RUN: sed 's/"amdgpu-dynamic-vgpr-block-size"="16"/"amdgpu-dynamic-vgpr-block-size"="0"/' %s \
+; RUN: | llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx1200 | FileCheck -check-prefix=NODVGPR %s
+
+; Chain calls are treated as indirect calls, but with dynamic VGPRs enabled each
+; function will get its own VGPR allocation. Chain functions that have no
+; indirect non-chain calls should have their num_vgpr count set to the max of
+; their local count and the counts of all direct callees.
+
+; With DVGPRs enabled "max_num_vgpr" represents the maximum VGPR count of all
+; non-chain functions. With DVGPRs disabled, it represents module-wide max VGPR
+; count.
+
+; DVGPR: .set .Lgfx_func_a.num_vgpr, 40
+; DVGPR: .set .Lgfx_func_b2.num_vgpr, 80
+; DVGPR: .set .Lgfx_func_b.num_vgpr, max(61, .Lgfx_func_b2.num_vgpr)
+; DVGPR: .set .Lamdgpu_cs_main.num_vgpr, max(42, .Lgfx_func_a.num_vgpr)
+; DVGPR: .set .Lfunc.0.num_vgpr, 13
+; DVGPR: .set .Lfunc.1.num_vgpr, max(14, .Lgfx_func_a.num_vgpr, .Lgfx_func_b.num_vgpr)
+; DVGPR: .set .Lfunc.2.num_vgpr, max(16, .Lgfx_func_a.num_vgpr)
+; DVGPR: .set .Lfunc.3.num_vgpr, max(15, .Lgfx_func_b.num_vgpr)
+; DVGPR: .set .Lfunc.4.num_vgpr, max(100, .Lgfx_func_b.num_vgpr)
+; DVGPR: .set .Lretry_vgpr_alloc.num_vgpr, 11
+; DVGPR: .set .Lfirst_retry_wrapper.num_vgpr, 11
+; DVGPR: .set amdgpu.max_num_vgpr, 80
+
+; NODVGPR: .set .Lgfx_func_a.num_vgpr, 40
+; NODVGPR: .set .Lgfx_func_b2.num_vgpr, 80
+; NODVGPR: .set .Lgfx_func_b.num_vgpr, max(61, .Lgfx_func_b2.num_vgpr)
+; NODVGPR: .set .Lamdgpu_cs_main.num_vgpr, max(42, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.0.num_vgpr, max(13, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.1.num_vgpr, max(14, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.2.num_vgpr, max(16, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.3.num_vgpr, max(15, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfunc.4.num_vgpr, max(100, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lretry_vgpr_alloc.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set .Lfirst_retry_wrapper.num_vgpr, max(11, amdgpu.max_num_vgpr)
+; NODVGPR: .set amdgpu.max_num_vgpr, 100
+
+; DVGPR: - .hardware_stages:
+; DVGPR: .vgpr_count: 0x2a
+; DVGPR: .shader_functions:
+; DVGPR: func.0:
+; DVGPR: .vgpr_count: 0xd
+; DVGPR: func.1:
+; DVGPR: .vgpr_count: 0x50
+; DVGPR: func.2:
+; DVGPR: .vgpr_count: 0x28
+; DVGPR: func.3:
+; DVGPR: .vgpr_count: 0x50
+; DVGPR: func.4:
+; DVGPR: .vgpr_count: 0x64
+; DVGPR: gfx_func_a:
+; DVGPR: .vgpr_count: 0x28
+; DVGPR: gfx_func_b:
+; DVGPR: .vgpr_count: 0x50
+; DVGPR: gfx_func_b2:
+; DVGPR: .vgpr_count: 0x50
+
+; NODVGPR: - .hardware_stages:
+; NODVGPR: .vgpr_count: 0x64
+; NODVGPR: .shader_functions:
+; NODVGPR: func.0:
+; NODVGPR: .vgpr_count: 0x64
+; NODVGPR: func.1:
+; NODVGPR: .vgpr_count: 0x64
+; NODVGPR: func.2:
+; NODVGPR: .vgpr_count: 0x64
+; NODVGPR: func.3:
+; NODVGPR: .vgpr_count: 0x64
+; NODVGPR: func.4:
+; NODVGPR: .vgpr_count: 0x64
+; NODVGPR: gfx_func_a:
+; NODVGPR: .vgpr_count: 0x28
+; NODVGPR: gfx_func_b:
+; NODVGPR: .vgpr_count: 0x50
+; NODVGPR: gfx_func_b2:
+; NODVGPR: .vgpr_count: 0x50
+
+define amdgpu_gfx void @gfx_func_a() #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39}"()
+ ret void
+}
+
+define amdgpu_gfx void @gfx_func_b2() #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39},~{v40},~{v41},~{v42},~{v43},~{v44},~{v45},~{v46},~{v47},~{v48},~{v49},~{v50},~{v51},~{v52},~{v53},~{v54},~{v55},~{v56},~{v57},~{v58},~{v59},~{v60},~{v61},~{v62},~{v63},~{v64},~{v65},~{v66},~{v67},~{v68},~{v69},~{v70},~{v71},~{v72},~{v73},~{v74},~{v75},~{v76},~{v77},~{v78},~{v79}"()
+ ret void
+}
+
+define amdgpu_gfx void @gfx_func_b() #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39},~{v40},~{v41},~{v42},~{v43},~{v44},~{v45},~{v46},~{v47},~{v48},~{v49},~{v50},~{v51},~{v52},~{v53},~{v54},~{v55},~{v56},~{v57},~{v58},~{v59}"()
+ call amdgpu_gfx void @gfx_func_b2()
+ ret void
+}
+
+define amdgpu_cs void @amdgpu_cs_main(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call amdgpu_gfx void @gfx_func_a()
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @func.1)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func.0(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10}"()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func.1(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13}"()
+ call amdgpu_gfx void @gfx_func_a()
+ call amdgpu_gfx void @gfx_func_b()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func.2(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15}"()
+ call amdgpu_gfx void @gfx_func_a()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func.3(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14}"()
+ call amdgpu_gfx void @gfx_func_b()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+define amdgpu_cs_chain void @func.4(<3 x i32> inreg %sgprs, <3 x i32> %vgprs) #0 {
+ call void asm sideeffect "", "~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{v32},~{v33},~{v34},~{v35},~{v36},~{v37},~{v38},~{v39},~{v40},~{v41},~{v42},~{v43},~{v44},~{v45},~{v46},~{v47},~{v48},~{v49},~{v50},~{v51},~{v52},~{v53},~{v54},~{v55},~{v56},~{v57},~{v58},~{v59},~{v60},~{v61},~{v62},~{v63},~{v64},~{v65},~{v66},~{v67},~{v68},~{v69},~{v70},~{v71},~{v72},~{v73},~{v74},~{v75},~{v76},~{v77},~{v78},~{v79},~{v80},~{v81},~{v82},~{v83},~{v84},~{v85},~{v86},~{v87},~{v88},~{v89},~{v90},~{v91},~{v92},~{v93},~{v94},~{v95},~{v96},~{v97},~{v98},~{v99}"()
+ call amdgpu_gfx void @gfx_func_b()
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @first_retry_wrapper)
+ unreachable
+}
+
+define amdgpu_cs_chain_preserve void @retry_vgpr_alloc(<3 x i32> inreg %sgprs) #0 {
+ %fptr = load ptr, ptr inttoptr(i64 0 to ptr)
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg %fptr, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @retry_vgpr_alloc)
+ unreachable
+}
+
+define amdgpu_cs_chain_preserve void @first_retry_wrapper(<3 x i32> inreg %sgprs) #0 {
+ call void(ptr, i32, <3 x i32>, <3 x i32>, i32, ...) @llvm.amdgcn.cs.chain.v3i32(ptr inreg @retry_vgpr_alloc, i32 inreg 0, <3 x i32> inreg %sgprs, <3 x i32> zeroinitializer, i32 1, i32 0, i32 -1, ptr @retry_vgpr_alloc)
+ unreachable
+}
+
+attributes #0 = { "amdgpu-dynamic-vgpr-block-size"="16" }
diff --git a/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16.ll b/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16.ll
index 4bd173c6eb885..76f6a56d22535 100644
--- a/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16.ll
+++ b/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16.ll
@@ -5,7 +5,7 @@
; Function with 129 VGPRs, which is too many with a block size of 16.
;
; ERR-DAG: .set .Lfunc129.num_vgpr, 129
-; ERR-DAG: too many DVGPR blocks for _dvgpr$ symbol for 'func129'
+; ERR-DAG: DVGPR block count 9 exceeds maximum of 8 for __dvgpr$ symbol for 'func129'
;
define amdgpu_cs_chain void @func129(<121 x float> %arg) #0 {
tail call void @func129(<121 x float> %arg)
diff --git a/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16_anon.ll b/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16_anon.ll
index 773fec2e68287..eb2eba22e7325 100644
--- a/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16_anon.ll
+++ b/llvm/test/CodeGen/AMDGPU/dvgpr_sym_fail_too_many_block_size_16_anon.ll
@@ -5,7 +5,7 @@
; Anonymous function with 129 VGPRs, which is too many with a block size of 16.
;
; ERR-DAG: .set .L__unnamed_1.num_vgpr, 129
-; ERR-DAG: too many DVGPR blocks for _dvgpr$ symbol for '__unnamed_1'
+; ERR-DAG: DVGPR block count 9 exceeds maximum of 8 for __dvgpr$ symbol for '__unnamed_1'
;
define amdgpu_cs_chain void @0(<121 x float> %arg) #0 {
tail call void @0(<121 x float> %arg)
More information about the llvm-commits
mailing list