Files
llvm-project/llvm/test/CodeGen/DirectX/CreateHandle-NURI.ll
Justin Bogner deb84db5b4 [DirectX] Apply DXIL op fnattrs to declarations (#193622)
We need to apply DXIL op attributes to the functions themselves, and all
DXIL ops should have the `unwind` attribute. This matches the DXC
behaviour and what consumers like warp's GPU-based validation expect.

Fixes #193620
2026-04-24 09:54:04 -06:00

71 lines
3.1 KiB
LLVM

; RUN: opt -S -passes=dxil-op-lower %s | FileCheck %s
target triple = "dxil-pc-shadermodel6.0-compute"
@A.str = internal unnamed_addr constant [2 x i8] c"A\00", align 1
@B.str = internal unnamed_addr constant [2 x i8] c"A\00", align 1
declare i32 @some_val();
define void @test_buffers_with_nuri() {
%val = call i32 @some_val()
%foo = alloca i32, align 4
; RWBuffer<float> A[10];
;
; A[NonUniformResourceIndex(val)];
%nuri1 = tail call noundef i32 @llvm.dx.resource.nonuniformindex(i32 %val)
%res1 = call target("dx.TypedBuffer", float, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 10, i32 %nuri1, ptr @A.str)
; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 %val, i1 true)
; CHECK-NOT: @llvm.dx.cast.handle
; CHECK-NOT: @llvm.dx.resource.nonuniformindex
; A[NonUniformResourceIndex(val + 1) % 10];
%add1 = add i32 %val, 1
%nuri2 = tail call noundef i32 @llvm.dx.resource.nonuniformindex(i32 %add1)
%rem1 = urem i32 %nuri2, 10
%res2 = call target("dx.TypedBuffer", float, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 10, i32 %rem1, ptr @A.str)
; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 %rem1, i1 true)
; A[10 + 3 * NonUniformResourceIndex(GI)];
%mul1 = mul i32 %nuri1, 3
%add2 = add i32 %mul1, 10
%res3 = call target("dx.TypedBuffer", float, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 10, i32 %add2, ptr @A.str)
; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 %add2, i1 true)
; NonUniformResourceIndex value going through store & load - the flag is not going to get picked up:
%a = tail call noundef i32 @llvm.dx.resource.nonuniformindex(i32 %val)
store i32 %a, ptr %foo
%b = load i32, ptr %foo
%res4 = call target("dx.TypedBuffer", float, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 10, i32 %b, ptr @A.str)
; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 %b, i1 false)
; NonUniformResourceIndex index value on a single resouce (not an array) - the flag is not going to get picked up:
;
; RWBuffer<float> B : register(u20);
; B[NonUniformResourceIndex(val)];
%nuri3 = tail call noundef i32 @llvm.dx.resource.nonuniformindex(i32 %val)
%res5 = call target("dx.TypedBuffer", float, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 20, i32 0, i32 1, i32 %nuri1, ptr @B.str)
; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 %val, i1 false)
; NonUniformResourceIndex on unrelated value - the call is removed:
; foo = NonUniformResourceIndex(val);
%nuri4 = tail call noundef i32 @llvm.dx.resource.nonuniformindex(i32 %val)
store i32 %nuri4, ptr %foo
; CHECK: store i32 %val, ptr %foo
; CHECK-NOT: @llvm.dx.resource.nonuniformindex
ret void
}
; CHECK: declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #[[#ATTR0:]]
; CHECK: attributes #[[#ATTR0]] = { nounwind memory(read) }
attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }