https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/136386
>From c1a89d6896edd29ff345dd8fdc30cd040f3760f3 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 18 Apr 2025 16:06:18 -0700 Subject: [PATCH 1/6] add md node type filter, and test --- .../test/CodeGenHLSL/metadata-stripping.hlsl | 13 ++++++++++++ llvm/lib/Target/DirectX/DXILPrepare.cpp | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 clang/test/CodeGenHLSL/metadata-stripping.hlsl diff --git a/clang/test/CodeGenHLSL/metadata-stripping.hlsl b/clang/test/CodeGenHLSL/metadata-stripping.hlsl new file mode 100644 index 0000000000000..0178f5efe4c01 --- /dev/null +++ b/clang/test/CodeGenHLSL/metadata-stripping.hlsl @@ -0,0 +1,13 @@ +// RUN: %clang --driver-mode=dxc -T cs_6_0 -Fo x.dxil %s | FileCheck %s +// CHECK-NOT: llvm.loop.mustprogress + +StructuredBuffer<uint4> X : register(t0); +StructuredBuffer<float4> In : register(t1); +RWStructuredBuffer<float4> Out : register(u0); + +[numthreads(1, 1, 1)] +void main(uint3 dispatch_thread_id : SV_DispatchThreadID) { + for (uint I = 0; I < X[dispatch_thread_id].x; ++I) { + Out[dispatch_thread_id] = In[dispatch_thread_id]; + } +} diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp index de97de209048b..c54a5ac5c1227 100644 --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -189,6 +189,26 @@ class DXILPrepareModule : public ModulePass { for (auto &BB : F) { IRBuilder<> Builder(&BB); for (auto &I : make_early_inc_range(BB)) { + + // TODO: Audit this list - is it enough? Too much? + static unsigned DXILCompatibleMDs[] = { + LLVMContext::MD_dbg, + LLVMContext::MD_tbaa, + LLVMContext::MD_prof, + LLVMContext::MD_fpmath, + LLVMContext::MD_range, + LLVMContext::MD_tbaa_struct, + LLVMContext::MD_invariant_load, + LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, + LLVMContext::MD_nontemporal, + LLVMContext::MD_mem_parallel_loop_access, + LLVMContext::MD_nonnull, + LLVMContext::MD_dereferenceable, + LLVMContext::MD_dereferenceable_or_null, + }; + I.dropUnknownNonDebugMetadata(DXILCompatibleMDs); + if (I.getOpcode() == Instruction::FNeg) { Builder.SetInsertPoint(&I); Value *In = I.getOperand(0); >From 0399c6fdf33a1314a70089cdaf1529f2ab641b5a Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 23 Apr 2025 21:37:40 -0700 Subject: [PATCH 2/6] add dxil prepare pass --- .../CodeGen/DirectX/metadata-stripping.ll | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/metadata-stripping.ll diff --git a/llvm/test/CodeGen/DirectX/metadata-stripping.ll b/llvm/test/CodeGen/DirectX/metadata-stripping.ll new file mode 100644 index 0000000000000..92cc500d5cab7 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/metadata-stripping.ll @@ -0,0 +1,109 @@ +; RUN: opt -S --dxil-prepare %s | FileCheck %s + +source_filename = "C:\\Users\\jbatista\\Desktop\\particle_life.hlsl" +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxilv1.0-unknown-shadermodel6.0-compute" + +%StructuredBuffer = type { <4 x i32> } +%StructuredBuffer.1 = type { <4 x float> } +%RWStructuredBuffer = type { <4 x float> } +%dx.types.Handle = type { ptr } +%dx.types.ResRet.i32 = type { i32, i32, i32, i32, i32 } +%dx.types.ResRet.f32 = type { float, float, float, float, i32 } + +@0 = external constant %StructuredBuffer +@1 = external constant %StructuredBuffer.1 +@2 = external constant %RWStructuredBuffer + +; Function Attrs: noinline nounwind memory(readwrite, inaccessiblemem: none) +define void @main() local_unnamed_addr #0 { +entry: + %_ZL1X_h.i.i3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) #1 + %0 = call i32 @dx.op.threadId.i32(i32 93, i32 0) #2 + %1 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %_ZL1X_h.i.i3, i32 %0, i32 0) #1 + %2 = extractvalue %dx.types.ResRet.i32 %1, 0 + %cmp.i1.not = icmp eq i32 %2, 0 + br i1 %cmp.i1.not, label %_Z4mainDv3_j.exit, label %for.body.i.lr.ph + +for.body.i.lr.ph: ; preds = %entry + %_ZL3Out_h.i.i5 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) #1 + %_ZL2In_h.i.i4 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 1, i32 1, i1 false) #1 + %3 = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle %_ZL2In_h.i.i4, i32 %0, i32 0) #1 + %4 = extractvalue %dx.types.ResRet.f32 %3, 0 + %5 = extractvalue %dx.types.ResRet.f32 %3, 1 + %6 = extractvalue %dx.types.ResRet.f32 %3, 2 + %7 = extractvalue %dx.types.ResRet.f32 %3, 3 + br label %for.body.i + +for.body.i: ; preds = %for.body.i.lr.ph, %for.body.i + %I.0.i2 = phi i32 [ 0, %for.body.i.lr.ph ], [ %inc.i, %for.body.i ] + call void @dx.op.bufferStore.f32(i32 69, %dx.types.Handle %_ZL3Out_h.i.i5, i32 %0, i32 0, float %4, float %5, float %6, float %7, i8 15) + %inc.i = add nuw i32 %I.0.i2, 1 + %8 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %_ZL1X_h.i.i3, i32 %0, i32 0) #1 + %9 = extractvalue %dx.types.ResRet.i32 %8, 0 + ; CHECK: %cmp.i = icmp ult i32 %inc.i, %9 + ; CHECK-NEXT: br i1 %cmp.i, label %for.body.i, label %_Z4mainDv3_j.exit + %cmp.i = icmp ult i32 %inc.i, %9 + br i1 %cmp.i, label %for.body.i, label %_Z4mainDv3_j.exit, !llvm.loop !16 + +_Z4mainDv3_j.exit: ; preds = %for.body.i, %entry + ret void + +; uselistorder directives + uselistorder %dx.types.Handle %_ZL1X_h.i.i3, { 1, 0 } + uselistorder i32 %0, { 3, 0, 1, 2 } + uselistorder label %for.body.i, { 1, 0 } + } + +declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) + +declare i32 @dx.op.threadId.i32(i32, i32) + +declare %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32, %dx.types.Handle, i32, i32) + +declare %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32, %dx.types.Handle, i32, i32) + +declare void @dx.op.bufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8) + +; uselistorder directives +uselistorder i32 57, { 1, 0, 2 } +uselistorder i32 0, { 3, 0, 10, 1, 5, 6, 9, 2, 4, 7, 8 } +uselistorder i1 false, { 1, 0, 2 } +uselistorder i32 68, { 2, 0, 1 } +uselistorder i32 1, { 2, 0, 1 } +uselistorder ptr @dx.op.createHandle, { 2, 0, 1 } + +attributes #0 = { noinline nounwind memory(readwrite, inaccessiblemem: none) } +attributes #1 = { memory(read) } +attributes #2 = { memory(none) } + +!dx.valver = !{!0} +!llvm.ident = !{!1} +!dx.shaderModel = !{!2} +!dx.version = !{!3} +!dx.resources = !{!4} +!dx.entryPoints = !{!11} +!llvm.module.flags = !{!14, !15} + +!0 = !{i32 1, i32 8} +!1 = !{!"clang version 21.0.0git (https://github.com/llvm/llvm-project.git 9ed4c705ac1c5c8797f328694f6cd22fbcdae03b)"} +!2 = !{!"cs", i32 6, i32 0} +!3 = !{i32 1, i32 0} +!4 = !{!5, !9, null, null} +!5 = !{!6, !8} +!6 = !{i32 0, ptr @0, !"", i32 0, i32 0, i32 1, i32 12, i32 0, !7} +!7 = !{i32 1, i32 16} +!8 = !{i32 1, ptr @1, !"", i32 0, i32 1, i32 1, i32 12, i32 0, !7} +!9 = !{!10} +!10 = !{i32 0, ptr @2, !"", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !7} +!11 = !{ptr @main, !"main", null, !4, !12} +!12 = !{i32 0, i64 16, i32 4, !13} +!13 = !{i32 1, i32 1, i32 1} +!14 = !{i32 1, !"wchar_size", i32 4} +; CHECK: !15 = !{i32 2, !"frame-pointer", i32 2} +; this next line checks that nothing comes after the above check line. +; No more metadata should be necessary after !15, the rest should be removed. +; CHECK-NOT: . +!15 = !{i32 2, !"frame-pointer", i32 2} +!16 = distinct !{!16, !17} +!17 = !{!"llvm.loop.mustprogress"} >From 19de1553bf2f9b08f7d9d544c06cfb40423aaba7 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Wed, 23 Apr 2025 21:40:01 -0700 Subject: [PATCH 3/6] remove hlsl file --- clang/test/CodeGenHLSL/metadata-stripping.hlsl | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 clang/test/CodeGenHLSL/metadata-stripping.hlsl diff --git a/clang/test/CodeGenHLSL/metadata-stripping.hlsl b/clang/test/CodeGenHLSL/metadata-stripping.hlsl deleted file mode 100644 index 0178f5efe4c01..0000000000000 --- a/clang/test/CodeGenHLSL/metadata-stripping.hlsl +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %clang --driver-mode=dxc -T cs_6_0 -Fo x.dxil %s | FileCheck %s -// CHECK-NOT: llvm.loop.mustprogress - -StructuredBuffer<uint4> X : register(t0); -StructuredBuffer<float4> In : register(t1); -RWStructuredBuffer<float4> Out : register(u0); - -[numthreads(1, 1, 1)] -void main(uint3 dispatch_thread_id : SV_DispatchThreadID) { - for (uint I = 0; I < X[dispatch_thread_id].x; ++I) { - Out[dispatch_thread_id] = In[dispatch_thread_id]; - } -} >From 416084c9fbd09039b651e88106489cff6429438a Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Thu, 24 Apr 2025 17:44:29 -0700 Subject: [PATCH 4/6] drop tbaa and memparallelloopaccess, add 3 dx mds, simplify test --- llvm/lib/Target/DirectX/DXILPrepare.cpp | 41 +++++++++++-------- .../CodeGen/DirectX/metadata-stripping.ll | 41 +++---------------- 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp index c54a5ac5c1227..492477ed26e10 100644 --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -161,6 +161,26 @@ class DXILPrepareModule : public ModulePass { Builder.getPtrTy(PtrTy->getAddressSpace()))); } + static llvm::SmallVector<unsigned> getCompatibleInstructionMDs(Module &M) { + llvm::SmallVector<unsigned, 16> ret = { + M.getMDKindID("dx.nonuniform"), + M.getMDKindID("dx.controlflow.hints"), + M.getMDKindID("dx.precise"), + LLVMContext::MD_prof, + LLVMContext::MD_fpmath, + LLVMContext::MD_range, + LLVMContext::MD_tbaa_struct, + LLVMContext::MD_invariant_load, + LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, + LLVMContext::MD_nontemporal, + LLVMContext::MD_nonnull, + LLVMContext::MD_dereferenceable, + LLVMContext::MD_dereferenceable_or_null}; + + return ret; + } + public: bool runOnModule(Module &M) override { PointerTypeMap PointerTypes = PointerTypeAnalysis::run(M); @@ -176,6 +196,10 @@ class DXILPrepareModule : public ModulePass { VersionTuple ValVer = MetadataInfo.ValidatorVersion; bool SkipValidation = ValVer.getMajor() == 0 && ValVer.getMinor() == 0; + // construct whitelist of valid metadata node kinds + llvm::SmallVector<unsigned> DXILCompatibleMDs = + getCompatibleInstructionMDs(M); + for (auto &F : M.functions()) { F.removeFnAttrs(AttrMask); F.removeRetAttrs(AttrMask); @@ -190,23 +214,6 @@ class DXILPrepareModule : public ModulePass { IRBuilder<> Builder(&BB); for (auto &I : make_early_inc_range(BB)) { - // TODO: Audit this list - is it enough? Too much? - static unsigned DXILCompatibleMDs[] = { - LLVMContext::MD_dbg, - LLVMContext::MD_tbaa, - LLVMContext::MD_prof, - LLVMContext::MD_fpmath, - LLVMContext::MD_range, - LLVMContext::MD_tbaa_struct, - LLVMContext::MD_invariant_load, - LLVMContext::MD_alias_scope, - LLVMContext::MD_noalias, - LLVMContext::MD_nontemporal, - LLVMContext::MD_mem_parallel_loop_access, - LLVMContext::MD_nonnull, - LLVMContext::MD_dereferenceable, - LLVMContext::MD_dereferenceable_or_null, - }; I.dropUnknownNonDebugMetadata(DXILCompatibleMDs); if (I.getOpcode() == Instruction::FNeg) { diff --git a/llvm/test/CodeGen/DirectX/metadata-stripping.ll b/llvm/test/CodeGen/DirectX/metadata-stripping.ll index 92cc500d5cab7..5a1881e694fb1 100644 --- a/llvm/test/CodeGen/DirectX/metadata-stripping.ll +++ b/llvm/test/CodeGen/DirectX/metadata-stripping.ll @@ -17,41 +17,18 @@ target triple = "dxilv1.0-unknown-shadermodel6.0-compute" ; Function Attrs: noinline nounwind memory(readwrite, inaccessiblemem: none) define void @main() local_unnamed_addr #0 { -entry: - %_ZL1X_h.i.i3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 0, i32 0, i1 false) #1 - %0 = call i32 @dx.op.threadId.i32(i32 93, i32 0) #2 - %1 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %_ZL1X_h.i.i3, i32 %0, i32 0) #1 - %2 = extractvalue %dx.types.ResRet.i32 %1, 0 - %cmp.i1.not = icmp eq i32 %2, 0 - br i1 %cmp.i1.not, label %_Z4mainDv3_j.exit, label %for.body.i.lr.ph - -for.body.i.lr.ph: ; preds = %entry - %_ZL3Out_h.i.i5 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) #1 - %_ZL2In_h.i.i4 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 0, i32 1, i32 1, i1 false) #1 - %3 = call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 68, %dx.types.Handle %_ZL2In_h.i.i4, i32 %0, i32 0) #1 - %4 = extractvalue %dx.types.ResRet.f32 %3, 0 - %5 = extractvalue %dx.types.ResRet.f32 %3, 1 - %6 = extractvalue %dx.types.ResRet.f32 %3, 2 - %7 = extractvalue %dx.types.ResRet.f32 %3, 3 - br label %for.body.i - -for.body.i: ; preds = %for.body.i.lr.ph, %for.body.i - %I.0.i2 = phi i32 [ 0, %for.body.i.lr.ph ], [ %inc.i, %for.body.i ] - call void @dx.op.bufferStore.f32(i32 69, %dx.types.Handle %_ZL3Out_h.i.i5, i32 %0, i32 0, float %4, float %5, float %6, float %7, i8 15) - %inc.i = add nuw i32 %I.0.i2, 1 - %8 = call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 68, %dx.types.Handle %_ZL1X_h.i.i3, i32 %0, i32 0) #1 - %9 = extractvalue %dx.types.ResRet.i32 %8, 0 - ; CHECK: %cmp.i = icmp ult i32 %inc.i, %9 - ; CHECK-NEXT: br i1 %cmp.i, label %for.body.i, label %_Z4mainDv3_j.exit - %cmp.i = icmp ult i32 %inc.i, %9 +entry: + %cmp.i1.not = icmp eq i32 1, 0 + br i1 %cmp.i1.not, label %_Z4mainDv3_j.exit, label %for.body.i + +for.body.i: ; preds = %entry + %cmp.i = icmp ult i32 1, 2 br i1 %cmp.i, label %for.body.i, label %_Z4mainDv3_j.exit, !llvm.loop !16 _Z4mainDv3_j.exit: ; preds = %for.body.i, %entry ret void ; uselistorder directives - uselistorder %dx.types.Handle %_ZL1X_h.i.i3, { 1, 0 } - uselistorder i32 %0, { 3, 0, 1, 2 } uselistorder label %for.body.i, { 1, 0 } } @@ -66,12 +43,6 @@ declare %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32, %dx.types.Handle, i32, i declare void @dx.op.bufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8) ; uselistorder directives -uselistorder i32 57, { 1, 0, 2 } -uselistorder i32 0, { 3, 0, 10, 1, 5, 6, 9, 2, 4, 7, 8 } -uselistorder i1 false, { 1, 0, 2 } -uselistorder i32 68, { 2, 0, 1 } -uselistorder i32 1, { 2, 0, 1 } -uselistorder ptr @dx.op.createHandle, { 2, 0, 1 } attributes #0 = { noinline nounwind memory(readwrite, inaccessiblemem: none) } attributes #1 = { memory(read) } >From 84ad1d4bd23d80c1add9eaffa8783c8c77d22d52 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 25 Apr 2025 12:36:19 -0700 Subject: [PATCH 5/6] prune whitelist --- llvm/lib/Target/DirectX/DXILPrepare.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp index 492477ed26e10..649a328fe77dd 100644 --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -163,20 +163,9 @@ class DXILPrepareModule : public ModulePass { static llvm::SmallVector<unsigned> getCompatibleInstructionMDs(Module &M) { llvm::SmallVector<unsigned, 16> ret = { - M.getMDKindID("dx.nonuniform"), - M.getMDKindID("dx.controlflow.hints"), - M.getMDKindID("dx.precise"), - LLVMContext::MD_prof, - LLVMContext::MD_fpmath, - LLVMContext::MD_range, - LLVMContext::MD_tbaa_struct, - LLVMContext::MD_invariant_load, - LLVMContext::MD_alias_scope, - LLVMContext::MD_noalias, - LLVMContext::MD_nontemporal, - LLVMContext::MD_nonnull, - LLVMContext::MD_dereferenceable, - LLVMContext::MD_dereferenceable_or_null}; + M.getMDKindID("dx.nonuniform"), M.getMDKindID("dx.controlflow.hints"), + M.getMDKindID("dx.precise"), LLVMContext::MD_range, + LLVMContext::MD_alias_scope, LLVMContext::MD_noalias}; return ret; } >From fb2932e70e2220dfb56f7e37fb400d8d5a96f035 Mon Sep 17 00:00:00 2001 From: Joshua Batista <jbati...@microsoft.com> Date: Fri, 25 Apr 2025 15:19:11 -0700 Subject: [PATCH 6/6] address Justin --- llvm/lib/Target/DirectX/DXILPrepare.cpp | 17 ++-- .../CodeGen/DirectX/metadata-stripping.ll | 93 ++++++------------- 2 files changed, 34 insertions(+), 76 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp index 649a328fe77dd..27b797635817b 100644 --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -161,13 +161,13 @@ class DXILPrepareModule : public ModulePass { Builder.getPtrTy(PtrTy->getAddressSpace()))); } - static llvm::SmallVector<unsigned> getCompatibleInstructionMDs(Module &M) { - llvm::SmallVector<unsigned, 16> ret = { - M.getMDKindID("dx.nonuniform"), M.getMDKindID("dx.controlflow.hints"), - M.getMDKindID("dx.precise"), LLVMContext::MD_range, - LLVMContext::MD_alias_scope, LLVMContext::MD_noalias}; - - return ret; + static std::array<unsigned, 6> getCompatibleInstructionMDs(llvm::Module &M) { + return {M.getMDKindID("dx.nonuniform"), + M.getMDKindID("dx.controlflow.hints"), + M.getMDKindID("dx.precise"), + llvm::LLVMContext::MD_range, + llvm::LLVMContext::MD_alias_scope, + llvm::LLVMContext::MD_noalias}; } public: @@ -186,8 +186,7 @@ class DXILPrepareModule : public ModulePass { bool SkipValidation = ValVer.getMajor() == 0 && ValVer.getMinor() == 0; // construct whitelist of valid metadata node kinds - llvm::SmallVector<unsigned> DXILCompatibleMDs = - getCompatibleInstructionMDs(M); + std::array<unsigned, 6> DXILCompatibleMDs = getCompatibleInstructionMDs(M); for (auto &F : M.functions()) { F.removeFnAttrs(AttrMask); diff --git a/llvm/test/CodeGen/DirectX/metadata-stripping.ll b/llvm/test/CodeGen/DirectX/metadata-stripping.ll index 5a1881e694fb1..199e7dbc2d09a 100644 --- a/llvm/test/CodeGen/DirectX/metadata-stripping.ll +++ b/llvm/test/CodeGen/DirectX/metadata-stripping.ll @@ -1,80 +1,39 @@ ; RUN: opt -S --dxil-prepare %s | FileCheck %s -source_filename = "C:\\Users\\jbatista\\Desktop\\particle_life.hlsl" -target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" -target triple = "dxilv1.0-unknown-shadermodel6.0-compute" - -%StructuredBuffer = type { <4 x i32> } -%StructuredBuffer.1 = type { <4 x float> } -%RWStructuredBuffer = type { <4 x float> } -%dx.types.Handle = type { ptr } -%dx.types.ResRet.i32 = type { i32, i32, i32, i32, i32 } -%dx.types.ResRet.f32 = type { float, float, float, float, i32 } +; This test tests the whitelist inside of DxilPrepare.cpp. +; It ensures that certain metadata nodes are removed that aren't +; in the whitelist, and that certain nodes may remain that +; are on the whitelist. -@0 = external constant %StructuredBuffer -@1 = external constant %StructuredBuffer.1 -@2 = external constant %RWStructuredBuffer +target triple = "dxilv1.0-unknown-shadermodel6.0-compute" ; Function Attrs: noinline nounwind memory(readwrite, inaccessiblemem: none) -define void @main() local_unnamed_addr #0 { +define void @main(i32* %ptr) { entry: - %cmp.i1.not = icmp eq i32 1, 0 + ; metadata ID changes to 0 once the current !0 and !1 are removed + ; since they aren't in the whitelist. range needs a payload. + ; CHECK: %val = load i32, ptr %ptr, align 4, !range !0 + %val = load i32, ptr %ptr, align 4, !range !2 + + ; dx.nonuniform is a valid metadata node kind on the whitelist, + ; so give it a bogus payload and ensure it sticks around + ; CHECK-next: %cmp.i1.not = icmp eq i32 1, 0, !dx.nonuniform !0 + %cmp.i1.not = icmp eq i32 1, 0, !dx.nonuniform !2 br i1 %cmp.i1.not, label %_Z4mainDv3_j.exit, label %for.body.i for.body.i: ; preds = %entry %cmp.i = icmp ult i32 1, 2 - br i1 %cmp.i, label %for.body.i, label %_Z4mainDv3_j.exit, !llvm.loop !16 + br i1 %cmp.i, label %for.body.i, label %_Z4mainDv3_j.exit, !llvm.loop !0 _Z4mainDv3_j.exit: ; preds = %for.body.i, %entry ret void - -; uselistorder directives - uselistorder label %for.body.i, { 1, 0 } - } - -declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) - -declare i32 @dx.op.threadId.i32(i32, i32) - -declare %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32, %dx.types.Handle, i32, i32) - -declare %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32, %dx.types.Handle, i32, i32) - -declare void @dx.op.bufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8) - -; uselistorder directives - -attributes #0 = { noinline nounwind memory(readwrite, inaccessiblemem: none) } -attributes #1 = { memory(read) } -attributes #2 = { memory(none) } - -!dx.valver = !{!0} -!llvm.ident = !{!1} -!dx.shaderModel = !{!2} -!dx.version = !{!3} -!dx.resources = !{!4} -!dx.entryPoints = !{!11} -!llvm.module.flags = !{!14, !15} - -!0 = !{i32 1, i32 8} -!1 = !{!"clang version 21.0.0git (https://github.com/llvm/llvm-project.git 9ed4c705ac1c5c8797f328694f6cd22fbcdae03b)"} -!2 = !{!"cs", i32 6, i32 0} -!3 = !{i32 1, i32 0} -!4 = !{!5, !9, null, null} -!5 = !{!6, !8} -!6 = !{i32 0, ptr @0, !"", i32 0, i32 0, i32 1, i32 12, i32 0, !7} -!7 = !{i32 1, i32 16} -!8 = !{i32 1, ptr @1, !"", i32 0, i32 1, i32 1, i32 12, i32 0, !7} -!9 = !{!10} -!10 = !{i32 0, ptr @2, !"", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !7} -!11 = !{ptr @main, !"main", null, !4, !12} -!12 = !{i32 0, i64 16, i32 4, !13} -!13 = !{i32 1, i32 1, i32 1} -!14 = !{i32 1, !"wchar_size", i32 4} -; CHECK: !15 = !{i32 2, !"frame-pointer", i32 2} -; this next line checks that nothing comes after the above check line. -; No more metadata should be necessary after !15, the rest should be removed. -; CHECK-NOT: . -!15 = !{i32 2, !"frame-pointer", i32 2} -!16 = distinct !{!16, !17} -!17 = !{!"llvm.loop.mustprogress"} +} + +; CHECK: !0 = !{i32 1, i32 5} +; this next check line checks that nothing comes after the above check line. +; No more metadata should be necessary, the rest (the current 0 and 1) +; should be removed. +; CHECK-NOT: !{!"llvm.loop.mustprogress"} +!0 = distinct !{!0, !1} +!1 = !{!"llvm.loop.mustprogress"} +!2 = !{i32 1, i32 5} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits