[llvm-branch-commits] [llvm] AMDGPU: Don't include stack size of chain callees (PR #234520)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 22 01:01:13 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Diana Picus (rovka)
<details>
<summary>Changes</summary>
Chain callees are always tail called into and overwrite the caller's
stack. Therefore, their stack size should not be added up to that of
their caller when computing the resource usage.
Assisted-by: AI
---
Full diff: https://github.com/llvm/llvm-project/pull/234520.diff
3 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp (+4-1)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp (+5-3)
- (modified) llvm/test/CodeGen/AMDGPU/amdpal-chain-metadata.ll (+119-4)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
index 1731b0463a099..a33a1d3c8fc05 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMCResourceInfo.cpp
@@ -371,7 +371,10 @@ void MCResourceInfo::gatherResourceInfo(
for (const Function *Callee : FRI.Callees) {
if (!Seen.insert(Callee).second)
continue;
- if (!Callee->isDeclaration()) {
+
+ // Chain callees use the same stack frame. Exclude them.
+ if (!Callee->isDeclaration() &&
+ !AMDGPU::isChainCC(Callee->getCallingConv())) {
MCSymbol *CalleeFnSym = TM.getSymbol(&Callee->getFunction());
MCSymbol *CalleeValSym =
getSymbol(CalleeFnSym->getName(), RIK_PrivateSegSize, OutContext);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp b/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
index aab43f23cf606..c2077e940ed3e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUResourceUsageAnalysis.cpp
@@ -306,9 +306,11 @@ AMDGPUResourceUsageAnalysisImpl::analyzeResourceUsage(
}
if (IsIndirect) {
- Info.CalleeSegmentSize =
- std::max(Info.CalleeSegmentSize,
- static_cast<uint64_t>(AssumedStackSizeForExternalCall));
+ // Chain callees use the same stack frame. Exclude them.
+ if (!IsChainCall)
+ Info.CalleeSegmentSize = std::max(
+ Info.CalleeSegmentSize,
+ static_cast<uint64_t>(AssumedStackSizeForExternalCall));
// Register usage of indirect calls gets handled later
Info.UsesVCC = true;
diff --git a/llvm/test/CodeGen/AMDGPU/amdpal-chain-metadata.ll b/llvm/test/CodeGen/AMDGPU/amdpal-chain-metadata.ll
index 8716b81d95299..d972dd7884902 100644
--- a/llvm/test/CodeGen/AMDGPU/amdpal-chain-metadata.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdpal-chain-metadata.ll
@@ -1,16 +1,63 @@
; RUN: llc -mtriple=amdgpu11.00--amdpal <%s | FileCheck %s
; CHECK-LABEL: {{^}}amdgpu_cs_chain_func:
-; CHECK: .amdgpu_pal_metadata
+; CHECK: .set .Lamdgpu_cs_chain_func.private_seg_size, 16{{$}}
+
+; CHECK-LABEL: {{^}}chain_callee_smaller_stack:
+; CHECK: .set .Lchain_callee_smaller_stack.private_seg_size, 36{{$}}
+
+; CHECK-LABEL: {{^}}chain_callee_larger_stack:
+; CHECK: .set .Lchain_callee_larger_stack.private_seg_size, 8{{$}}
+
+; CHECK-LABEL: {{^}}chain_and_wwf:
+; CHECK: .set .Lchain_and_wwf.private_seg_size, 80+max(.Lwwf_alloca.private_seg_size){{$}}
+
+; CHECK-LABEL: {{^}}wwf_alloca:
+; CHECK: .set .Lwwf_alloca.private_seg_size, 28{{$}}
+
+; CHECK-LABEL: {{^}}gfx_alloca:
+; CHECK: .set .Lgfx_alloca.private_seg_size, 28{{$}}
+
+; CHECK-LABEL: {{^}}chain_and_gfx:
+; CHECK: .set .Lchain_and_gfx.private_seg_size, 32+max(.Lgfx_alloca.private_seg_size){{$}}
+
+; CHECK-LABEL: {{^}}cs_to_chain_and_wwf:
+; CHECK: .set .Lcs_to_chain_and_wwf.private_seg_size, 12{{$}}
+
+; CHECK-LABEL: {{^}}chain_indirect_and_wwf:
+; CHECK: .set .Lchain_indirect_and_wwf.private_seg_size, 64+max(.Lwwf_alloca.private_seg_size){{$}}
+; CHECK: .set .Lchain_indirect_and_wwf.has_indirect_call, 1{{$}}
+
+; CHECK-LABEL: .amdgpu_pal_metadata
; CHECK-NEXT: ---
; CHECK-NEXT: amdpal.pipelines:
; CHECK-NEXT: - .api: Vulkan
+; CHECK-LABEL: .hardware_stages:
+; CHECK: .cs:
+; CHECK: .entry_point_symbol: cs_to_chain_and_wwf
+; CHECK: .scratch_memory_size: 0x10{{$}}
; CHECK: .shader_functions:
-; CHECK-NEXT: amdgpu_cs_chain_func:
+; CHECK-LABEL: amdgpu_cs_chain_func:
; CHECK: .backend_stack_size: 0x10{{$}}
; CHECK: .stack_frame_size_in_bytes: 0x10{{$}}
-; CHECK-NEXT: .vgpr_count:
-; CHECK-NEXT: .shaders:
+; CHECK-LABEL: chain_and_gfx:
+; CHECK: .backend_stack_size: 0x20{{$}}
+; CHECK: .stack_frame_size_in_bytes: 0x20{{$}}
+; CHECK-LABEL: chain_and_wwf:
+; CHECK: .backend_stack_size: 0x50{{$}}
+; CHECK: .stack_frame_size_in_bytes: 0x50{{$}}
+; CHECK-LABEL: chain_callee_larger_stack:
+; CHECK: .backend_stack_size: 0x8{{$}}
+; CHECK: .stack_frame_size_in_bytes: 0x8{{$}}
+; CHECK-LABEL: chain_callee_smaller_stack:
+; CHECK: .backend_stack_size: 0x24{{$}}
+; CHECK: .stack_frame_size_in_bytes: 0x24{{$}}
+; CHECK-LABEL: chain_indirect_and_wwf:
+; CHECK: .backend_stack_size: 0x40{{$}}
+; CHECK: .stack_frame_size_in_bytes: 0x40{{$}}
+; CHECK-LABEL: gfx_alloca:
+; CHECK: .backend_stack_size: 0x1c{{$}}
+; CHECK: .stack_frame_size_in_bytes: 0x1c{{$}}
; CHECK:amdpal.version:
; CHECK-NEXT: - 0x3
; CHECK-NEXT: - 0
@@ -25,11 +72,79 @@ define amdgpu_cs_chain void @amdgpu_cs_chain_func(<40 x i32> %should_spill) {
ret void
}
+define amdgpu_cs_chain void @chain_callee_smaller_stack(<40 x i32> %v) {
+.entry:
+ %a = alloca [8 x i32], addrspace(5)
+ store volatile i32 1, ptr addrspace(5) %a
+ call void (ptr, i32, {}, <40 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr @amdgpu_cs_chain_func, i32 -1, {} inreg poison, <40 x i32> %v, i32 0)
+ unreachable
+}
+
+define amdgpu_cs_chain void @chain_callee_larger_stack(<40 x i32> %v) {
+.entry:
+ %a = alloca [1 x i32], addrspace(5)
+ store volatile i32 1, ptr addrspace(5) %a
+ call void (ptr, i32, {}, <40 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr @amdgpu_cs_chain_func, i32 -1, {} inreg poison, <40 x i32> %v, i32 0)
+ unreachable
+}
+
+define amdgpu_cs_chain void @chain_and_wwf(<40 x i32> %v) {
+.entry:
+ %a = alloca [16 x i32], addrspace(5)
+ store i32 2, ptr addrspace(5) %a
+ call void (ptr, ...) @llvm.amdgcn.call.whole.wave(ptr @wwf_alloca, ptr addrspace(5) %a)
+ call void (ptr, i32, {}, <40 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr @amdgpu_cs_chain_func, i32 -1, {} inreg poison, <40 x i32> %v, i32 0)
+ unreachable
+}
+
+define amdgpu_gfx_whole_wave void @wwf_alloca(i1 %active, ptr addrspace(5) %p) {
+ %a = alloca [4 x i32], addrspace(5)
+ store volatile i32 3, ptr addrspace(5) %a
+ store i32 4, ptr addrspace(5) %p
+ ret void
+}
+
+define amdgpu_cs_chain void @chain_and_gfx(<40 x i32> %v) {
+.entry:
+ %a = alloca [4 x i32], addrspace(5)
+ store i32 6, ptr addrspace(5) %a
+ call amdgpu_gfx void @gfx_alloca(ptr addrspace(5) %a)
+ call void (ptr, i32, {}, <40 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr @amdgpu_cs_chain_func, i32 -1, {} inreg poison, <40 x i32> %v, i32 0)
+ unreachable
+}
+
+define amdgpu_gfx void @gfx_alloca(ptr addrspace(5) %p) {
+ %a = alloca [6 x i32], addrspace(5)
+ store volatile i32 7, ptr addrspace(5) %a
+ store i32 8, ptr addrspace(5) %p
+ ret void
+}
+
+define amdgpu_cs void @cs_to_chain_and_wwf(<40 x i32> %v) {
+.entry:
+ %a = alloca [2 x i32], addrspace(5)
+ store volatile i32 9, ptr addrspace(5) %a
+ call void (ptr, i32, {}, <40 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr @chain_and_wwf, i32 -1, {} inreg poison, <40 x i32> %v, i32 0)
+ unreachable
+}
+
+define amdgpu_cs_chain void @chain_indirect_and_wwf(ptr inreg %callee, <40 x i32> %v) {
+.entry:
+ %a = alloca [12 x i32], addrspace(5)
+ store i32 10, ptr addrspace(5) %a
+ call void (ptr, ...) @llvm.amdgcn.call.whole.wave(ptr @wwf_alloca, ptr addrspace(5) %a)
+ call void (ptr, i32, {}, <40 x i32>, i32, ...) @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr %callee, i32 -1, {} inreg poison, <40 x i32> %v, i32 0)
+ unreachable
+}
+
define amdgpu_cs_chain_preserve void @amdgpu_cs_chain_preserve_func() {
.entry:
ret void
}
+declare void @llvm.amdgcn.call.whole.wave(ptr, ...)
+declare void @llvm.amdgcn.cs.chain.p0.i32.s.v40i32(ptr, i32, {}, <40 x i32>, i32 immarg, ...)
+
declare amdgpu_gfx void @use(...)
!amdgpu.pal.metadata.msgpack = !{!0}
``````````
</details>
https://github.com/llvm/llvm-project/pull/234520
More information about the llvm-branch-commits
mailing list