[llvm-branch-commits] [llvm] [DirectX] Update `dxil-resource-access` to handle access of resources with a struct that produce a gep (PR #211384)
Deric C. via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 13 14:13:58 PDT 2026
Icohedron wrote:
Testing the PR locally, I found a bug where the flattened GEP offset is misinterpreted as a cbuffer row index:
```llvm
; cbuffer byte-offset i8 GEP is reinterpreted as a row index
;
; @cb_single_handle : one handle -> legalizeResourceHandles does not fire
; @cb_phi_handle : two handles -> legalizeResourceHandles fires, and
; rewrites the typed GEP into `getelementptr i8, ..., %idx*16`
;
%__cblayout_CB = type <{ <{ [9 x <{ <3 x i32>, target("dx.Padding", 4) }>], <3 x i32> }> }>
@CB.str = private unnamed_addr constant [3 x i8] c"CB\00"
define void @cb_single_handle(ptr %dst, i32 %idx) {
entry:
%h0 = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding(i32 1, i32 0, i32 2, i32 0, ptr @CB.str)
%p0 = call ptr addrspace(2) @llvm.dx.resource.getpointer(target("dx.CBuffer", %__cblayout_CB) %h0, i32 0)
%gep = getelementptr <{ <3 x i32>, target("dx.Padding", 4) }>, ptr addrspace(2) %p0, i32 %idx
%ld = load <3 x i32>, ptr addrspace(2) %gep, align 16
%e = extractelement <3 x i32> %ld, i32 0
store i32 %e, ptr %dst, align 4
ret void
}
define void @cb_phi_handle(ptr %dst, i1 %cond, i32 %idx) {
entry:
%h0 = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding(i32 1, i32 0, i32 2, i32 0, ptr @CB.str)
%p0 = call ptr addrspace(2) @llvm.dx.resource.getpointer(target("dx.CBuffer", %__cblayout_CB) %h0, i32 0)
br i1 %cond, label %if.then, label %main
if.then:
%h1 = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding(i32 1, i32 0, i32 2, i32 1, ptr @CB.str)
%p1 = call ptr addrspace(2) @llvm.dx.resource.getpointer(target("dx.CBuffer", %__cblayout_CB) %h1, i32 0)
br label %main
main:
%pp = phi ptr addrspace(2) [ %p0, %entry ], [ %p1, %if.then ]
%gep = getelementptr <{ <3 x i32>, target("dx.Padding", 4) }>, ptr addrspace(2) %pp, i32 %idx
%ld = load <3 x i32>, ptr addrspace(2) %gep, align 16
%e = extractelement <3 x i32> %ld, i32 0
store i32 %e, ptr %dst, align 4
ret void
}
```
Compiling with: `opt -S -disable-verify -dxil-resource-type -dxil-resource-access -mtriple=dxil-pc-shadermodel6.6-compute`
```llvm
define void @cb_single_handle(ptr %dst, i32 %idx) {
entry:
%h0 = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBst(i32 1, i32 0, i32 2, i32 0, ptr @CB.str)
; correct row at %idx
%ld.load = call { i32, i32, i32, i32 }
@llvm.dx.resource.load.cbufferrow.4.i32.i32.i32.i32.tdx.CBuffer_s___cblayout_CBst(target("dx.CBuffer", %__cblayout_CB) %h0, i32 %idx)
...
define void @cb_phi_handle(ptr %dst, i1 %cond, i32 %idx) {
entry:
br i1 %cond, label %if.then, label %main
if.then: ; preds = %entry
br label %main
main: ; preds = %if.then, %entry
%0 = phi i32 [ 0, %entry ], [ 1, %if.then ]
%1 = mul i32 %idx, 16
%2 = add i32 0, %1
%3 = call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBst(i32 1, i32 0, i32 2, i32 %0, ptr @CB.str)
; incorrect row: %2 = %idx * 16
%ld.load = call { i32, i32, i32, i32 } @llvm.dx.resource.load.cbufferrow.4.i32.i32.i32.i32.tdx.CBuffer_s___cblayout_CBst(target("dx.CBuffer", %__cblayout_CB) %3, i32 %2)
...
```
https://github.com/llvm/llvm-project/pull/211384
More information about the llvm-branch-commits
mailing list