[DirectX] Apply DXIL op fnattrs to declarations#193622
Open
[DirectX] Apply DXIL op fnattrs to declarations#193622
Conversation
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 llvm#193620
Member
|
@llvm/pr-subscribers-backend-directx Author: Justin Bogner (bogner) ChangesWe need to apply DXIL op attributes to the functions themselves, and all DXIL ops should have the Fixes #193620 Patch is 150.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/193622.diff 51 Files Affected:
diff --git a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp
index 1f41d2457e5bc..66c7d03e2aa81 100644
--- a/llvm/lib/Target/DirectX/DXILOpBuilder.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpBuilder.cpp
@@ -470,18 +470,23 @@ static dxil::Attributes getDXILAttributes(dxil::OpCode OpCode,
// Retreive the set of DXIL Attributes given the version and map them to an
// llvm function attribute that is set onto the instruction
-static void setDXILAttributes(CallInst *CI, dxil::OpCode OpCode,
- VersionTuple DXILVersion) {
+static AttributeList getDXILFnAttributeList(LLVMContext &Ctx,
+ dxil::OpCode OpCode,
+ VersionTuple DXILVersion) {
dxil::Attributes Attributes = getDXILAttributes(OpCode, DXILVersion);
+ AttrBuilder FnAttrs(Ctx);
+
if (Attributes.ReadNone)
- CI->setDoesNotAccessMemory();
+ FnAttrs.addMemoryAttr(MemoryEffects::none());
if (Attributes.ReadOnly)
- CI->setOnlyReadsMemory();
+ FnAttrs.addMemoryAttr(MemoryEffects::readOnly());
if (Attributes.NoReturn)
- CI->setDoesNotReturn();
+ FnAttrs.addAttribute(Attribute::NoReturn);
if (Attributes.NoDuplicate)
- CI->setCannotDuplicate();
- return;
+ FnAttrs.addAttribute(Attribute::NoDuplicate);
+ FnAttrs.addAttribute(Attribute::NoUnwind);
+
+ return AttributeList::get(Ctx, AttributeList::FunctionIndex, FnAttrs);
}
namespace llvm {
@@ -569,8 +574,11 @@ Expected<CallInst *> DXILOpBuilder::tryCreateOp(dxil::OpCode OpCode,
if (!(ValidShaderKindMask & ModuleStagekind))
return makeOpError(OpCode, "Invalid stage");
+ AttributeList DXILFnAttrs =
+ getDXILFnAttributeList(M.getContext(), OpCode, DXILVersion);
std::string DXILFnName = constructOverloadName(Kind, OverloadTy, *Prop);
- FunctionCallee DXILFn = M.getOrInsertFunction(DXILFnName, DXILOpFT);
+ FunctionCallee DXILFn =
+ M.getOrInsertFunction(DXILFnName, DXILOpFT, DXILFnAttrs);
// We need to inject the opcode as the first argument.
SmallVector<Value *> OpArgs;
@@ -580,9 +588,6 @@ Expected<CallInst *> DXILOpBuilder::tryCreateOp(dxil::OpCode OpCode,
// Create the function call instruction
CallInst *CI = IRB.CreateCall(DXILFn, OpArgs, Name);
- // We then need to attach available function attributes
- setDXILAttributes(CI, OpCode, DXILVersion);
-
return CI;
}
diff --git a/llvm/test/CodeGen/DirectX/BufferLoad.ll b/llvm/test/CodeGen/DirectX/BufferLoad.ll
index 77f56a0f07b08..c3496a305777a 100644
--- a/llvm/test/CodeGen/DirectX/BufferLoad.ll
+++ b/llvm/test/CodeGen/DirectX/BufferLoad.ll
@@ -16,7 +16,7 @@ define void @loadv4f32() {
; The temporary casts should all have been cleaned up
; CHECK-NOT: %dx.resource.casthandle
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR:]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%load0 = call {<4 x float>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i32 0)
%data0 = extractvalue {<4 x float>, i1} %load0, 0
@@ -34,7 +34,7 @@ define void @loadv4f32() {
call void @scalar_user(float %data0_0)
call void @scalar_user(float %data0_2)
- ; CHECK: [[DATA4:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 4, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA4:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 4, i32 undef)
%load4 = call {<4 x float>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i32 4)
%data4 = extractvalue {<4 x float>, i1} %load4, 0
@@ -49,7 +49,7 @@ define void @loadv4f32() {
; CHECK: insertelement <4 x float>
call void @vector_user(<4 x float> %data4)
- ; CHECK: [[DATA12:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 12, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA12:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 12, i32 undef)
%load12 = call {<4 x float>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i32 12)
%data12 = extractvalue {<4 x float>, i1} %load12, 0
@@ -72,7 +72,7 @@ define void @index_dynamic(i32 %bufindex, i32 %elemindex) {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[LOAD:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 %bufindex, i32 undef) #[[#ATTR]]
+ ; CHECK: [[LOAD:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 %bufindex, i32 undef)
%load = call {<4 x float>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i32 %bufindex)
%data = extractvalue {<4 x float>, i1} %load, 0
@@ -108,7 +108,7 @@ define void @loadf32() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%load0 = call {float, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", float, 0, 0, 0) %buffer, i32 0)
%data0 = extractvalue {float, i1} %load0, 0
@@ -127,7 +127,7 @@ define void @loadv2f32() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v2f32_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%data0 = call {<2 x float>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <2 x float>, 0, 0, 0) %buffer, i32 0)
@@ -141,12 +141,12 @@ define void @loadv4f32_checkbit() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%data0 = call {<4 x float>, i1} @llvm.dx.resource.load.typedbuffer.f32(
target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i32 0)
; CHECK: [[STATUS:%.*]] = extractvalue %dx.types.ResRet.f32 [[DATA0]], 4
- ; CHECK: [[MAPPED:%.*]] = call i1 @dx.op.checkAccessFullyMapped.i32(i32 71, i32 [[STATUS]]) #[[#ATTR]]
+ ; CHECK: [[MAPPED:%.*]] = call i1 @dx.op.checkAccessFullyMapped.i32(i32 71, i32 [[STATUS]])
%check = extractvalue {<4 x float>, i1} %data0, 1
; CHECK: call void @check_user(i1 [[MAPPED]])
@@ -162,7 +162,7 @@ define void @loadv4i32() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4i32_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%data0 = call {<4 x i32>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x i32>, 0, 0, 0) %buffer, i32 0)
@@ -176,7 +176,7 @@ define void @loadv4f16() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f16_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f16 @dx.op.bufferLoad.f16(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.f16 @dx.op.bufferLoad.f16(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%data0 = call {<4 x half>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x half>, 0, 0, 0) %buffer, i32 0)
@@ -190,7 +190,7 @@ define void @loadv4i16() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4i16_0_0_0(
i32 0, i32 0, i32 1, i32 0, ptr null)
- ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.i16 @dx.op.bufferLoad.i16(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef) #[[#ATTR]]
+ ; CHECK: [[DATA0:%.*]] = call %dx.types.ResRet.i16 @dx.op.bufferLoad.i16(i32 68, %dx.types.Handle [[HANDLE]], i32 0, i32 undef)
%data0 = call {<4 x i16>, i1} @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <4 x i16>, 0, 0, 0) %buffer, i32 0)
@@ -199,34 +199,42 @@ define void @loadv4i16() {
define void @loadf64() {
; show dxil op lower can handle typedbuffer load where target is double but load type is <2 x i32>
- ; CHECK: [[B1:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 1, i1 false) #0
+ ; CHECK: [[B1:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 1, i1 false)
%buffer = call target("dx.TypedBuffer", double, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f64_1_0_0t(
i32 0, i32 1, i32 1, i32 0, ptr null)
- ; CHECK: [[BA:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[B1]], %dx.types.ResourceProperties { i32 4106, i32 266 }) #0
+ ; CHECK: [[BA:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[B1]], %dx.types.ResourceProperties { i32 4106, i32 266 })
%load = call { <2 x i32>, i1 } @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", double, 1, 0, 0) %buffer, i32 0)
-; CHECK: call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle [[BA]], i32 0, i32 undef) #1
+; CHECK: call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle [[BA]], i32 0, i32 undef)
%val = extractvalue { <2 x i32>, i1 } %load, 0
ret void
}
define void @loadv2f64() {
; show dxil op lower can handle typedbuffer load where target is double2 but load type is <4 x i32>
- ; CHECK: [[B1:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 1, i1 false) #0
+ ; CHECK: [[B1:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 1, i1 false)
%buffer = call target("dx.TypedBuffer", <2 x double>, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v2f64_1_0_0t(
i32 0, i32 1, i32 1, i32 0, ptr null)
- ; CHECK: [[BA:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[B1]], %dx.types.ResourceProperties { i32 4106, i32 522 }) #0
+ ; CHECK: [[BA:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[B1]], %dx.types.ResourceProperties { i32 4106, i32 522 })
%load = call { <4 x i32>, i1 } @llvm.dx.resource.load.typedbuffer(
target("dx.TypedBuffer", <2 x double>, 1, 0, 0) %buffer, i32 0)
- ; CHECK: call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle [[BA]], i32 0, i32 undef) #1
+ ; CHECK: call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle [[BA]], i32 0, i32 undef)
%val = extractvalue { <4 x i32>, i1 } %load, 0
ret void
}
-; CHECK: attributes #[[#ATTR]] = {{{.*}} memory(read) {{.*}}}
+; CHECK-DAG: declare %dx.types.Handle @dx.op.createHandleFromBinding(i32, %dx.types.ResBind, i32, i1) #[[#ATTR0:]]
+; CHECK-DAG: declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #[[#ATTR0]]
+; CHECK-DAG: declare %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32, %dx.types.Handle, i32, i32) #[[#ATTR1:]]
+; CHECK-DAG: declare %dx.types.ResRet.i16 @dx.op.bufferLoad.i16(i32, %dx.types.Handle, i32, i32) #[[#ATTR1]]
+; CHECK-DAG: declare %dx.types.ResRet.f16 @dx.op.bufferLoad.f16(i32, %dx.types.Handle, i32, i32) #[[#ATTR1]]
+; CHECK-DAG: declare %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32, %dx.types.Handle, i32, i32) #[[#ATTR1]]
+
+; CHECK-DAG: attributes #[[#ATTR0]] = { nounwind memory(none) }
+; CHECK-DAG: attributes #[[#ATTR1]] = { nounwind memory(read) }
diff --git a/llvm/test/CodeGen/DirectX/CreateHandle-NURI.ll b/llvm/test/CodeGen/DirectX/CreateHandle-NURI.ll
index cfa6c983df3f4..f0832d3382618 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandle-NURI.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandle-NURI.ll
@@ -19,7 +19,7 @@ define void @test_buffers_with_nuri() {
%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) #[[ATTR:.*]]
+ ; 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
@@ -29,14 +29,14 @@ define void @test_buffers_with_nuri() {
%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) #[[ATTR]]
+ ; 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) #[[ATTR]]
+ ; 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)
@@ -44,7 +44,7 @@ define void @test_buffers_with_nuri() {
%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) #[[ATTR]]
+ ; 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:
;
@@ -53,7 +53,7 @@ define void @test_buffers_with_nuri() {
%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) #[[ATTR]]
+ ; 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);
@@ -64,7 +64,7 @@ define void @test_buffers_with_nuri() {
ret void
}
-
-; CHECK: attributes #[[ATTR]] = {{{.*}} memory(read) {{.*}}}
+; 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) }
diff --git a/llvm/test/CodeGen/DirectX/CreateHandle.ll b/llvm/test/CodeGen/DirectX/CreateHandle.ll
index d92f4d369ad94..8e155a4702ad4 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandle.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandle.ll
@@ -26,14 +26,14 @@ define void @test_buffers() {
%typed0 = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_1_0_0(
i32 3, i32 5, i32 1, i32 0, ptr @BufA.str)
- ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 5, i1 false) #[[#ATTR:]]
+ ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 5, i1 false)
; CHECK-NOT: @llvm.dx.cast.handle
; RWBuffer<int> Buf : register(u7, space2)
%typed1 = call target("dx.TypedBuffer", i32, 1, 0, 1)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0_1t(
i32 2, i32 7, i32 1, i32 0, ptr null)
- ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 7, i1 false) #[[#ATTR]]
+ ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 7, i1 false)
; Buffer<uint4> Buf[24] : register(t3, space5)
; Buffer<uint4> typed2 = Buf[4]
@@ -41,20 +41,20 @@ define void @test_buffers() {
%typed2 = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_0_0_0t(
i32 5, i32 3, i32 24, i32 4, ptr @BufB.str)
- ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 3, i32 7, i1 false) #[[#ATTR]]
+ ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 3, i32 7, i1 false)
; struct S { float4 a; uint4 b; };
; StructuredBuffer<S> Buf : register(t2, space4)
%struct0 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
i32 4, i32 2, i32 1, i32 0, ptr null)
- ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 2, i32 2, i1 false) #[[#ATTR]]
+ ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 2, i32 2, i1 false)
; ByteAddressBuffer Buf : register(t8, space1)
%byteaddr0 = call target("dx.RawBuffer", i8, 0, 0)
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
i32 1, i32 8, i32 1, i32 0, ptr null)
- ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 1, i32 8, i1 false) #[[#ATTR]]
+ ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 1, i32 8, i1 false)
; Buffer<float4> Buf[] : register(t7)
; Buffer<float4> typed3 = Buf[ix]
@@ -63,12 +63,13 @@ define void @test_buffers() {
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_0_0_0t(
i32 0, i32 7, i32 0, i32 %typed3_ix, ptr null)
; CHECK: %[[IX:.*]] = add i32 %typed3_ix, 7
- ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 %[[IX]], i1 false) #[[#ATTR]]
+ ; CHECK: call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 %[[IX]], i1 false)
ret void
}
-; CHECK: attributes #[[#ATTR]] = {{{.*}} memory(read) {{.*}}}
+; CHECK: declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #[[#ATTR0:]]
+; CHECK: attributes #[[#ATTR0]] = { nounwind memory(read) }
; Just check that we have the right types and number of metadata nodes, the
; contents of the metadata are tested elsewhere.
diff --git a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding-NURI.ll b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding-NURI.ll
index 80bf5a6a67c91..d5f4f0d8d7d2a 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding-NURI.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding-NURI.ll
@@ -17,10 +17,10 @@ define void @test_buffers_with_nuri() {
; A[NonUniformResourceIndex(val)];
%nuri1 = tail call noundef i32 @llvm.dx.resource.nonuniformindex(i32 %val)
- %res1 = call target("dx.TypedBuffer", float, 1, 0, 0)
+ %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: %[[RES1:.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 0, i32 9, i32 0, i8 1 }, i32 ...
[truncated]
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
We need to apply DXIL op attributes to the functions themselves, and all DXIL ops should have the
unwindattribute. This matches the DXC behaviour and what consumers like warp's GPU-based validation expect.Fixes #193620