Skip to content

[DirectX backend] emits metadata for DXIL version. #88350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/TargetParser/Triple.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,10 @@ class Triple {
/// (SubArch). This should only be called with Vulkan SPIR-V triples.
VersionTuple getVulkanVersion() const;

/// Parse the DXIL version number from the DXIL version
/// (SubArch). This should only be called with DXIL triples.
VersionTuple getDXILVersion() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't seem accurate, given that getDXILVersion doesn't currently use the OS version

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.


/// @}
/// @name Direct Component Access
/// @{
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/DirectX/DXILMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ void dxil::createShaderModelMD(Module &M) {
Entry->addOperand(MDNode::get(Ctx, Vals));
}

void dxil::createDXILVersionMD(Module &M) {
Triple TT(Triple::normalize(M.getTargetTriple()));
VersionTuple Ver = TT.getDXILVersion();
LLVMContext &Ctx = M.getContext();
IRBuilder<> B(Ctx);
NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version");
Metadata *Vals[2];
Vals[0] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor()));
Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0)));
Entry->addOperand(MDNode::get(Ctx, Vals));
}

static uint32_t getShaderStage(Triple::EnvironmentType Env) {
return (uint32_t)Env - (uint32_t)llvm::Triple::Pixel;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/DXILMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ValidatorVersionMD {
};

void createShaderModelMD(Module &M);
void createDXILVersionMD(Module &M);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider expanding MD as Metadata in the function name createDXILVersionMD as createDXILVersionMetadata. Similarly, createShaderModelMetadata.

void createEntryMD(Module &M, const uint64_t ShaderFlags);

} // namespace dxil
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ bool DXILTranslateMetadata::runOnModule(Module &M) {
if (ValVerMD.isEmpty())
ValVerMD.update(VersionTuple(1, 0));
dxil::createShaderModelMD(M);
dxil::createDXILVersionMD(M);

const dxil::Resources &Res =
getAnalysis<DXILResourceWrapper>().getDXILResource();
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/TargetParser/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,17 @@ VersionTuple Triple::getVulkanVersion() const {
return VersionTuple(0);
}

VersionTuple Triple::getDXILVersion() const {
if (getArch() != dxil || getOS() != ShaderModel)
llvm_unreachable("invalid DXIL triple");
StringRef Arch = getArchName();
Arch.consume_front("dxilv");
VersionTuple DXILVersion = parseVersionFromName(Arch);
// FIXME: validate DXIL version against Shader Model version.
// Tracked by https://github.com/llvm/llvm-project/issues/91388
return DXILVersion;
}

void Triple::setTriple(const Twine &Str) {
*this = Triple(Str);
}
Expand Down
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
target triple = "dxil-pc-shadermodel6.0-vertex"

; CHECK: !dx.version = !{![[DXVER:[0-9]+]]}
; CHECK: ![[DXVER]] = !{i32 1, i32 0}

define void @entry() #0 {
entry:
ret void
}

attributes #0 = { noinline nounwind "hlsl.shader"="vertex" }
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
target triple = "dxil-pc-shadermodel6.8-compute"

; CHECK: !dx.version = !{![[DXVER:[0-9]+]]}
; CHECK: ![[DXVER]] = !{i32 1, i32 8}

define void @entry() #0 {
entry:
ret void
}

attributes #0 = { noinline nounwind "hlsl.numthreads"="1,2,1" "hlsl.shader"="compute" }
79 changes: 79 additions & 0 deletions llvm/unittests/TargetParser/TripleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,85 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(VersionTuple(1, 3), T.getVulkanVersion());
EXPECT_EQ(Triple::Compute, T.getEnvironment());

T = Triple("dxilv1.0--shadermodel6.0-pixel");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_0, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 0), T.getDXILVersion());
EXPECT_EQ(Triple::Pixel, T.getEnvironment());

T = Triple("dxilv1.1--shadermodel6.1-vertex");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_1, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 1), T.getDXILVersion());
EXPECT_EQ(Triple::Vertex, T.getEnvironment());

T = Triple("dxilv1.2--shadermodel6.2-geometry");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_2, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 2), T.getDXILVersion());
EXPECT_EQ(Triple::Geometry, T.getEnvironment());

T = Triple("dxilv1.3--shadermodel6.3-library");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_3, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 3), T.getDXILVersion());
EXPECT_EQ(Triple::Library, T.getEnvironment());

T = Triple("dxilv1.4--shadermodel6.4-hull");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_4, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 4), T.getDXILVersion());
EXPECT_EQ(Triple::Hull, T.getEnvironment());

T = Triple("dxilv1.5--shadermodel6.5-domain");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_5, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 5), T.getDXILVersion());
EXPECT_EQ(Triple::Domain, T.getEnvironment());

T = Triple("dxilv1.6--shadermodel6.6-compute");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_6, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 6), T.getDXILVersion());
EXPECT_EQ(Triple::Compute, T.getEnvironment());

T = Triple("dxilv1.7-unknown-shadermodel6.7-mesh");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_7, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 7), T.getDXILVersion());
EXPECT_EQ(Triple::Mesh, T.getEnvironment());

T = Triple("dxilv1.8-unknown-shadermodel6.8-amplification");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_8, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 8), T.getDXILVersion());
EXPECT_EQ(Triple::Amplification, T.getEnvironment());

T = Triple("dxilv1.8-unknown-shadermodel6.15-library");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_8, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 8), T.getDXILVersion());

T = Triple("x86_64-unknown-fuchsia");
EXPECT_EQ(Triple::x86_64, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
Expand Down