[llvm] AMDGPU/GlobalISel: RegBankLegalize rules for cluster_load_b32/b64/b128 (PR #196186)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 7 13:57:13 PDT 2026


https://github.com/vangthao95 updated https://github.com/llvm/llvm-project/pull/196186

>From 793141c0baa1c9084bf1fbfec1d38c9b558af309 Mon Sep 17 00:00:00 2001
From: Vang Thao <Vang.Thao at amd.com>
Date: Wed, 6 May 2026 16:56:53 -0400
Subject: [PATCH 1/2] AMDGPU/GlobalISel: RegBankLegalize rules for
 cluster_load_b32/b64/b128

---
 .../AMDGPU/AMDGPURegBankLegalizeRules.cpp     | 24 ++++++++
 .../AMDGPU/AMDGPURegBankLegalizeRules.h       |  2 +
 .../AMDGPU/llvm.amdgcn.cluster.load.ll        | 55 ++++++++++++++++++-
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 33611ee8e2768..e4f36da18ec70 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -134,6 +134,8 @@ bool matchUniformityAndLLT(Register Reg, UniformityLLTOpPredicateID UniID,
     return MRI.getType(Reg) == LLT::fixed_vector(2, 16) && MUI.isUniform(Reg);
   case UniV2S32:
     return MRI.getType(Reg) == LLT::fixed_vector(2, 32) && MUI.isUniform(Reg);
+  case UniV4S32:
+    return MRI.getType(Reg) == LLT::fixed_vector(4, 32) && MUI.isUniform(Reg);
   case UniB32:
     return MRI.getType(Reg).getSizeInBits() == 32 && MUI.isUniform(Reg);
   case UniB64:
@@ -193,6 +195,8 @@ bool matchUniformityAndLLT(Register Reg, UniformityLLTOpPredicateID UniID,
     return MRI.getType(Reg) == LLT::fixed_vector(2, 32) && MUI.isDivergent(Reg);
   case DivV3S32:
     return MRI.getType(Reg) == LLT::fixed_vector(3, 32) && MUI.isDivergent(Reg);
+  case DivV4S32:
+    return MRI.getType(Reg) == LLT::fixed_vector(4, 32) && MUI.isDivergent(Reg);
   case DivV4S16:
     return MRI.getType(Reg) == LLT::fixed_vector(4, 16) && MUI.isDivergent(Reg);
   case DivV6S32:
@@ -1872,6 +1876,26 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
                     amdgcn_global_store_async_from_lds_b128})
       .Any({{}, {{}, {IntrId, VgprP1, VgprP3}}});
 
+  addRulesForIOpcs({amdgcn_cluster_load_b32})
+      .Any({{UniB32}, {{UniInVgprB32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivB32, _, UniP1}, {{VgprB32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any(
+          {{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
+
+  addRulesForIOpcs({amdgcn_cluster_load_b64})
+      .Any({{UniV2S32}, {{UniInVgprV2S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivV2S32, _, UniP1},
+            {{VgprV2S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivV2S32, _, DivP1},
+            {{VgprV2S32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
+
+  addRulesForIOpcs({amdgcn_cluster_load_b128})
+      .Any({{UniV4S32}, {{UniInVgprV4S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivV4S32, _, UniP1},
+            {{VgprV4S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivV4S32, _, DivP1},
+            {{VgprV4S32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
+
   addRulesForIOpcs({amdgcn_cluster_load_async_to_lds_b8,
                     amdgcn_cluster_load_async_to_lds_b32,
                     amdgcn_cluster_load_async_to_lds_b64,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
index 35bbefb54d29e..b0eb21607f9e5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
@@ -103,12 +103,14 @@ enum UniformityLLTOpPredicateID {
 
   UniV2S16,
   UniV2S32,
+  UniV4S32,
   UniV2S64,
 
   DivV2S16,
   DivV2S32,
   DivV2S64,
   DivV3S32,
+  DivV4S32,
   DivV4S16,
   DivV6S32,
 
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.cluster.load.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.cluster.load.ll
index 5a9f954b6d9f0..b2ccd23117fcc 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.cluster.load.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.cluster.load.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1250 -O3 < %s | FileCheck -check-prefixes=GFX1250,GFX1250-SDAG %s
-; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1250 -O3 < %s | FileCheck -check-prefixes=GFX1250,GFX1250-GISEL %s
+; RUN: llc -global-isel=1 -new-reg-bank-select -mtriple=amdgcn -mcpu=gfx1250 -O3 < %s | FileCheck -check-prefixes=GFX1250,GFX1250-GISEL %s
 
 declare i32 @llvm.amdgcn.cluster.load.b32.i32.p1(ptr addrspace(1), i32 %cpol, i32 %mask)
 declare <2 x i32> @llvm.amdgcn.cluster.load.b64.v2i32.p1(ptr addrspace(1), i32 %cpol, i32 %mask)
@@ -189,6 +189,59 @@ entry:
   store <4 x i32> %val, ptr addrspace(1) %use
   ret void
 }
+define amdgpu_ps void @cluster_load_b32_saddr_vmask(ptr addrspace(1) inreg %addr, ptr addrspace(1) %use, i32 %mask) {
+; GFX1250-LABEL: cluster_load_b32_saddr_vmask:
+; GFX1250:       ; %bb.0: ; %entry
+; GFX1250-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1250-NEXT:    v_readfirstlane_b32 s2, v2
+; GFX1250-NEXT:    v_mov_b32_e32 v2, 0
+; GFX1250-NEXT:    s_mov_b32 m0, s2
+; GFX1250-NEXT:    cluster_load_b32 v2, v2, s[0:1] offset:32 th:TH_LOAD_NT
+; GFX1250-NEXT:    s_wait_loadcnt 0x0
+; GFX1250-NEXT:    global_store_b32 v[0:1], v2, off
+; GFX1250-NEXT:    s_endpgm
+entry:
+  %gep = getelementptr i64, ptr addrspace(1) %addr, i32 4
+  %val = call i32 @llvm.amdgcn.cluster.load.b32.i32.p1(ptr addrspace(1) %gep, i32 1, i32 %mask)
+  store i32 %val, ptr addrspace(1) %use
+  ret void
+}
+
+define amdgpu_ps void @cluster_load_b64_saddr_vmask(ptr addrspace(1) inreg %addr, ptr addrspace(1) %use, i32 %mask) {
+; GFX1250-LABEL: cluster_load_b64_saddr_vmask:
+; GFX1250:       ; %bb.0: ; %entry
+; GFX1250-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1250-NEXT:    v_readfirstlane_b32 s2, v2
+; GFX1250-NEXT:    v_mov_b32_e32 v2, 0
+; GFX1250-NEXT:    s_mov_b32 m0, s2
+; GFX1250-NEXT:    cluster_load_b64 v[2:3], v2, s[0:1] offset:32 th:TH_LOAD_NT
+; GFX1250-NEXT:    s_wait_loadcnt 0x0
+; GFX1250-NEXT:    global_store_b64 v[0:1], v[2:3], off
+; GFX1250-NEXT:    s_endpgm
+entry:
+  %gep = getelementptr i64, ptr addrspace(1) %addr, i32 4
+  %val = call <2 x i32> @llvm.amdgcn.cluster.load.b64.v2i32.p1(ptr addrspace(1) %gep, i32 1, i32 %mask)
+  store <2 x i32> %val, ptr addrspace(1) %use
+  ret void
+}
+
+define amdgpu_ps void @cluster_load_b128_saddr_vmask(ptr addrspace(1) inreg %addr, ptr addrspace(1) %use, i32 %mask) {
+; GFX1250-LABEL: cluster_load_b128_saddr_vmask:
+; GFX1250:       ; %bb.0: ; %entry
+; GFX1250-NEXT:    s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; GFX1250-NEXT:    v_readfirstlane_b32 s2, v2
+; GFX1250-NEXT:    v_mov_b32_e32 v2, 0
+; GFX1250-NEXT:    s_mov_b32 m0, s2
+; GFX1250-NEXT:    cluster_load_b128 v[2:5], v2, s[0:1] offset:32 th:TH_LOAD_NT
+; GFX1250-NEXT:    s_wait_loadcnt 0x0
+; GFX1250-NEXT:    global_store_b128 v[0:1], v[2:5], off
+; GFX1250-NEXT:    s_endpgm
+entry:
+  %gep = getelementptr i64, ptr addrspace(1) %addr, i32 4
+  %val = call <4 x i32> @llvm.amdgcn.cluster.load.b128.v4i32.p1(ptr addrspace(1) %gep, i32 1, i32 %mask)
+  store <4 x i32> %val, ptr addrspace(1) %use
+  ret void
+}
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
 ; GFX1250-GISEL: {{.*}}
 ; GFX1250-SDAG: {{.*}}

>From 17451e9c6a1c8c739f4dda6a79847dfd54946459 Mon Sep 17 00:00:00 2001
From: Vang Thao <Vang.Thao at amd.com>
Date: Thu, 7 May 2026 16:33:27 -0400
Subject: [PATCH 2/2] Use B64 and B128 types

---
 .../AMDGPU/AMDGPURegBankLegalizeRules.cpp     | 23 ++++++++-----------
 .../AMDGPU/AMDGPURegBankLegalizeRules.h       |  2 --
 2 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index e4f36da18ec70..a64df2081db27 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -134,8 +134,6 @@ bool matchUniformityAndLLT(Register Reg, UniformityLLTOpPredicateID UniID,
     return MRI.getType(Reg) == LLT::fixed_vector(2, 16) && MUI.isUniform(Reg);
   case UniV2S32:
     return MRI.getType(Reg) == LLT::fixed_vector(2, 32) && MUI.isUniform(Reg);
-  case UniV4S32:
-    return MRI.getType(Reg) == LLT::fixed_vector(4, 32) && MUI.isUniform(Reg);
   case UniB32:
     return MRI.getType(Reg).getSizeInBits() == 32 && MUI.isUniform(Reg);
   case UniB64:
@@ -195,8 +193,6 @@ bool matchUniformityAndLLT(Register Reg, UniformityLLTOpPredicateID UniID,
     return MRI.getType(Reg) == LLT::fixed_vector(2, 32) && MUI.isDivergent(Reg);
   case DivV3S32:
     return MRI.getType(Reg) == LLT::fixed_vector(3, 32) && MUI.isDivergent(Reg);
-  case DivV4S32:
-    return MRI.getType(Reg) == LLT::fixed_vector(4, 32) && MUI.isDivergent(Reg);
   case DivV4S16:
     return MRI.getType(Reg) == LLT::fixed_vector(4, 16) && MUI.isDivergent(Reg);
   case DivV6S32:
@@ -1883,18 +1879,17 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
           {{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
 
   addRulesForIOpcs({amdgcn_cluster_load_b64})
-      .Any({{UniV2S32}, {{UniInVgprV2S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
-      .Any({{DivV2S32, _, UniP1},
-            {{VgprV2S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
-      .Any({{DivV2S32, _, DivP1},
-            {{VgprV2S32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
+      .Any({{UniB64}, {{UniInVgprB64}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any(
+          {{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
 
   addRulesForIOpcs({amdgcn_cluster_load_b128})
-      .Any({{UniV4S32}, {{UniInVgprV4S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
-      .Any({{DivV4S32, _, UniP1},
-            {{VgprV4S32}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
-      .Any({{DivV4S32, _, DivP1},
-            {{VgprV4S32}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
+      .Any({{UniB128}, {{UniInVgprB128}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivB128, _, UniP1},
+            {{VgprB128}, {IntrId, SgprP1, Imm, SgprB32_M0}}})
+      .Any({{DivB128, _, DivP1},
+            {{VgprB128}, {IntrId, VgprP1, Imm, SgprB32_M0}}});
 
   addRulesForIOpcs({amdgcn_cluster_load_async_to_lds_b8,
                     amdgcn_cluster_load_async_to_lds_b32,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
index b0eb21607f9e5..35bbefb54d29e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h
@@ -103,14 +103,12 @@ enum UniformityLLTOpPredicateID {
 
   UniV2S16,
   UniV2S32,
-  UniV4S32,
   UniV2S64,
 
   DivV2S16,
   DivV2S32,
   DivV2S64,
   DivV3S32,
-  DivV4S32,
   DivV4S16,
   DivV6S32,
 



More information about the llvm-commits mailing list