[llvm] [DirectX] Use an allow-list of DXIL compatible module metadata (PR #165290)
Finn Plummer via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 29 12:08:55 PDT 2025
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/165290
>From 0c6079a84eedd52123d6f9e12dfb3375b8efe580 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Mon, 27 Oct 2025 10:22:16 -0700
Subject: [PATCH 1/5] [DirectX] Use an allow-list on module metadata
---
.../Target/DirectX/DXILTranslateMetadata.cpp | 35 +++++----
llvm/test/CodeGen/DirectX/strip-module-md.ll | 75 +++++++++++++++++++
2 files changed, 97 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/strip-module-md.ll
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index 1e4797bbd05aa..f7051efe6eb69 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -364,6 +364,16 @@ static void cleanModuleFlags(Module &M) {
M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
}
+using GlobalMDList = std::array<StringLiteral, 7>;
+
+// The following are compatible with DXIL but not emit with clang, they can
+// be added when applicable:
+// dx.typeAnnotations, dx.viewIDState, dx.dxrPayloadAnnotations
+static GlobalMDList CompatibleNamedModuleMDs = {
+ "llvm.ident", "llvm.module.flags", "dx.resources", "dx.valver",
+ "dx.shaderModel", "dx.version", "dx.entryPoints",
+};
+
static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
DXILResourceTypeMap &DRTM,
const ModuleShaderFlags &ShaderFlags,
@@ -426,19 +436,18 @@ static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
cleanModuleFlags(M);
- // dx.rootsignatures will have been parsed from its metadata form as its
- // binary form as part of the RootSignatureAnalysisWrapper, so safely
- // remove it as it is not recognized in DXIL
- if (NamedMDNode *RootSignature = M.getNamedMetadata("dx.rootsignatures"))
- RootSignature->eraseFromParent();
-
- // llvm.errno.tbaa was recently added but is not supported in LLVM 3.7 and
- // causes all tests using the DXIL Validator to fail.
- //
- // This is a temporary fix and should be replaced with a allowlist once
- // we have determined all metadata that the DXIL Validator allows
- if (NamedMDNode *ErrNo = M.getNamedMetadata("llvm.errno.tbaa"))
- ErrNo->eraseFromParent();
+ // Finally, strip all module metadata that is not explicitly specified in the
+ // allow-list
+ SmallVector<NamedMDNode *> ToStrip;
+
+ for (NamedMDNode &NamedMD : M.named_metadata()) {
+ if (!NamedMD.getName().starts_with("llvm.dbg.") &&
+ !llvm::is_contained(CompatibleNamedModuleMDs, NamedMD.getName()))
+ ToStrip.push_back(&NamedMD);
+ }
+
+ for (NamedMDNode *NamedMD : ToStrip)
+ NamedMD->eraseFromParent();
}
PreservedAnalyses DXILTranslateMetadata::run(Module &M,
diff --git a/llvm/test/CodeGen/DirectX/strip-module-md.ll b/llvm/test/CodeGen/DirectX/strip-module-md.ll
new file mode 100644
index 0000000000000..4d8b9ec935f6b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/strip-module-md.ll
@@ -0,0 +1,75 @@
+; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s
+
+; Ensures that only metadata explictly specified on the allow list, or debug
+; related, metadata is emitted
+
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+; CHECK-NOT: !dx.rootsignatures
+; CHECK-NOT: !llvm.errno.tbaa
+
+; CHECK-DAG: !llvm.dbg.cu
+
+; CHECK-DAG: !llvm.module.flags = !{![[#DWARF_VER:]], ![[#DEBUG_VER:]]}
+; CHECK-DAG: !llvm.ident = !{![[#IDENT:]]}
+
+; CHECK-DAG: !dx.shaderModel
+; CHECK-DAG: !dx.version
+; CHECK-DAG: !dx.entryPoints
+; CHECK-DAG: !dx.valver
+; CHECK-DAG: !dx.resources
+
+; CHECK-NOT: !dx.rootsignatures
+; CHECK-NOT: !llvm.errno.tbaa
+
+; Check allowed llvm metadata structure to ensure it is still DXIL compatible
+; If this fails, please ensure that the updated form is DXIL compatible before
+; updating the test.
+
+; CHECK-DAG: ![[#IDENT]] = !{!"clang 22.0.0"}
+; CHECK-DAG: ![[#DWARF_VER]] = !{i32 2, !"Dwarf Version", i32 2}
+; CHECK-DAG: ![[#DEBUG_VER]] = !{i32 2, !"Debug Info Version", i32 3}
+
+; CHECK-NOT: !dx.rootsignatures
+; CHECK-NOT: !llvm.errno.tbaa
+
+ at BufA.str = private unnamed_addr constant [5 x i8] c"BufA\00", align 1
+
+define void @main () #0 {
+entry:
+ %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)
+ ret void
+}
+
+attributes #0 = { noinline nounwind "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+; Incompatible
+!dx.rootsignatures = !{!2}
+!llvm.errno.tbaa = !{!5}
+
+; Compatible
+!llvm.dbg.cu = !{!8}
+!llvm.module.flags = !{!11, !12}
+!llvm.ident = !{!13}
+!dx.valver = !{!14}
+
+!2 = !{ ptr @main, !3, i32 2 }
+!3 = !{ !4 }
+!4 = !{ !"RootFlags", i32 1 }
+
+!5 = !{!6, !6, i64 0}
+!6 = !{!"omnipotent char", !7}
+!7 = !{!"Simple C/C++ TBAA"}
+
+!8 = distinct !DICompileUnit(language: DW_LANG_C99, file: !9, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !10, splitDebugInlining: false, nameTableKind: None)
+!9 = !DIFile(filename: "hlsl.hlsl", directory: "/some-path")
+!10 = !{}
+
+!11 = !{i32 2, !"Dwarf Version", i32 2}
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+
+!13 = !{!"clang 22.0.0"}
+
+!14 = !{i32 1, i32 1}
>From c7814967cbfe9df20bd1e59258e344a41f5a4132 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Mon, 27 Oct 2025 11:19:38 -0700
Subject: [PATCH 2/5] style-guide
---
llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index f7051efe6eb69..be31da15581a3 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -440,11 +440,10 @@ static void translateGlobalMetadata(Module &M, DXILResourceMap &DRM,
// allow-list
SmallVector<NamedMDNode *> ToStrip;
- for (NamedMDNode &NamedMD : M.named_metadata()) {
+ for (NamedMDNode &NamedMD : M.named_metadata())
if (!NamedMD.getName().starts_with("llvm.dbg.") &&
!llvm::is_contained(CompatibleNamedModuleMDs, NamedMD.getName()))
ToStrip.push_back(&NamedMD);
- }
for (NamedMDNode *NamedMD : ToStrip)
NamedMD->eraseFromParent();
>From 34d6d6137c74fcbcf74f8e9b8f67e4d8e865c478 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 29 Oct 2025 11:56:59 -0700
Subject: [PATCH 3/5] update md-manystrings to use DXIL compatible metadata
this test checks that we can embed lots of string as metadata into DXIL
bitcode and retrieve it again
renaming the metadata to llvm.ident retains the testing with a DXIL
compatible metadata node
---
llvm/test/tools/dxil-dis/md-manystrings.ll | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/tools/dxil-dis/md-manystrings.ll b/llvm/test/tools/dxil-dis/md-manystrings.ll
index 938e2dd5114da..a7dd595f09d94 100644
--- a/llvm/test/tools/dxil-dis/md-manystrings.ll
+++ b/llvm/test/tools/dxil-dis/md-manystrings.ll
@@ -4,7 +4,7 @@
target triple = "dxil-unknown-shadermodel6.7-library"
-!llvm.too_many_strings = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31}
+!llvm.ident = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31}
!0 = !{!"String 0"}
!1 = !{!"String 1"}
@@ -39,7 +39,7 @@ target triple = "dxil-unknown-shadermodel6.7-library"
!30 = !{!"String 30"}
!31 = !{!"String 31"}
-; CHECK: !llvm.too_many_strings = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31}
+; CHECK: !llvm.ident = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31}
; CHECK: !0 = !{!"String 0"}
; CHECK: !1 = !{!"String 1"}
; CHECK: !2 = !{!"String 2"}
>From 0019e625b8da6d418d33bd828a530e21c2665a20 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 29 Oct 2025 11:58:36 -0700
Subject: [PATCH 4/5] update di-subprogram to only use DXIL compatible metadata
the intent of this test is to ensure that the metadata written with the
DXIL bitcode writer is correctly read back from being embedded in the
DXIL
removing the unrecognized metadata retains the test purpose
---
llvm/test/tools/dxil-dis/di-subprogram.ll | 37 -----------------------
1 file changed, 37 deletions(-)
diff --git a/llvm/test/tools/dxil-dis/di-subprogram.ll b/llvm/test/tools/dxil-dis/di-subprogram.ll
index 8255d396dd55d..912421fb28ae5 100644
--- a/llvm/test/tools/dxil-dis/di-subprogram.ll
+++ b/llvm/test/tools/dxil-dis/di-subprogram.ll
@@ -3,8 +3,6 @@ target triple = "dxil-unknown-shadermodel6.7-library"
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
-!llvm.used = !{!5}
-!llvm.lines = !{!13, !14, !15, !16}
; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2)
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Some Compiler", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
@@ -16,38 +14,3 @@ target triple = "dxil-unknown-shadermodel6.7-library"
!3 = !{i32 2, !"Dwarf Version", i32 4}
; CHECK: !4 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 2, !"Debug Info Version", i32 3}
-
-; CHECK: !5 = distinct !DISubprogram(name: "fma", scope: !1, file: !1, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, function: !0, variables: !9)
-!5 = distinct !DISubprogram(name: "fma", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !9)
-
-; CHECK: !6 = !DISubroutineType(types: !7)
-!6 = !DISubroutineType(types: !7)
-
-; CHECK: !7 = !{!8, !8, !8, !8}
-!7 = !{!8, !8, !8, !8}
-
-; CHECK: !8 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!8 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-
-; CHECK: !9 = !{!10, !11, !12}
-!9 = !{!10, !11, !12}
-
-; CHECK: !10 = !DILocalVariable(tag: DW_TAG_variable, name: "x", arg: 1, scope: !5, file: !1, line: 1, type: !8)
-!10 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !1, line: 1, type: !8)
-
-; CHECK: !11 = !DILocalVariable(tag: DW_TAG_variable, name: "y", arg: 2, scope: !5, file: !1, line: 1, type: !8)
-!11 = !DILocalVariable(name: "y", arg: 2, scope: !5, file: !1, line: 1, type: !8)
-
-; CHECK: !12 = !DILocalVariable(tag: DW_TAG_variable, name: "z", arg: 3, scope: !5, file: !1, line: 1, type: !8)
-!12 = !DILocalVariable(name: "z", arg: 3, scope: !5, file: !1, line: 1, type: !8)
-
-
-; CHECK: !13 = !DILocation(line: 0, scope: !5)
-; CHECK: !14 = !DILocation(line: 2, column: 12, scope: !5)
-; CHECK: !15 = !DILocation(line: 2, column: 16, scope: !5)
-; CHECK: !16 = !DILocation(line: 2, column: 3, scope: !5)
-
-!13 = !DILocation(line: 0, scope: !5)
-!14 = !DILocation(line: 2, column: 12, scope: !5)
-!15 = !DILocation(line: 2, column: 16, scope: !5)
-!16 = !DILocation(line: 2, column: 3, scope: !5)
>From 7966dad2e665a6044c9063eaff5b5f474830fa95 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Wed, 29 Oct 2025 12:03:34 -0700
Subject: [PATCH 5/5] remove di-subrotine
this test is redundant with respect to di-subprogram, so we can remove
it without reducing test coverage
---
llvm/test/tools/dxil-dis/di-subrotine.ll | 12 ------------
1 file changed, 12 deletions(-)
delete mode 100644 llvm/test/tools/dxil-dis/di-subrotine.ll
diff --git a/llvm/test/tools/dxil-dis/di-subrotine.ll b/llvm/test/tools/dxil-dis/di-subrotine.ll
deleted file mode 100644
index 285e319b74056..0000000000000
--- a/llvm/test/tools/dxil-dis/di-subrotine.ll
+++ /dev/null
@@ -1,12 +0,0 @@
-; RUN: llc --filetype=obj %s -o - | dxil-dis -o - | FileCheck %s
-target triple = "dxil-unknown-shadermodel6.7-library"
-
-!llvm.used = !{!0}
-
-!0 = !DISubroutineType(types: !1)
-!1 = !{!2, !2, !2, !2}
-!2 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-
-; CHECK: !0 = !DISubroutineType(types: !1)
-; CHECK: !1 = !{!2, !2, !2, !2}
-; CHECK: !2 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
More information about the llvm-commits
mailing list