[llvm] [DirectX] ForwardHandle needs to check if globals were stored on allocas (PR #151751)

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 1 13:01:08 PDT 2025


================
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -dxil-forward-handle-accesses  %s | FileCheck %s
+
+%"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", i32, 1, 0) }
+ at _ZL4dest = internal unnamed_addr global %"class.hlsl::RWStructuredBuffer" poison, align 4
+ at .str = private unnamed_addr constant [5 x i8] c"dest\00", align 1
+
+
+; NOTE: intent of this test is to confirm load target("dx.RawBuffer", i32, 1, 0)
+;       is replaced with call @llvm.dx.resource.getpointer
+define void @CSMain() local_unnamed_addr {
+; CHECK-LABEL: define void @CSMain() local_unnamed_addr {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[AGG_TMP_I1_SROA_0:%.*]] = alloca target("dx.RawBuffer", i32, 1, 0), align 8
+; CHECK-NEXT:    [[TMP0:%.*]] = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false, ptr nonnull @.str)
+; CHECK-NEXT:    store target("dx.RawBuffer", i32, 1, 0) [[TMP0]], ptr @_ZL4dest, align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i32 @llvm.dx.thread.id(i32 0)
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr @_ZL4dest, align 4
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[AGG_TMP_I1_SROA_0]])
+; CHECK-NEXT:    store i32 [[TMP2]], ptr [[AGG_TMP_I1_SROA_0]], align 8
+; CHECK-NEXT:    [[TMP3:%.*]] = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0) [[TMP0]], i32 [[TMP1]])
+; CHECK-NEXT:    store i32 0, ptr [[TMP3]], align 4
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[AGG_TMP_I1_SROA_0]])
----------------
bogner wrote:

The output here is a little scary, though I guess a lot of it is dead code. I guess if I'm reading it right the non-dead code here looks a bit like this?
```llvm
entry:
  %handle = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 3, i32 1, i32 0, i1 false, ptr nonnull @.str)
  %tid = tail call i32 @llvm.dx.thread.id(i32 0)
  call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %handle, i32 %tid, i32 0, i32 0)
  ret void
```

This is probably okay, but it doesn't look like anything cleans this up later - if I run the [example from #137715]( https://github.com/llvm/llvm-project/issues/137715#issuecomment-2856375398) through clang-dxc with this change we end up with a bunch of noise in the DXIL:
```llvm
define void @CSMain() {
entry:
  %agg.tmp.i1.sroa.0 = alloca target("dx.RawBuffer", i32, 1, 0), align 8
  %0 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 3, i1 false) #1
  %1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) #2
  %2 = bitcast ptr @_ZL4dest to ptr
  %3 = load i32, ptr %2, align 4
  %4 = bitcast ptr %agg.tmp.i1.sroa.0 to ptr
  store target("dx.RawBuffer", i32, 1, 0) undef, ptr %4, align 4
  %5 = bitcast ptr %agg.tmp.i1.sroa.0 to ptr
  store i32 %3, ptr %5, align 4
  call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %0, i32 %1, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4)
  %6 = bitcast ptr %agg.tmp.i1.sroa.0 to ptr
  store target("dx.RawBuffer", i32, 1, 0) undef, ptr %6, align 4
  ret void
}
````

This obviously fails in the bitcode writer for various reasons. Compare to [DXC](https://godbolt.org/z/fhbdPx8jq):
```llvm
define void @CSMain() {
  %dest_UAV_structbuf = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 3, i1 false)
  %1 = call i32 @dx.op.threadId.i32(i32 93, i32 0)
  call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %dest_UAV_structbuf, i32 %1, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4)
  ret void
}
```

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


More information about the llvm-commits mailing list