[llvm] AMDGPU/GlobalISel: RegBankLegalize rules for transpose loads (PR #192766)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 17 21:29:27 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: vangthao95

<details>
<summary>Changes</summary>

Adds RegBankLegalize rules for:
  - amdgcn_global_load_tr4_b64 / tr6_b96
  - amdgcn_ds_load_tr4_b64 / tr6_b96 / tr8_b64 / tr16_b128

Extends the existing amdgcn_global_load_tr_b64 / tr_b128 rules with a Uni/Div pointer split, so divergent VGPR pointers select the VADDR form while uniform pointers still select SADDR.

---
Full diff: https://github.com/llvm/llvm-project/pull/192766.diff


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp (+25-4) 
- (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.global.load.tr-w64.ll (+34) 
- (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.load.tr.gfx1250.w32.ll (+1-1) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
index 03b9ea9397650..6b8d49ff901f8 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp
@@ -1709,12 +1709,33 @@ RegBankLegalizeRules::RegBankLegalizeRules(const GCNSubtarget &_ST,
       .Div(V2S16, {{VgprV2S16}, {IntrId, Vgpr32, Vgpr32}});
 
   addRulesForIOpcs({amdgcn_global_load_tr_b64})
-      .Any({{DivB64}, {{VgprB64}, {IntrId, SgprP1}}})
-      .Any({{DivB32}, {{VgprB32}, {IntrId, SgprP1}}});
+      .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1}}})
+      .Any({{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1}}})
+      .Any({{DivB32, _, UniP1}, {{VgprB32}, {IntrId, SgprP1}}})
+      .Any({{DivB32, _, DivP1}, {{VgprB32}, {IntrId, VgprP1}}});
 
   addRulesForIOpcs({amdgcn_global_load_tr_b128})
-      .Any({{DivB64}, {{VgprB64}, {IntrId, SgprP1}}})
-      .Any({{DivB128}, {{VgprB128}, {IntrId, SgprP1}}});
+      .Any({{DivB64, _, UniP1}, {{VgprB64}, {IntrId, SgprP1}}})
+      .Any({{DivB64, _, DivP1}, {{VgprB64}, {IntrId, VgprP1}}})
+      .Any({{DivB128, _, UniP1}, {{VgprB128}, {IntrId, SgprP1}}})
+      .Any({{DivB128, _, DivP1}, {{VgprB128}, {IntrId, VgprP1}}});
+
+  addRulesForIOpcs({amdgcn_global_load_tr4_b64})
+      .Any({{DivV2S32, _, UniP1}, {{VgprV2S32}, {IntrId, SgprP1}}})
+      .Any({{DivV2S32, _, DivP1}, {{VgprV2S32}, {IntrId, VgprP1}}});
+
+  addRulesForIOpcs({amdgcn_global_load_tr6_b96})
+      .Any({{DivV3S32, _, UniP1}, {{VgprV3S32}, {IntrId, SgprP1}}})
+      .Any({{DivV3S32, _, DivP1}, {{VgprV3S32}, {IntrId, VgprP1}}});
+
+  addRulesForIOpcs({amdgcn_ds_load_tr4_b64, amdgcn_ds_load_tr8_b64})
+      .Any({{DivV2S32}, {{VgprV2S32}, {IntrId, VgprP3}}});
+
+  addRulesForIOpcs({amdgcn_ds_load_tr6_b96})
+      .Any({{DivV3S32}, {{VgprV3S32}, {IntrId, VgprP3}}});
+
+  addRulesForIOpcs({amdgcn_ds_load_tr16_b128})
+      .Any({{DivB128}, {{VgprB128}, {IntrId, VgprP3}}});
 
   addRulesForIOpcs({amdgcn_global_atomic_ordered_add_b64})
       .Any({{DivS64}, {{Vgpr64}, {IntrId, VgprP1, Vgpr64}}});
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.global.load.tr-w64.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.global.load.tr-w64.ll
index 03305af9b598a..d34593f431f08 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.global.load.tr-w64.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.global.load.tr-w64.ll
@@ -74,3 +74,37 @@ entry:
   store <4 x bfloat> %val, ptr addrspace(1) %use
   ret void
 }
+
+define i32 @global_load_tr_b64_i32_vaddr(ptr addrspace(1) %addr) {
+; GFX12-LABEL: global_load_tr_b64_i32_vaddr:
+; GFX12:       ; %bb.0: ; %entry
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    global_load_tr_b64 v0, v[0:1], off offset:32
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %gep = getelementptr i64, ptr addrspace(1) %addr, i32 4
+  %val = call i32 @llvm.amdgcn.global.load.tr.b64.i32.p1(ptr addrspace(1) %gep)
+  ret i32 %val
+}
+
+define <4 x i16> @global_load_tr_b128_v4i16_vaddr(ptr addrspace(1) %addr) {
+; GFX12-LABEL: global_load_tr_b128_v4i16_vaddr:
+; GFX12:       ; %bb.0: ; %entry
+; GFX12-NEXT:    s_wait_loadcnt_dscnt 0x0
+; GFX12-NEXT:    s_wait_expcnt 0x0
+; GFX12-NEXT:    s_wait_samplecnt 0x0
+; GFX12-NEXT:    s_wait_bvhcnt 0x0
+; GFX12-NEXT:    s_wait_kmcnt 0x0
+; GFX12-NEXT:    global_load_tr_b128 v[0:1], v[0:1], off offset:32
+; GFX12-NEXT:    s_wait_loadcnt 0x0
+; GFX12-NEXT:    s_setpc_b64 s[30:31]
+entry:
+  %gep = getelementptr i64, ptr addrspace(1) %addr, i32 4
+  %val = call <4 x i16> @llvm.amdgcn.global.load.tr.b128.v4i16.p1(ptr addrspace(1) %gep)
+  ret <4 x i16> %val
+}
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.load.tr.gfx1250.w32.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.load.tr.gfx1250.w32.ll
index b93163f2238ae..829f01af4d144 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.load.tr.gfx1250.w32.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.load.tr.gfx1250.w32.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 -mattr=+wavefrontsize32,-wavefrontsize64 < %s | FileCheck -check-prefixes=GFX1250,GFX1250-SDAG %s
-; RUN: llc -global-isel=1 -global-isel-abort=2 -mtriple=amdgcn -mcpu=gfx1250 -mattr=+wavefrontsize32,-wavefrontsize64 < %s | FileCheck -check-prefixes=GFX1250,GFX1250-GISEL %s
+; RUN: llc -global-isel=1 -new-reg-bank-select -global-isel-abort=2 -mtriple=amdgcn -mcpu=gfx1250 -mattr=+wavefrontsize32,-wavefrontsize64 < %s | FileCheck -check-prefixes=GFX1250,GFX1250-GISEL %s
 
 define amdgpu_ps void @global_load_tr4_b64_vaddr(ptr addrspace(1) %addr, ptr addrspace(1) %use) {
 ; GFX1250-LABEL: global_load_tr4_b64_vaddr:

``````````

</details>


https://github.com/llvm/llvm-project/pull/192766


More information about the llvm-commits mailing list