[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