[clang] [llvm] [DXIL] Remove incompatible metadata types when preparing DXIL. (PR #136386)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 18 16:14:44 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-directx
Author: Joshua Batista (bob80905)
<details>
<summary>Changes</summary>
This PR introduces a Metadata Node Kind whitelist. The purpose is to prevent newer Metadata Node Kinds to be used and inserted into the outputted DXIL module. The Github DXC validator doesn't support these newer Metadata Node Kinds, so we need to filter them out.
In Github DXC, `lib\HLSL\DxilPreparePasses.cpp:814`, there is a loop:
```
for (unsigned I = LLVMContext::MD_fpmath + 1;
I <= LLVMContext::MD_dereferenceable_or_null; ++I) {
IllegalMDSet.insert(I);
}
```
that loops up to and including the last metadata node kind that should be disallowed in the current context. I believe this code shows that there are no other metadata nodes to be allowed, setting aside the explicit list shown in `lib\IR\LLVMContext.cpp:34`
So, given that this is the world of acceptable metadata node kinds, we introduce this restrictive whitelist into LLVM and strip all metadata that isn't found in the list.
The accompanying test would add the loop.llvm.mustprogress metadata node kind, but thanks to the whitelist, filters it out, and so the whitelist is proven to work.
---
Full diff: https://github.com/llvm/llvm-project/pull/136386.diff
2 Files Affected:
- (added) clang/test/CodeGenHLSL/metadata-stripping.hlsl (+13)
- (modified) llvm/lib/Target/DirectX/DXILPrepare.cpp (+20)
``````````diff
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);
``````````
</details>
https://github.com/llvm/llvm-project/pull/136386
More information about the llvm-commits
mailing list