[llvm] [AMDGPU] Set gfx13 LDS to 192KB and model LDS size via subtarget features (PR #214513)
Mariusz Sikora via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 08:13:40 PDT 2026
https://github.com/mariusz-sikora-at-amd updated https://github.com/llvm/llvm-project/pull/214513
>From a91510e0706dc49b72e49cf2aebdd3e329572e81 Mon Sep 17 00:00:00 2001
From: Mariusz Sikora <mariusz.sikora at amd.com>
Date: Tue, 4 Aug 2026 16:36:05 -0400
Subject: [PATCH 1/5] [AMDGPU] Set gfx13 LDS to 192KB and model LDS size via
subtarget features
Set gfx13 addressable LDS to 192KB (96KB in CU mode).
Replace the isGFX10/1250 if-logic to calculate LDS size with FeatureLocalMemorySize.
This change is NFC for all targets except gfx13.
---
llvm/lib/Target/AMDGPU/AMDGPU.td | 9 ++-
llvm/lib/Target/AMDGPU/AMDGPUFeatures.td | 14 ++++
llvm/lib/Target/AMDGPU/GCNSubtarget.cpp | 5 +-
.../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp | 61 ++++++++--------
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h | 5 ++
.../AMDGPU/lds-limit-diagnostics-gfx13.ll | 17 +++++
llvm/test/CodeGen/AMDGPU/occupancy-levels.ll | 69 ++++++++++++++++++-
7 files changed, 145 insertions(+), 35 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index c909f2748e0b0..9dcee2d66c887 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -1636,7 +1636,8 @@ def FeatureGFX9 : GCNSubtargetFeatureGeneration<"GFX9",
def FeatureGFX10 : GCNSubtargetFeatureGeneration<"GFX10",
"gfx10",
- [FeatureFP64, FeatureAddressableLocalMemorySize65536, FeatureMIMG_R128,
+ [FeatureFP64, FeatureAddressableLocalMemorySize65536,
+ FeatureLocalMemorySize131072, FeatureMIMG_R128,
FeatureSupportsWave32, FeatureSupportsWave64, FeatureSupportsWGP,
FeatureFlatAddressSpace,
FeatureCIInsts, Feature16BitInsts,
@@ -1667,7 +1668,8 @@ def FeatureGFX10 : GCNSubtargetFeatureGeneration<"GFX10",
def FeatureGFX11 : GCNSubtargetFeatureGeneration<"GFX11",
"gfx11",
- [FeatureFP64, FeatureAddressableLocalMemorySize65536, FeatureMIMG_R128,
+ [FeatureFP64, FeatureAddressableLocalMemorySize65536,
+ FeatureLocalMemorySize131072, FeatureMIMG_R128,
FeatureSupportsWave32, FeatureSupportsWave64, FeatureSupportsWGP,
FeatureFlatAddressSpace, Feature16BitInsts,
FeatureInv2PiInlineImm, FeatureApertureRegs,
@@ -2209,6 +2211,7 @@ def FeatureISAVersion12 : FeatureSet<
FeatureSupportsWave64, FeatureSupportsWGP,
FeatureBackOffBarrier,
FeatureAddressableLocalMemorySize65536,
+ FeatureLocalMemorySize131072,
FeatureLDSBankCount32,
FeatureDLInsts,
FeatureDot7Insts,
@@ -2436,7 +2439,7 @@ def FeatureISAVersion12_5_Generic: FeatureSet<
def FeatureISAVersion13 : FeatureSet<
[FeatureGFX13,
FeatureGFX1250Insts,
- FeatureAddressableLocalMemorySize65536,
+ FeatureAddressableLocalMemorySize196608,
Feature64BitLiterals,
FeatureLDSBankCount32,
FeatureDLInsts,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td b/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td
index b1c09a89433ab..1dc62ded656f7 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td
@@ -42,8 +42,22 @@ class SubtargetFeatureAddressableLocalMemorySize <int Value> : SubtargetFeature<
def FeatureAddressableLocalMemorySize32768 : SubtargetFeatureAddressableLocalMemorySize<32768>;
def FeatureAddressableLocalMemorySize65536 : SubtargetFeatureAddressableLocalMemorySize<65536>;
def FeatureAddressableLocalMemorySize163840 : SubtargetFeatureAddressableLocalMemorySize<163840>;
+def FeatureAddressableLocalMemorySize196608 : SubtargetFeatureAddressableLocalMemorySize<196608>;
def FeatureAddressableLocalMemorySize327680 : SubtargetFeatureAddressableLocalMemorySize<327680>;
+// Total size of LDS on the whole block, in bytes. Set this only when it is
+// larger than the addressable size, i.e. when one workgroup cannot use the whole
+// block (e.g. gfx10/11/12: a block is two 64k CUs => 128k total). If not set, it
+// defaults to the addressable size.
+class SubtargetFeatureLocalMemorySize <int Value> : SubtargetFeature<
+ "localmemorysize"#Value,
+ "LocalMemorySize",
+ !cast<string>(Value),
+ "The total size of local memory in bytes"
+>;
+
+def FeatureLocalMemorySize131072 : SubtargetFeatureLocalMemorySize<131072>;
+
// Whether each wavefront size mode is available on the hardware,
// independent of the active mode.
def FeatureSupportsWave32 : SubtargetFeature<"supports-wave32",
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
index 1c0e718bd8d97..c4a3e97b16fe2 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
@@ -173,13 +173,12 @@ GCNSubtarget &GCNSubtarget::initializeSubtargetDependencies(const Triple &TT,
if (LDSBankCount == 0)
LDSBankCount = 32;
- if (AddressableLocalMemorySize == 0)
- AddressableLocalMemorySize = 32768;
-
if (FlatOffsetBitWidth == 0)
FlatOffsetBitWidth = 13;
LocalMemorySize = AMDGPU::IsaInfo::getLocalMemorySize(*this);
+ AddressableLocalMemorySize =
+ AMDGPU::IsaInfo::getAddressableLocalMemorySize(*this);
// LDS Allocation Granularity calculated in bytes from dwords
LDSAllocationGranularity =
AMDGPU::getLdsDwGranularity(*this) * sizeof(uint32_t);
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 38329d6295538..9dea8f5deff70 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1176,48 +1176,49 @@ unsigned getWavefrontSize(const MCSubtargetInfo &STI) {
return 64;
}
-unsigned getLocalMemorySize(const MCSubtargetInfo &STI) {
- unsigned BytesPerCU = getAddressableLocalMemorySize(STI);
-
- // "Per CU" really means "per whatever functional block the waves of a
- // workgroup must share". So the effective local memory size is doubled in
- // WGP mode on gfx10.
- if (isGFX10Plus(STI) && !STI.getFeatureBits().test(FeatureCuMode))
- BytesPerCU *= 2;
-
- return BytesPerCU;
-}
-
-unsigned getAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
+// Maximum LDS a single work-group can address. This is the fixed HW addressing
+// cap and does not depend on CU/WGP (full-SIMD) mode.
+static unsigned getMaxHWAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
if (STI.getFeatureBits().test(FeatureAddressableLocalMemorySize32768))
return 32768;
if (STI.getFeatureBits().test(FeatureAddressableLocalMemorySize65536))
return 65536;
if (STI.getFeatureBits().test(FeatureAddressableLocalMemorySize163840))
return 163840;
+ if (STI.getFeatureBits().test(FeatureAddressableLocalMemorySize196608))
+ return 196608;
if (STI.getFeatureBits().test(FeatureAddressableLocalMemorySize327680))
return 327680;
return 32768;
}
-unsigned getEUsPerCU(const MCSubtargetInfo &STI) {
- // "Per CU" really means "per whatever functional block the waves of a
- // workgroup must share".
+// Total physical LDS on the block. On some targets a single work-group cannot
+// address the whole block, so the physical size is larger than the addressable
+// size; those set FeatureLocalMemorySize (gfx10/11/12: two 64k CUs => 128k).
+// Otherwise it defaults to the addressable size.
+static unsigned getPhysicalLocalMemorySize(const MCSubtargetInfo &STI) {
+ if (STI.getFeatureBits().test(FeatureLocalMemorySize131072))
+ return 131072;
+ return getMaxHWAddressableLocalMemorySize(STI);
+}
- // GFX12.5 only supports CU mode, which contains four SIMDs.
- if (isGFX1250(STI)) {
- assert(STI.getFeatureBits().test(FeatureCuMode));
- return 4;
- }
+unsigned getLocalMemorySize(const MCSubtargetInfo &STI) {
+ // Total LDS on the block, halved in CU (half-WGP) mode.
+ unsigned Size = getPhysicalLocalMemorySize(STI);
+ if (!isFullSIMDMode(STI))
+ Size /= 2;
+ return Size;
+}
- // For gfx10 in CU mode the functional block is the CU, which contains
- // two SIMDs.
- if (isGFX10Plus(STI) && STI.getFeatureBits().test(FeatureCuMode))
- return 2;
+unsigned getAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
+ // HW addressing cap, but no more than is available in the current mode.
+ return std::min(getMaxHWAddressableLocalMemorySize(STI),
+ getLocalMemorySize(STI));
+}
- // Pre-gfx10 a CU contains four SIMDs. For gfx10 in WGP mode the WGP
- // contains two CUs, so a total of four SIMDs.
- return 4;
+unsigned getEUsPerCU(const MCSubtargetInfo &STI) {
+ // Four SIMD32s in full SIMD mode, two in CU (half-WGP) mode.
+ return isFullSIMDMode(STI) ? 4 : 2;
}
unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo &STI,
@@ -2596,6 +2597,10 @@ bool isGFX1250(const MCSubtargetInfo &STI) {
return STI.getFeatureBits()[AMDGPU::FeatureGFX1250Insts] && !isGFX13(STI);
}
+bool isFullSIMDMode(const MCSubtargetInfo &STI) {
+ return isGFX1250(STI) || !STI.getFeatureBits().test(FeatureCuMode);
+}
+
bool isGFX1250Plus(const MCSubtargetInfo &STI) {
return STI.getFeatureBits()[AMDGPU::FeatureGFX1250Insts];
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 44476d4d555c0..e7597fc0e5e82 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -1513,6 +1513,11 @@ bool isGFX1250(const MCSubtargetInfo &STI);
bool isGFX1250Plus(const MCSubtargetInfo &STI);
bool isGFX13(const MCSubtargetInfo &STI);
bool isGFX13Plus(const MCSubtargetInfo &STI);
+
+/// \returns true if waves in a work-group span all four SIMD32s (one contiguous
+/// LDS), i.e. not half-WGP/CU mode.
+bool isFullSIMDMode(const MCSubtargetInfo &STI);
+
bool supportsWGP(const MCSubtargetInfo &STI);
bool isNotGFX12Plus(const MCSubtargetInfo &STI);
bool isNotGFX11Plus(const MCSubtargetInfo &STI);
diff --git a/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll b/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll
new file mode 100644
index 0000000000000..e0ad7a2dc979d
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll
@@ -0,0 +1,17 @@
+; RUN: not llc -mtriple=amdgpu13.10-amd-amdhsa -verify-machineinstrs < %s 2>&1 | FileCheck -check-prefix=ERROR %s
+; RUN: not llc -mtriple=amdgpu13.10-amd-amdhsa -mattr=+cumode -verify-machineinstrs < %s 2>&1 | FileCheck -check-prefix=ERROR-CU %s
+
+; GFX1310 supports up to 192 KB LDS in WGP (full-SIMD) mode, where the whole
+; block is addressable by a single workgroup. In CU (half-WGP) mode the block is
+; split between the two CUs, so only half (96 KB) is usable.
+; These are negative tests checking when the LDS size exceeds the usable limit.
+
+; ERROR: error: <unknown>:0:0: local memory (196612) exceeds limit (196608) in function 'test_lds_limit'
+; ERROR-CU: error: <unknown>:0:0: local memory (196612) exceeds limit (98304) in function 'test_lds_limit'
+ at dst = addrspace(3) global [196612 x i8] undef
+
+define amdgpu_kernel void @test_lds_limit(i8 %val) {
+ %gep = getelementptr [196612 x i8], ptr addrspace(3) @dst, i32 0, i32 100
+ store i8 %val, ptr addrspace(3) %gep
+ ret void
+}
diff --git a/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll b/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll
index 22203931528e9..07175ef639d69 100644
--- a/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll
+++ b/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll
@@ -31,7 +31,10 @@
; RUN: llc -mtriple=amdgpu12.00 -mattr=+cumode < %s | FileCheck --check-prefixes=GCN,GFX1200,GFX1200W32,GFX1200W32CU %s
; RUN: llc -mtriple=amdgpu12.00 -mattr=+wavefrontsize64,+cumode < %s | FileCheck --check-prefixes=GCN,GFX1200,GFX1200W64,GFX1200W64CU %s
; RUN: llc -mtriple=amdgpu12.50 < %s | FileCheck --check-prefixes=GCN,GFX1250 %s
-; RUN: llc -mtriple=amdgpu13.10 < %s | FileCheck --check-prefixes=GCN,GFX1100,GFX1100W32 %s
+; RUN: llc -mtriple=amdgpu13.10 < %s | FileCheck --check-prefixes=GCN,GFX1310,GFX1310W32,GFX1310W32WG %s
+; RUN: llc -mtriple=amdgpu13.10 -mattr=+wavefrontsize64 < %s | FileCheck --check-prefixes=GCN,GFX1310,GFX1310W64,GFX1310W64WG %s
+; RUN: llc -mtriple=amdgpu13.10 -mattr=+cumode < %s | FileCheck --check-prefixes=GCN,GFX1310,GFX1310W32,GFX1310W32CU %s
+; RUN: llc -mtriple=amdgpu13.10 -mattr=+wavefrontsize64,+cumode < %s | FileCheck --check-prefixes=GCN,GFX1310,GFX1310W64,GFX1310W64CU %s
; GCN-LABEL: {{^}}max_occupancy:
; GFX6: ; Occupancy: 10{{$}}
@@ -44,6 +47,7 @@
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @max_occupancy() #10 {
ret void
}
@@ -61,6 +65,8 @@ define amdgpu_kernel void @max_occupancy() #10 {
; GFX1200W32: ; Occupancy: 5
; GFX1200W64: ; Occupancy: 3
; GFX1250: ; Occupancy: 3
+; GFX1310W32: ; Occupancy: 5
+; GFX1310W64: ; Occupancy: 3
define amdgpu_kernel void @limited_occupancy_3() #0 {
ret void
}
@@ -76,6 +82,7 @@ define amdgpu_kernel void @limited_occupancy_3() #0 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @limited_occupancy_18() #1 {
ret void
}
@@ -91,6 +98,7 @@ define amdgpu_kernel void @limited_occupancy_18() #1 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @limited_occupancy_19() #2 {
ret void
}
@@ -106,6 +114,7 @@ define amdgpu_kernel void @limited_occupancy_19() #2 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_24_vgprs() #10 {
call void asm sideeffect "", "~{v23}" ()
ret void
@@ -123,6 +132,7 @@ define amdgpu_kernel void @used_24_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_28_vgprs() #10 {
call void asm sideeffect "", "~{v27}" ()
ret void
@@ -140,6 +150,7 @@ define amdgpu_kernel void @used_28_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_32_vgprs() #10 {
call void asm sideeffect "", "~{v31}" ()
ret void
@@ -158,6 +169,7 @@ define amdgpu_kernel void @used_32_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_36_vgprs() #10 {
call void asm sideeffect "", "~{v35}" ()
ret void
@@ -175,6 +187,7 @@ define amdgpu_kernel void @used_36_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_40_vgprs() #10 {
call void asm sideeffect "", "~{v39}" ()
ret void
@@ -193,6 +206,7 @@ define amdgpu_kernel void @used_40_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_44_vgprs() #10 {
call void asm sideeffect "", "~{v43}" ()
ret void
@@ -210,6 +224,7 @@ define amdgpu_kernel void @used_44_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_48_vgprs() #10 {
call void asm sideeffect "", "~{v47}" ()
ret void
@@ -229,6 +244,8 @@ define amdgpu_kernel void @used_48_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 12
; GFX1250: ; Occupancy: 16
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 12
define amdgpu_kernel void @used_56_vgprs() #10 {
call void asm sideeffect "", "~{v55}" ()
ret void
@@ -247,6 +264,8 @@ define amdgpu_kernel void @used_56_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 10
; GFX1250: ; Occupancy: 16
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 10
define amdgpu_kernel void @used_64_vgprs() #10 {
call void asm sideeffect "", "~{v63}" ()
ret void
@@ -266,6 +285,8 @@ define amdgpu_kernel void @used_64_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 10
; GFX1250: ; Occupancy: 12
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 10
define amdgpu_kernel void @used_72_vgprs() #10 {
call void asm sideeffect "", "~{v71}" ()
ret void
@@ -284,6 +305,8 @@ define amdgpu_kernel void @used_72_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 9
; GFX1250: ; Occupancy: 12
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 9
define amdgpu_kernel void @used_80_vgprs() #10 {
call void asm sideeffect "", "~{v79}" ()
ret void
@@ -304,6 +327,8 @@ define amdgpu_kernel void @used_80_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 9
; GFX1250: ; Occupancy: 10
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 9
define amdgpu_kernel void @used_84_vgprs() #10 {
call void asm sideeffect "", "~{v83}" ()
ret void
@@ -323,6 +348,8 @@ define amdgpu_kernel void @used_84_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 8
; GFX1250: ; Occupancy: 10
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 8
define amdgpu_kernel void @used_88_vgprs() #10 {
call void asm sideeffect "", "~{v87}" ()
ret void
@@ -341,6 +368,8 @@ define amdgpu_kernel void @used_88_vgprs() #10 {
; GFX1200W32: ; Occupancy: 16
; GFX1200W64: ; Occupancy: 8
; GFX1250: ; Occupancy: 10
+; GFX1310W32: ; Occupancy: 16
+; GFX1310W64: ; Occupancy: 8
define amdgpu_kernel void @used_96_vgprs() #10 {
call void asm sideeffect "", "~{v95}" ()
ret void
@@ -360,6 +389,8 @@ define amdgpu_kernel void @used_96_vgprs() #10 {
; GFX1200W32: ; Occupancy: 12
; GFX1200W64: ; Occupancy: 7
; GFX1250: ; Occupancy: 9
+; GFX1310W32: ; Occupancy: 12
+; GFX1310W64: ; Occupancy: 7
define amdgpu_kernel void @used_100_vgprs() #10 {
call void asm sideeffect "", "~{v99}" ()
ret void
@@ -378,6 +409,8 @@ define amdgpu_kernel void @used_100_vgprs() #10 {
; GFX1200W32: ; Occupancy: 12
; GFX1200W64: ; Occupancy: 6
; GFX1250: ; Occupancy: 9
+; GFX1310W32: ; Occupancy: 12
+; GFX1310W64: ; Occupancy: 6
define amdgpu_kernel void @used_112_vgprs() #10 {
call void asm sideeffect "", "~{v111}" ()
ret void
@@ -396,6 +429,8 @@ define amdgpu_kernel void @used_112_vgprs() #10 {
; GFX1200W32: ; Occupancy: 10
; GFX1200W64: ; Occupancy: 5
; GFX1250: ; Occupancy: 8
+; GFX1310W32: ; Occupancy: 10
+; GFX1310W64: ; Occupancy: 5
define amdgpu_kernel void @used_128_vgprs() #10 {
call void asm sideeffect "", "~{v127}" ()
ret void
@@ -414,6 +449,8 @@ define amdgpu_kernel void @used_128_vgprs() #10 {
; GFX1200W32: ; Occupancy: 10
; GFX1200W64: ; Occupancy: 5
; GFX1250: ; Occupancy: 7
+; GFX1310W32: ; Occupancy: 10
+; GFX1310W64: ; Occupancy: 5
define amdgpu_kernel void @used_144_vgprs() #10 {
call void asm sideeffect "", "~{v143}" ()
ret void
@@ -433,6 +470,8 @@ define amdgpu_kernel void @used_144_vgprs() #10 {
; GFX1200W32: ; Occupancy: 9
; GFX1200W64: ; Occupancy: 4
; GFX1250: ; Occupancy: 5
+; GFX1310W32: ; Occupancy: 9
+; GFX1310W64: ; Occupancy: 4
define amdgpu_kernel void @used_168_vgprs() #10 {
call void asm sideeffect "", "~{v167}" ()
ret void
@@ -452,6 +491,8 @@ define amdgpu_kernel void @used_168_vgprs() #10 {
; GFX1200W32: ; Occupancy: 7
; GFX1200W64: ; Occupancy: 3
; GFX1250: ; Occupancy: 4
+; GFX1310W32: ; Occupancy: 7
+; GFX1310W64: ; Occupancy: 3
define amdgpu_kernel void @used_200_vgprs() #10 {
call void asm sideeffect "", "~{v199}" ()
ret void
@@ -470,6 +511,8 @@ define amdgpu_kernel void @used_200_vgprs() #10 {
; GFX1200W32: ; Occupancy: 5
; GFX1200W64: ; Occupancy: 2
; GFX1250: ; Occupancy: 4
+; GFX1310W32: ; Occupancy: 5
+; GFX1310W64: ; Occupancy: 2
define amdgpu_kernel void @used_256_vgprs() #10 {
call void asm sideeffect "", "~{v255}" ()
ret void
@@ -488,6 +531,7 @@ define amdgpu_kernel void @used_256_vgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_80_sgprs() #10 {
call void asm sideeffect "", "~{s79}" ()
ret void
@@ -506,6 +550,7 @@ define amdgpu_kernel void @used_80_sgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_88_sgprs() #10 {
call void asm sideeffect "", "~{s87}" ()
ret void
@@ -524,6 +569,7 @@ define amdgpu_kernel void @used_88_sgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_100_sgprs() #10 {
call void asm sideeffect "", "~{s99}" ()
ret void
@@ -542,6 +588,7 @@ define amdgpu_kernel void @used_100_sgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
define amdgpu_kernel void @used_101_sgprs() #10 {
call void asm sideeffect "", "~{s100}" ()
ret void
@@ -559,6 +606,7 @@ define amdgpu_kernel void @used_101_sgprs() #10 {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
@lds6552 = internal addrspace(3) global [6552 x i8] poison, align 4
define amdgpu_kernel void @used_lds_6552() {
store volatile i8 1, ptr addrspace(3) @lds6552
@@ -577,6 +625,7 @@ define amdgpu_kernel void @used_lds_6552() {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
@lds6556 = internal addrspace(3) global [6556 x i8] poison, align 4
define amdgpu_kernel void @used_lds_6556() {
store volatile i8 1, ptr addrspace(3) @lds6556
@@ -595,6 +644,7 @@ define amdgpu_kernel void @used_lds_6556() {
; GFX1100: ; Occupancy: 16
; GFX1200: ; Occupancy: 16
; GFX1250: ; Occupancy: 16
+; GFX1310: ; Occupancy: 16
@lds13112 = internal addrspace(3) global [13112 x i8] poison, align 4
define amdgpu_kernel void @used_lds_13112() {
store volatile i8 1, ptr addrspace(3) @lds13112
@@ -615,6 +665,9 @@ define amdgpu_kernel void @used_lds_13112() {
; GFX1200W32CU: ; Occupancy: 7{{$}}
; GFX1200W64: ; Occupancy: 4{{$}}
; GFX1250: ; Occupancy: 8{{$}}
+; GFX1310W32WG: ; Occupancy: 12{{$}}
+; GFX1310W32CU: ; Occupancy: 11{{$}}
+; GFX1310W64: ; Occupancy: 6{{$}}
@lds8252 = internal addrspace(3) global [8252 x i8] poison, align 4
define amdgpu_kernel void @used_lds_8252_max_group_size_64() #3 {
store volatile i8 1, ptr addrspace(3) @lds8252
@@ -636,6 +689,10 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_64() #3 {
; GFX1200W64WG: ; Occupancy: 8{{$}}
; GFX1200W64CU: ; Occupancy: 7{{$}}
; GFX1250: ; Occupancy: 12{{$}}
+; GFX1310W32WG: ; Occupancy: 16{{$}}
+; GFX1310W32CU: ; Occupancy: 15{{$}}
+; GFX1310W64WG: ; Occupancy: 12{{$}}
+; GFX1310W64CU: ; Occupancy: 11{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_96() #4 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -656,6 +713,9 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_96() #4 {
; GFX1200W64WG: ; Occupancy: 8{{$}}
; GFX1200W64CU: ; Occupancy: 7{{$}}
; GFX1250: ; Occupancy: 16{{$}}
+; GFX1310W32: ; Occupancy: 16{{$}}
+; GFX1310W64WG: ; Occupancy: 12{{$}}
+; GFX1310W64CU: ; Occupancy: 11{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_128() #5 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -676,6 +736,9 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_128() #5 {
; GFX1200W64WG: ; Occupancy: 12{{$}}
; GFX1200W64CU: ; Occupancy: 11{{$}}
; GFX1250: ; Occupancy: 15{{$}}
+; GFX1310W32: ; Occupancy: 15{{$}}
+; GFX1310W64WG: ; Occupancy: 16{{$}}
+; GFX1310W64CU: ; Occupancy: 15{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_192() #6 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -696,6 +759,7 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_192() #6 {
; GFX1200W64WG: ; Occupancy: 15{{$}}
; GFX1200W64CU: ; Occupancy: 14{{$}}
; GFX1250: ; Occupancy: 16{{$}}
+; GFX1310: ; Occupancy: 16{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_256() #7 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -712,6 +776,7 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_256() #7 {
; GFX1100: ; Occupancy: 16{{$}}
; GFX1200: ; Occupancy: 16{{$}}
; GFX1250: ; Occupancy: 16{{$}}
+; GFX1310: ; Occupancy: 16{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_512() #8 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -729,6 +794,7 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_512() #8 {
; GFX1100: ; Occupancy: 16{{$}}
; GFX1200: ; Occupancy: 16{{$}}
; GFX1250: ; Occupancy: 16{{$}}
+; GFX1310: ; Occupancy: 16{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_1024() #9 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -744,6 +810,7 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_1024() #9 {
; GFX1100: ; Occupancy: 4{{$}}
; GFX1200: ; Occupancy: 4{{$}}
; GFX1250: ; Occupancy: 8{{$}}
+; GFX1310: ; Occupancy: 6{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_32() #10 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
>From 99e1f4d1ba8f42839a31c1cf5ffc10f9349c5b88 Mon Sep 17 00:00:00 2001
From: Mariusz Sikora <mariusz.sikora at amd.com>
Date: Fri, 7 Aug 2026 03:17:11 -0400
Subject: [PATCH 2/5] Update Granualarity for gfx13 to 256
---
llvm/docs/AMDGPUUsage.rst | 2 ++
.../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp | 2 ++
llvm/test/CodeGen/AMDGPU/extra-lds-size.ll | 7 +++++++
llvm/test/CodeGen/AMDGPU/occupancy-levels.ll | 20 +++++++++++--------
4 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst
index 87ba811e1a686..d3cd3a7c28ff6 100644
--- a/llvm/docs/AMDGPUUsage.rst
+++ b/llvm/docs/AMDGPUUsage.rst
@@ -6708,6 +6708,8 @@ The fields used by CP for code objects before V3 also match those specified in
roundup(lds-size / (320 * 4))
GFX125*
roundup(lds-size / (512 * 4))
+ GFX13
+ roundup(lds-size / (256 * 4))
24 1 bit ENABLE_EXCEPTION_IEEE_754_FP Wavefront starts execution
_INVALID_OPERATION with specified exceptions
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 9dea8f5deff70..b86426dd69e48 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -3730,6 +3730,8 @@ unsigned getLdsDwGranularity(const MCSubtargetInfo &ST) {
return 64;
if (ST.getFeatureBits().test(FeatureAddressableLocalMemorySize65536))
return 128;
+ if (ST.getFeatureBits().test(FeatureAddressableLocalMemorySize196608))
+ return 256;
if (ST.getFeatureBits().test(FeatureAddressableLocalMemorySize163840))
return 320;
if (ST.getFeatureBits().test(FeatureAddressableLocalMemorySize327680))
diff --git a/llvm/test/CodeGen/AMDGPU/extra-lds-size.ll b/llvm/test/CodeGen/AMDGPU/extra-lds-size.ll
index 30100302f102f..2395543f96e4d 100644
--- a/llvm/test/CodeGen/AMDGPU/extra-lds-size.ll
+++ b/llvm/test/CodeGen/AMDGPU/extra-lds-size.ll
@@ -8,6 +8,8 @@
; RUN: llc -mtriple=amdgpu12.00-mesa-mesa3d < %s | FileCheck -check-prefix=GFX1200-MESA %s
; RUN: llc -mtriple=amdgpu12.50-amd-amdpal < %s | FileCheck -check-prefix=GFX1250-PAL %s
; RUN: llc -mtriple=amdgpu12.50-mesa-mesa3d < %s | FileCheck -check-prefix=GFX1250-MESA %s
+; RUN: llc -mtriple=amdgpu13.10-amd-amdpal < %s | FileCheck -check-prefix=GFX1310-PAL %s
+; RUN: llc -mtriple=amdgpu13.10-mesa-mesa3d < %s | FileCheck -check-prefix=GFX1310-MESA %s
; Check EXTRA_LDS_SIZE in SPI_SHADER_PGM_RSRC2_PS.
@@ -36,6 +38,11 @@
; GFX1250-MESA: .long 45100
; GFX1250-MESA-NEXT: .long 256
+; GFX1310-PAL: '0x2c0b (SPI_SHADER_PGM_RSRC2_PS)': 0x200
+
+; GFX1310-MESA: .long 45100
+; GFX1310-MESA-NEXT: .long 512
+
@lds = internal addrspace(3) global [4096 x i8] poison
define amdgpu_ps void @global_store_saddr_uniform_ptr_in_vgprs(i32 %voffset) {
diff --git a/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll b/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll
index 07175ef639d69..1d63d62fc8524 100644
--- a/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll
+++ b/llvm/test/CodeGen/AMDGPU/occupancy-levels.ll
@@ -665,9 +665,10 @@ define amdgpu_kernel void @used_lds_13112() {
; GFX1200W32CU: ; Occupancy: 7{{$}}
; GFX1200W64: ; Occupancy: 4{{$}}
; GFX1250: ; Occupancy: 8{{$}}
-; GFX1310W32WG: ; Occupancy: 12{{$}}
-; GFX1310W32CU: ; Occupancy: 11{{$}}
-; GFX1310W64: ; Occupancy: 6{{$}}
+; GFX1310W32WG: ; Occupancy: 11{{$}}
+; GFX1310W32CU: ; Occupancy: 10{{$}}
+; GFX1310W64WG: ; Occupancy: 6{{$}}
+; GFX1310W64CU: ; Occupancy: 5{{$}}
@lds8252 = internal addrspace(3) global [8252 x i8] poison, align 4
define amdgpu_kernel void @used_lds_8252_max_group_size_64() #3 {
store volatile i8 1, ptr addrspace(3) @lds8252
@@ -691,8 +692,8 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_64() #3 {
; GFX1250: ; Occupancy: 12{{$}}
; GFX1310W32WG: ; Occupancy: 16{{$}}
; GFX1310W32CU: ; Occupancy: 15{{$}}
-; GFX1310W64WG: ; Occupancy: 12{{$}}
-; GFX1310W64CU: ; Occupancy: 11{{$}}
+; GFX1310W64WG: ; Occupancy: 11{{$}}
+; GFX1310W64CU: ; Occupancy: 10{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_96() #4 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -714,8 +715,8 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_96() #4 {
; GFX1200W64CU: ; Occupancy: 7{{$}}
; GFX1250: ; Occupancy: 16{{$}}
; GFX1310W32: ; Occupancy: 16{{$}}
-; GFX1310W64WG: ; Occupancy: 12{{$}}
-; GFX1310W64CU: ; Occupancy: 11{{$}}
+; GFX1310W64WG: ; Occupancy: 11{{$}}
+; GFX1310W64CU: ; Occupancy: 10{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_128() #5 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
@@ -810,7 +811,10 @@ define amdgpu_kernel void @used_lds_8252_max_group_size_1024() #9 {
; GFX1100: ; Occupancy: 4{{$}}
; GFX1200: ; Occupancy: 4{{$}}
; GFX1250: ; Occupancy: 8{{$}}
-; GFX1310: ; Occupancy: 6{{$}}
+; GFX1310W32WG: ; Occupancy: 6{{$}}
+; GFX1310W32CU: ; Occupancy: 5{{$}}
+; GFX1310W64WG: ; Occupancy: 6{{$}}
+; GFX1310W64CU: ; Occupancy: 5{{$}}
define amdgpu_kernel void @used_lds_8252_max_group_size_32() #10 {
store volatile i8 1, ptr addrspace(3) @lds8252
ret void
>From bbb06d5c69f661405454551522ca4f59b053a885 Mon Sep 17 00:00:00 2001
From: Mariusz Sikora <mariusz.sikora at amd.com>
Date: Fri, 7 Aug 2026 03:17:45 -0400
Subject: [PATCH 3/5] Stop using CU / WGP
---
llvm/lib/Target/AMDGPU/AMDGPUFeatures.td | 4 ++--
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp | 10 +++++-----
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h | 4 ++--
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td b/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td
index 1dc62ded656f7..c38be3b43eb50 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUFeatures.td
@@ -47,8 +47,8 @@ def FeatureAddressableLocalMemorySize327680 : SubtargetFeatureAddressableLocalMe
// Total size of LDS on the whole block, in bytes. Set this only when it is
// larger than the addressable size, i.e. when one workgroup cannot use the whole
-// block (e.g. gfx10/11/12: a block is two 64k CUs => 128k total). If not set, it
-// defaults to the addressable size.
+// block (e.g. gfx10/11/12: 128k physical block vs 64k addressable). If not set,
+// it defaults to the addressable size.
class SubtargetFeatureLocalMemorySize <int Value> : SubtargetFeature<
"localmemorysize"#Value,
"LocalMemorySize",
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index b86426dd69e48..248cad3459121 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1177,7 +1177,7 @@ unsigned getWavefrontSize(const MCSubtargetInfo &STI) {
}
// Maximum LDS a single work-group can address. This is the fixed HW addressing
-// cap and does not depend on CU/WGP (full-SIMD) mode.
+// cap and is independent of whether a work-group runs on four SIMDs or two.
static unsigned getMaxHWAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
if (STI.getFeatureBits().test(FeatureAddressableLocalMemorySize32768))
return 32768;
@@ -1194,8 +1194,8 @@ static unsigned getMaxHWAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
// Total physical LDS on the block. On some targets a single work-group cannot
// address the whole block, so the physical size is larger than the addressable
-// size; those set FeatureLocalMemorySize (gfx10/11/12: two 64k CUs => 128k).
-// Otherwise it defaults to the addressable size.
+// size; those set FeatureLocalMemorySize (gfx10/11/12: 128k physical vs 64k
+// addressable). Otherwise it defaults to the addressable size.
static unsigned getPhysicalLocalMemorySize(const MCSubtargetInfo &STI) {
if (STI.getFeatureBits().test(FeatureLocalMemorySize131072))
return 131072;
@@ -1203,7 +1203,7 @@ static unsigned getPhysicalLocalMemorySize(const MCSubtargetInfo &STI) {
}
unsigned getLocalMemorySize(const MCSubtargetInfo &STI) {
- // Total LDS on the block, halved in CU (half-WGP) mode.
+ // Total LDS on the block, halved when a work-group runs on two SIMDs, not four.
unsigned Size = getPhysicalLocalMemorySize(STI);
if (!isFullSIMDMode(STI))
Size /= 2;
@@ -1217,7 +1217,7 @@ unsigned getAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
}
unsigned getEUsPerCU(const MCSubtargetInfo &STI) {
- // Four SIMD32s in full SIMD mode, two in CU (half-WGP) mode.
+ // Four SIMD32s when a work-group runs on all of them, two otherwise.
return isFullSIMDMode(STI) ? 4 : 2;
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index e7597fc0e5e82..18772b9537103 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -1514,8 +1514,8 @@ bool isGFX1250Plus(const MCSubtargetInfo &STI);
bool isGFX13(const MCSubtargetInfo &STI);
bool isGFX13Plus(const MCSubtargetInfo &STI);
-/// \returns true if waves in a work-group span all four SIMD32s (one contiguous
-/// LDS), i.e. not half-WGP/CU mode.
+/// \returns true if a work-group's waves run on all four SIMD32s (one
+/// contiguous LDS) rather than on only two.
bool isFullSIMDMode(const MCSubtargetInfo &STI);
bool supportsWGP(const MCSubtargetInfo &STI);
>From 958515055aff65e32963ee67370a5d6c4d0ed7e0 Mon Sep 17 00:00:00 2001
From: Mariusz Sikora <mariusz.sikora at amd.com>
Date: Fri, 7 Aug 2026 10:20:09 -0400
Subject: [PATCH 4/5] Update comments about LDS size
---
.../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp | 20 +++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 248cad3459121..0de742a1a1999 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1192,26 +1192,34 @@ static unsigned getMaxHWAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
return 32768;
}
-// Total physical LDS on the block. On some targets a single work-group cannot
-// address the whole block, so the physical size is larger than the addressable
-// size; those set FeatureLocalMemorySize (gfx10/11/12: 128k physical vs 64k
-// addressable). Otherwise it defaults to the addressable size.
+// Total LDS on the block. Larger than the addressable size when a work-group
+// cannot address the whole block. Defaults to the addressable size otherwise.
static unsigned getPhysicalLocalMemorySize(const MCSubtargetInfo &STI) {
if (STI.getFeatureBits().test(FeatureLocalMemorySize131072))
return 131072;
return getMaxHWAddressableLocalMemorySize(STI);
}
+// Sizes in use, by generation (addressable / physical block):
+// gfx6 : 32 KiB
+// gfx7 / gfx8 / gfx9: 64 KiB
+// gfx9.5 (gfx950) : 160 KiB
+// gfx10 / 11 / 12 : 64 KiB addressable, 128 KiB physical block
+// gfx12.5 (gfx1250) : 320 KiB (always runs on four SIMDs)
+// gfx13 : 192 KiB on four SIMDs, 96 KiB on two
+// Total available in the current mode, that is the physical size halved when a
+// work-group runs on two SIMDs.
unsigned getLocalMemorySize(const MCSubtargetInfo &STI) {
- // Total LDS on the block, halved when a work-group runs on two SIMDs, not four.
unsigned Size = getPhysicalLocalMemorySize(STI);
if (!isFullSIMDMode(STI))
Size /= 2;
return Size;
}
+// What one work-group can allocate in the current mode. This is the HW
+// addressable cap, but no more than is available in the current mode (two SIMDs
+// / four SIMDs).
unsigned getAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
- // HW addressing cap, but no more than is available in the current mode.
return std::min(getMaxHWAddressableLocalMemorySize(STI),
getLocalMemorySize(STI));
}
>From 18cb8f16609cf685fcb3ba5e93d20ff23f73d5d9 Mon Sep 17 00:00:00 2001
From: Mariusz Sikora <mariusz.sikora at amd.com>
Date: Fri, 7 Aug 2026 11:10:09 -0400
Subject: [PATCH 5/5] undef -> poison
---
llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll b/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll
index e0ad7a2dc979d..39e39ada9167a 100644
--- a/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll
+++ b/llvm/test/CodeGen/AMDGPU/lds-limit-diagnostics-gfx13.ll
@@ -8,7 +8,7 @@
; ERROR: error: <unknown>:0:0: local memory (196612) exceeds limit (196608) in function 'test_lds_limit'
; ERROR-CU: error: <unknown>:0:0: local memory (196612) exceeds limit (98304) in function 'test_lds_limit'
- at dst = addrspace(3) global [196612 x i8] undef
+ at dst = addrspace(3) global [196612 x i8] poison
define amdgpu_kernel void @test_lds_limit(i8 %val) {
%gep = getelementptr [196612 x i8], ptr addrspace(3) @dst, i32 0, i32 100
More information about the llvm-commits
mailing list