[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