[llvm] [DirectX backend] emits metadata for DXIL version. (PR #88350)

Xiang Li via llvm-commits llvm-commits at lists.llvm.org
Tue May 7 13:39:03 PDT 2024


https://github.com/python3kgae updated https://github.com/llvm/llvm-project/pull/88350

>From d9353d11f0a56b53e3c7f8da0275cd5385bed99e Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Thu, 11 Apr 2024 00:09:46 -0400
Subject: [PATCH 1/8] [DirectX backend] emit metadata for DXIL version.

Emit named metadata "dx.version".

Default to DXIL 1.0
---
 llvm/lib/Target/DirectX/DXILMetadata.cpp          | 12 ++++++++++++
 llvm/lib/Target/DirectX/DXILMetadata.h            |  1 +
 llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp |  1 +
 llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll | 12 ++++++++++++
 llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll | 12 ++++++++++++
 5 files changed, 38 insertions(+)
 create mode 100644 llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll
 create mode 100644 llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll

diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index 2d94490a7f24c..61882f8509566 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -81,6 +81,18 @@ void dxil::createShaderModelMD(Module &M) {
   Entry->addOperand(MDNode::get(Ctx, Vals));
 }
 
+void dxil::createDXILVersionMD(Module &M) {
+  Triple TT(M.getTargetTriple());
+  VersionTuple Ver = TT.getOSVersion();
+  LLVMContext &Ctx = M.getContext();
+  IRBuilder<> B(Ctx);
+  NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version");
+  Metadata *Vals[2];
+  Vals[0] = ConstantAsMetadata::get(B.getInt32(1));
+  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;
 }
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.h b/llvm/lib/Target/DirectX/DXILMetadata.h
index 2f5d7d9fe7683..c105c15f3d47a 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.h
+++ b/llvm/lib/Target/DirectX/DXILMetadata.h
@@ -33,6 +33,7 @@ class ValidatorVersionMD {
 };
 
 void createShaderModelMD(Module &M);
+void createDXILVersionMD(Module &M);
 void createEntryMD(Module &M, const uint64_t ShaderFlags);
 
 } // namespace dxil
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index 80d94bf0c9d48..ae6d6f96904c8 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -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();
diff --git a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll
new file mode 100644
index 0000000000000..254479e5f94cb
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll
@@ -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" }
diff --git a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll
new file mode 100644
index 0000000000000..efeb5a1b24862
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll
@@ -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" }

>From 2b13ac2ec845c2398eb257e2118397f544a79148 Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Mon, 6 May 2024 18:50:20 -0400
Subject: [PATCH 2/8] Get dxil version from subarch.

---
 llvm/lib/Target/DirectX/DXILMetadata.cpp | 40 ++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index 61882f8509566..0394b4fe0f259 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -82,13 +82,47 @@ void dxil::createShaderModelMD(Module &M) {
 }
 
 void dxil::createDXILVersionMD(Module &M) {
-  Triple TT(M.getTargetTriple());
-  VersionTuple Ver = TT.getOSVersion();
+  Triple TT(Triple::normalize(M.getTargetTriple()));
+  VersionTuple Ver = VersionTuple(1, 0);
+  switch (TT.getSubArch()) {
+  case Triple::DXILSubArch_v1_0:
+    Ver = VersionTuple(1, 0);
+    break;
+  case Triple::DXILSubArch_v1_1:
+    Ver = VersionTuple(1, 1);
+    break;
+  case Triple::DXILSubArch_v1_2:
+    Ver = VersionTuple(1, 2);
+    break;
+  case Triple::DXILSubArch_v1_3:
+    Ver = VersionTuple(1, 3);
+    break;
+  case Triple::DXILSubArch_v1_4:
+    Ver = VersionTuple(1, 4);
+    break;
+  case Triple::DXILSubArch_v1_5:
+    Ver = VersionTuple(1, 5);
+    break;
+  case Triple::DXILSubArch_v1_6:
+    Ver = VersionTuple(1, 6);
+    break;
+  case Triple::DXILSubArch_v1_7:
+    Ver = VersionTuple(1, 7);
+    break;
+  case Triple::DXILSubArch_v1_8:
+    Ver = VersionTuple(1, 8);
+    break;
+  case Triple::NoSubArch:
+    break;
+  default:
+    llvm_unreachable("Unsupported subarch for DXIL generation.");
+    break;
+  }
   LLVMContext &Ctx = M.getContext();
   IRBuilder<> B(Ctx);
   NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version");
   Metadata *Vals[2];
-  Vals[0] = ConstantAsMetadata::get(B.getInt32(1));
+  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));
 }

>From 6d0a795baaccf65dd2e94b4c94fff8c163509668 Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Tue, 7 May 2024 12:39:30 -0400
Subject: [PATCH 3/8] Add DXILVersion for DXIL metadata abstractions

---
 llvm/include/llvm/Transforms/Utils/DXIL.h     |  66 ++++++++++
 llvm/lib/Target/DirectX/DXILMetadata.cpp      |  46 -------
 llvm/lib/Target/DirectX/DXILMetadata.h        |   1 -
 .../Target/DirectX/DXILTranslateMetadata.cpp  |   9 +-
 llvm/lib/Transforms/Utils/CMakeLists.txt      |   1 +
 llvm/lib/Transforms/Utils/DXIL.cpp            | 119 ++++++++++++++++++
 llvm/lib/Transforms/Utils/DXILUpgrade.cpp     |  16 +++
 .../DirectX/Metadata/dxilVer-default.ll       |  12 ++
 .../Transforms/DXILUpgrade/strip-dxilver.ll   |  18 +++
 9 files changed, 240 insertions(+), 48 deletions(-)
 create mode 100644 llvm/include/llvm/Transforms/Utils/DXIL.h
 create mode 100644 llvm/lib/Transforms/Utils/DXIL.cpp
 create mode 100644 llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll
 create mode 100644 llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll

diff --git a/llvm/include/llvm/Transforms/Utils/DXIL.h b/llvm/include/llvm/Transforms/Utils/DXIL.h
new file mode 100644
index 0000000000000..a91eeaa646828
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Utils/DXIL.h
@@ -0,0 +1,66 @@
+//===- DXIL.h - Abstractions for DXIL constructs ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file This file defines various abstractions for transforming between DXIL's
+// and LLVM's representations of shader metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_DXIL_H
+#define LLVM_TRANSFORMS_UTILS_DXIL_H
+
+#include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace llvm {
+class Module;
+
+namespace dxil {
+
+class DXILVersion {
+  unsigned Major = 0;
+  unsigned Minor = 0;
+
+public:
+  DXILVersion() = default;
+  DXILVersion(unsigned Major, unsigned Minor) : Major(Major), Minor(Minor) {}
+
+  /// Get the DXILVersion for \c M
+  static Expected<DXILVersion> get(Module &M);
+  /// Read the DXILVersion from the DXIL metadata in \c M
+  static Expected<DXILVersion> readDXIL(Module &M);
+
+  /// Returns true if no DXILVersion is set
+  bool empty() { return Major == 0 && Minor == 0; }
+
+  /// Remove any non-DXIL LLVM representations of the DXILVersion from \c M.
+  void strip(Module &M);
+  /// Embed the LLVM representation of the DXILVersion into \c M.
+  void embed(Module &M);
+  /// Remove any DXIL representation of the DXILVersion from \c M.
+  void stripDXIL(Module &M);
+  /// Embed a DXIL representation of the DXILVersion into \c M.
+  void embedDXIL(Module &M);
+
+  void print(raw_ostream &OS) const {
+    // Format like Triple ArchName.
+    OS << "dxilv" << Major << "." << Minor;
+  }
+  LLVM_DUMP_METHOD void dump() const { print(errs()); }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const DXILVersion &V) {
+  V.print(OS);
+  return OS;
+}
+
+} // namespace dxil
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_DXIL_H
+
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index 0394b4fe0f259..2d94490a7f24c 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -81,52 +81,6 @@ void dxil::createShaderModelMD(Module &M) {
   Entry->addOperand(MDNode::get(Ctx, Vals));
 }
 
-void dxil::createDXILVersionMD(Module &M) {
-  Triple TT(Triple::normalize(M.getTargetTriple()));
-  VersionTuple Ver = VersionTuple(1, 0);
-  switch (TT.getSubArch()) {
-  case Triple::DXILSubArch_v1_0:
-    Ver = VersionTuple(1, 0);
-    break;
-  case Triple::DXILSubArch_v1_1:
-    Ver = VersionTuple(1, 1);
-    break;
-  case Triple::DXILSubArch_v1_2:
-    Ver = VersionTuple(1, 2);
-    break;
-  case Triple::DXILSubArch_v1_3:
-    Ver = VersionTuple(1, 3);
-    break;
-  case Triple::DXILSubArch_v1_4:
-    Ver = VersionTuple(1, 4);
-    break;
-  case Triple::DXILSubArch_v1_5:
-    Ver = VersionTuple(1, 5);
-    break;
-  case Triple::DXILSubArch_v1_6:
-    Ver = VersionTuple(1, 6);
-    break;
-  case Triple::DXILSubArch_v1_7:
-    Ver = VersionTuple(1, 7);
-    break;
-  case Triple::DXILSubArch_v1_8:
-    Ver = VersionTuple(1, 8);
-    break;
-  case Triple::NoSubArch:
-    break;
-  default:
-    llvm_unreachable("Unsupported subarch for DXIL generation.");
-    break;
-  }
-  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;
 }
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.h b/llvm/lib/Target/DirectX/DXILMetadata.h
index c105c15f3d47a..2f5d7d9fe7683 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.h
+++ b/llvm/lib/Target/DirectX/DXILMetadata.h
@@ -33,7 +33,6 @@ class ValidatorVersionMD {
 };
 
 void createShaderModelMD(Module &M);
-void createDXILVersionMD(Module &M);
 void createEntryMD(Module &M, const uint64_t ShaderFlags);
 
 } // namespace dxil
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index ae6d6f96904c8..9b2c9e5873c7c 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -19,6 +19,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/DXIL.h"
 
 using namespace llvm;
 using namespace llvm::dxil;
@@ -48,7 +49,13 @@ bool DXILTranslateMetadata::runOnModule(Module &M) {
   if (ValVerMD.isEmpty())
     ValVerMD.update(VersionTuple(1, 0));
   dxil::createShaderModelMD(M);
-  dxil::createDXILVersionMD(M);
+  Expected<dxil::DXILVersion> DXILVer = dxil::DXILVersion::get(M);
+  if (auto E = DXILVer.takeError()) {
+    errs() << "Fail to get DXIL version " << toString(std::move(E)) << "\n";
+    return false;
+  }
+
+  DXILVer->embedDXIL(M);
 
   const dxil::Resources &Res =
       getAnalysis<DXILResourceWrapper>().getDXILResource();
diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index 51e8821773c3a..a2f22144cb69d 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_component_library(LLVMTransformUtils
   CountVisits.cpp
   Debugify.cpp
   DemoteRegToStack.cpp
+  DXIL.cpp
   DXILUpgrade.cpp
   EntryExitInstrumenter.cpp
   EscapeEnumerator.cpp
diff --git a/llvm/lib/Transforms/Utils/DXIL.cpp b/llvm/lib/Transforms/Utils/DXIL.cpp
new file mode 100644
index 0000000000000..a87075fb4e1e3
--- /dev/null
+++ b/llvm/lib/Transforms/Utils/DXIL.cpp
@@ -0,0 +1,119 @@
+//===- DXIL.cpp - Abstractions for DXIL constructs ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Utils/DXIL.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+using namespace llvm::dxil;
+
+static Error errInvalid(const char *Msg) {
+  return createStringError(std::errc::invalid_argument, Msg);
+}
+
+template <typename... Ts>
+static Error errInvalid(const char *Fmt, const Ts &... Vals) {
+  return createStringError(std::errc::invalid_argument, Fmt, Vals...);
+}
+
+Expected<DXILVersion> DXILVersion::get(Module &M) {
+  Triple TT(Triple::normalize(M.getTargetTriple()));
+
+  if (!TT.isDXIL())
+    return errInvalid("Cannot get DXIL version for arch '%s'",
+                      TT.getArchName().str().c_str());
+
+  switch (TT.getSubArch()) {
+    case Triple::NoSubArch:
+    case Triple::DXILSubArch_v1_0:
+      return DXILVersion(1, 0);
+    case Triple::DXILSubArch_v1_1:
+      return DXILVersion(1, 1);
+    case Triple::DXILSubArch_v1_2:
+      return DXILVersion(1, 2);
+    case Triple::DXILSubArch_v1_3:
+      return DXILVersion(1, 3);
+    case Triple::DXILSubArch_v1_4:
+      return DXILVersion(1, 4);
+    case Triple::DXILSubArch_v1_5:
+      return DXILVersion(1, 5);
+    case Triple::DXILSubArch_v1_6:
+      return DXILVersion(1, 6);
+    case Triple::DXILSubArch_v1_7:
+      return DXILVersion(1, 7);
+    case Triple::DXILSubArch_v1_8:
+      return DXILVersion(1, 8);
+    default:
+    return errInvalid("Cannot get DXIL version for arch '%s'",
+                      TT.getArchName().str().c_str());
+  }
+}
+
+Expected<DXILVersion> DXILVersion::readDXIL(Module &M) {
+  NamedMDNode *DXILVersionMD = M.getNamedMetadata("dx.version");
+  if (!DXILVersionMD)
+    return DXILVersion();
+
+  if (DXILVersionMD->getNumOperands() != 1)
+    return errInvalid("dx.version must have one operand");
+
+  MDNode *N = DXILVersionMD->getOperand(0);
+  if (N->getNumOperands() != 2)
+    return errInvalid("dx.version must have 2 components, not %d",
+                      N->getNumOperands());
+
+  const auto *MajorOp = mdconst::dyn_extract<ConstantInt>(N->getOperand(0));
+  const auto *MinorOp = mdconst::dyn_extract<ConstantInt>(N->getOperand(1));
+  if (!MajorOp)
+    return errInvalid("dx.version major version must be an integer");
+  if (!MinorOp)
+    return errInvalid("dx.version minor version must be an integer");
+
+  return DXILVersion(MajorOp->getZExtValue(), MinorOp->getZExtValue());
+}
+
+void DXILVersion::strip(Module &M) {
+  M.setTargetTriple("dxil-ms-dx");
+}
+
+void DXILVersion::embed(Module &M) {
+  Triple TT(Triple::normalize(M.getTargetTriple()));
+  SmallString<64> Triple;
+  raw_svector_ostream OS(Triple);
+  print(OS);
+  OS << "-" << TT.getVendorName() << "-" << TT.getOSAndEnvironmentName();
+  M.setTargetTriple(OS.str());
+}
+
+void DXILVersion::stripDXIL(Module &M) {
+  if (NamedMDNode *V = M.getNamedMetadata("dx.version")) {
+    V->dropAllReferences();
+    V->eraseFromParent();
+  }
+}
+
+void DXILVersion::embedDXIL(Module &M) {
+  LLVMContext &Ctx = M.getContext();
+  IRBuilder<> B(Ctx);
+
+  Metadata *Vals[2];
+  Vals[0] = ConstantAsMetadata::get(B.getInt32(Major));
+  Vals[1] = ConstantAsMetadata::get(B.getInt32(Minor));
+  MDNode *MD = MDNode::get(Ctx, Vals);
+
+  NamedMDNode *V = M.getOrInsertNamedMetadata("dx.version");
+  if (V->getNumOperands())
+    V->setOperand(0, MD);
+  else
+    V->addOperand(MD);
+}
diff --git a/llvm/lib/Transforms/Utils/DXILUpgrade.cpp b/llvm/lib/Transforms/Utils/DXILUpgrade.cpp
index 09991f628224c..40486e431c9fa 100644
--- a/llvm/lib/Transforms/Utils/DXILUpgrade.cpp
+++ b/llvm/lib/Transforms/Utils/DXILUpgrade.cpp
@@ -11,6 +11,7 @@
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Utils/DXIL.h"
 
 using namespace llvm;
 
@@ -33,6 +34,20 @@ static bool handleValVerMetadata(Module &M) {
   return true;
 }
 
+static bool handleDXILVerMetadata(Module &M) {
+  auto V = dxil::DXILVersion::readDXIL(M);
+  if (Error E = V.takeError()) {
+    report_fatal_error(std::move(E), /*gen_crash_diag=*/false);
+  }
+  if (V->empty())
+    return false;
+
+  LLVM_DEBUG(dbgs() << "DXIL: DXIL Version " << *V << "\n");
+  V->embed(M);
+  V->stripDXIL(M);
+  return true;
+}
+
 PreservedAnalyses DXILUpgradePass::run(Module &M, ModuleAnalysisManager &AM) {
   PreservedAnalyses PA;
   // We never add, remove, or change functions here.
@@ -41,6 +56,7 @@ PreservedAnalyses DXILUpgradePass::run(Module &M, ModuleAnalysisManager &AM) {
 
   bool Changed = false;
   Changed |= handleValVerMetadata(M);
+  Changed |= handleDXILVerMetadata(M);
 
   if (!Changed)
     return PreservedAnalyses::all();
diff --git a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll
new file mode 100644
index 0000000000000..db053c1753423
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll
@@ -0,0 +1,12 @@
+; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
+target triple = "dxil-pc-shadermodel-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" }
diff --git a/llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll b/llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll
new file mode 100644
index 0000000000000..3041eeb64d11c
--- /dev/null
+++ b/llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll
@@ -0,0 +1,18 @@
+; RUN: opt -passes=dxil-upgrade -S < %s | FileCheck %s
+
+; Ensure that both the dxil version metadata and its operand are removed.
+; CHECK: !unrelated_md1 = !{!0}
+; CHECK-NOT: !dx.version
+; CHECK: !unrelated_md2 = !{!1}
+;
+; CHECK: !0 = !{i32 1234}
+; CHECK-NOT: !{i32 1, i32 7}
+; CHECK: !1 = !{i32 4321}
+
+!unrelated_md1 = !{!0}
+!dx.version = !{!1}
+!unrelated_md2 = !{!2}
+
+!0 = !{i32 1234}
+!1 = !{i32 1, i32 7}
+!2 = !{i32 4321}

>From 85c007f1ea3f3aaba99980c31f0260890814d43c Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Tue, 7 May 2024 12:44:51 -0400
Subject: [PATCH 4/8] Fix clang-format

---
 llvm/include/llvm/Transforms/Utils/DXIL.h |  1 -
 llvm/lib/Transforms/Utils/DXIL.cpp        | 46 +++++++++++------------
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/DXIL.h b/llvm/include/llvm/Transforms/Utils/DXIL.h
index a91eeaa646828..932077b929e07 100644
--- a/llvm/include/llvm/Transforms/Utils/DXIL.h
+++ b/llvm/include/llvm/Transforms/Utils/DXIL.h
@@ -63,4 +63,3 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DXILVersion &V) {
 } // namespace llvm
 
 #endif // LLVM_TRANSFORMS_UTILS_DXIL_H
-
diff --git a/llvm/lib/Transforms/Utils/DXIL.cpp b/llvm/lib/Transforms/Utils/DXIL.cpp
index a87075fb4e1e3..33c2ea3e5cc22 100644
--- a/llvm/lib/Transforms/Utils/DXIL.cpp
+++ b/llvm/lib/Transforms/Utils/DXIL.cpp
@@ -22,7 +22,7 @@ static Error errInvalid(const char *Msg) {
 }
 
 template <typename... Ts>
-static Error errInvalid(const char *Fmt, const Ts &... Vals) {
+static Error errInvalid(const char *Fmt, const Ts &...Vals) {
   return createStringError(std::errc::invalid_argument, Fmt, Vals...);
 }
 
@@ -34,26 +34,26 @@ Expected<DXILVersion> DXILVersion::get(Module &M) {
                       TT.getArchName().str().c_str());
 
   switch (TT.getSubArch()) {
-    case Triple::NoSubArch:
-    case Triple::DXILSubArch_v1_0:
-      return DXILVersion(1, 0);
-    case Triple::DXILSubArch_v1_1:
-      return DXILVersion(1, 1);
-    case Triple::DXILSubArch_v1_2:
-      return DXILVersion(1, 2);
-    case Triple::DXILSubArch_v1_3:
-      return DXILVersion(1, 3);
-    case Triple::DXILSubArch_v1_4:
-      return DXILVersion(1, 4);
-    case Triple::DXILSubArch_v1_5:
-      return DXILVersion(1, 5);
-    case Triple::DXILSubArch_v1_6:
-      return DXILVersion(1, 6);
-    case Triple::DXILSubArch_v1_7:
-      return DXILVersion(1, 7);
-    case Triple::DXILSubArch_v1_8:
-      return DXILVersion(1, 8);
-    default:
+  case Triple::NoSubArch:
+  case Triple::DXILSubArch_v1_0:
+    return DXILVersion(1, 0);
+  case Triple::DXILSubArch_v1_1:
+    return DXILVersion(1, 1);
+  case Triple::DXILSubArch_v1_2:
+    return DXILVersion(1, 2);
+  case Triple::DXILSubArch_v1_3:
+    return DXILVersion(1, 3);
+  case Triple::DXILSubArch_v1_4:
+    return DXILVersion(1, 4);
+  case Triple::DXILSubArch_v1_5:
+    return DXILVersion(1, 5);
+  case Triple::DXILSubArch_v1_6:
+    return DXILVersion(1, 6);
+  case Triple::DXILSubArch_v1_7:
+    return DXILVersion(1, 7);
+  case Triple::DXILSubArch_v1_8:
+    return DXILVersion(1, 8);
+  default:
     return errInvalid("Cannot get DXIL version for arch '%s'",
                       TT.getArchName().str().c_str());
   }
@@ -82,9 +82,7 @@ Expected<DXILVersion> DXILVersion::readDXIL(Module &M) {
   return DXILVersion(MajorOp->getZExtValue(), MinorOp->getZExtValue());
 }
 
-void DXILVersion::strip(Module &M) {
-  M.setTargetTriple("dxil-ms-dx");
-}
+void DXILVersion::strip(Module &M) { M.setTargetTriple("dxil-ms-dx"); }
 
 void DXILVersion::embed(Module &M) {
   Triple TT(Triple::normalize(M.getTargetTriple()));

>From 889332eeff39477758c198ac40eb17a5023b15f9 Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Tue, 7 May 2024 15:56:06 -0400
Subject: [PATCH 5/8] Revert "Fix clang-format"

This reverts commit 85c007f1ea3f3aaba99980c31f0260890814d43c.
---
 llvm/include/llvm/Transforms/Utils/DXIL.h |  1 +
 llvm/lib/Transforms/Utils/DXIL.cpp        | 46 ++++++++++++-----------
 2 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/DXIL.h b/llvm/include/llvm/Transforms/Utils/DXIL.h
index 932077b929e07..a91eeaa646828 100644
--- a/llvm/include/llvm/Transforms/Utils/DXIL.h
+++ b/llvm/include/llvm/Transforms/Utils/DXIL.h
@@ -63,3 +63,4 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DXILVersion &V) {
 } // namespace llvm
 
 #endif // LLVM_TRANSFORMS_UTILS_DXIL_H
+
diff --git a/llvm/lib/Transforms/Utils/DXIL.cpp b/llvm/lib/Transforms/Utils/DXIL.cpp
index 33c2ea3e5cc22..a87075fb4e1e3 100644
--- a/llvm/lib/Transforms/Utils/DXIL.cpp
+++ b/llvm/lib/Transforms/Utils/DXIL.cpp
@@ -22,7 +22,7 @@ static Error errInvalid(const char *Msg) {
 }
 
 template <typename... Ts>
-static Error errInvalid(const char *Fmt, const Ts &...Vals) {
+static Error errInvalid(const char *Fmt, const Ts &... Vals) {
   return createStringError(std::errc::invalid_argument, Fmt, Vals...);
 }
 
@@ -34,26 +34,26 @@ Expected<DXILVersion> DXILVersion::get(Module &M) {
                       TT.getArchName().str().c_str());
 
   switch (TT.getSubArch()) {
-  case Triple::NoSubArch:
-  case Triple::DXILSubArch_v1_0:
-    return DXILVersion(1, 0);
-  case Triple::DXILSubArch_v1_1:
-    return DXILVersion(1, 1);
-  case Triple::DXILSubArch_v1_2:
-    return DXILVersion(1, 2);
-  case Triple::DXILSubArch_v1_3:
-    return DXILVersion(1, 3);
-  case Triple::DXILSubArch_v1_4:
-    return DXILVersion(1, 4);
-  case Triple::DXILSubArch_v1_5:
-    return DXILVersion(1, 5);
-  case Triple::DXILSubArch_v1_6:
-    return DXILVersion(1, 6);
-  case Triple::DXILSubArch_v1_7:
-    return DXILVersion(1, 7);
-  case Triple::DXILSubArch_v1_8:
-    return DXILVersion(1, 8);
-  default:
+    case Triple::NoSubArch:
+    case Triple::DXILSubArch_v1_0:
+      return DXILVersion(1, 0);
+    case Triple::DXILSubArch_v1_1:
+      return DXILVersion(1, 1);
+    case Triple::DXILSubArch_v1_2:
+      return DXILVersion(1, 2);
+    case Triple::DXILSubArch_v1_3:
+      return DXILVersion(1, 3);
+    case Triple::DXILSubArch_v1_4:
+      return DXILVersion(1, 4);
+    case Triple::DXILSubArch_v1_5:
+      return DXILVersion(1, 5);
+    case Triple::DXILSubArch_v1_6:
+      return DXILVersion(1, 6);
+    case Triple::DXILSubArch_v1_7:
+      return DXILVersion(1, 7);
+    case Triple::DXILSubArch_v1_8:
+      return DXILVersion(1, 8);
+    default:
     return errInvalid("Cannot get DXIL version for arch '%s'",
                       TT.getArchName().str().c_str());
   }
@@ -82,7 +82,9 @@ Expected<DXILVersion> DXILVersion::readDXIL(Module &M) {
   return DXILVersion(MajorOp->getZExtValue(), MinorOp->getZExtValue());
 }
 
-void DXILVersion::strip(Module &M) { M.setTargetTriple("dxil-ms-dx"); }
+void DXILVersion::strip(Module &M) {
+  M.setTargetTriple("dxil-ms-dx");
+}
 
 void DXILVersion::embed(Module &M) {
   Triple TT(Triple::normalize(M.getTargetTriple()));

>From 8252881049ce4222770b2c1812da8a7f241a9f46 Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Tue, 7 May 2024 15:56:29 -0400
Subject: [PATCH 6/8] Revert "Add DXILVersion for DXIL metadata abstractions"

This reverts commit 6d0a795baaccf65dd2e94b4c94fff8c163509668.
---
 llvm/include/llvm/Transforms/Utils/DXIL.h     |  66 ----------
 llvm/lib/Target/DirectX/DXILMetadata.cpp      |  46 +++++++
 llvm/lib/Target/DirectX/DXILMetadata.h        |   1 +
 .../Target/DirectX/DXILTranslateMetadata.cpp  |   9 +-
 llvm/lib/Transforms/Utils/CMakeLists.txt      |   1 -
 llvm/lib/Transforms/Utils/DXIL.cpp            | 119 ------------------
 llvm/lib/Transforms/Utils/DXILUpgrade.cpp     |  16 ---
 .../DirectX/Metadata/dxilVer-default.ll       |  12 --
 .../Transforms/DXILUpgrade/strip-dxilver.ll   |  18 ---
 9 files changed, 48 insertions(+), 240 deletions(-)
 delete mode 100644 llvm/include/llvm/Transforms/Utils/DXIL.h
 delete mode 100644 llvm/lib/Transforms/Utils/DXIL.cpp
 delete mode 100644 llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll
 delete mode 100644 llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll

diff --git a/llvm/include/llvm/Transforms/Utils/DXIL.h b/llvm/include/llvm/Transforms/Utils/DXIL.h
deleted file mode 100644
index a91eeaa646828..0000000000000
--- a/llvm/include/llvm/Transforms/Utils/DXIL.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===- DXIL.h - Abstractions for DXIL constructs ----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file This file defines various abstractions for transforming between DXIL's
-// and LLVM's representations of shader metadata.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_DXIL_H
-#define LLVM_TRANSFORMS_UTILS_DXIL_H
-
-#include "llvm/Support/Error.h"
-#include "llvm/TargetParser/Triple.h"
-
-namespace llvm {
-class Module;
-
-namespace dxil {
-
-class DXILVersion {
-  unsigned Major = 0;
-  unsigned Minor = 0;
-
-public:
-  DXILVersion() = default;
-  DXILVersion(unsigned Major, unsigned Minor) : Major(Major), Minor(Minor) {}
-
-  /// Get the DXILVersion for \c M
-  static Expected<DXILVersion> get(Module &M);
-  /// Read the DXILVersion from the DXIL metadata in \c M
-  static Expected<DXILVersion> readDXIL(Module &M);
-
-  /// Returns true if no DXILVersion is set
-  bool empty() { return Major == 0 && Minor == 0; }
-
-  /// Remove any non-DXIL LLVM representations of the DXILVersion from \c M.
-  void strip(Module &M);
-  /// Embed the LLVM representation of the DXILVersion into \c M.
-  void embed(Module &M);
-  /// Remove any DXIL representation of the DXILVersion from \c M.
-  void stripDXIL(Module &M);
-  /// Embed a DXIL representation of the DXILVersion into \c M.
-  void embedDXIL(Module &M);
-
-  void print(raw_ostream &OS) const {
-    // Format like Triple ArchName.
-    OS << "dxilv" << Major << "." << Minor;
-  }
-  LLVM_DUMP_METHOD void dump() const { print(errs()); }
-};
-
-inline raw_ostream &operator<<(raw_ostream &OS, const DXILVersion &V) {
-  V.print(OS);
-  return OS;
-}
-
-} // namespace dxil
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_DXIL_H
-
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index 2d94490a7f24c..0394b4fe0f259 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -81,6 +81,52 @@ void dxil::createShaderModelMD(Module &M) {
   Entry->addOperand(MDNode::get(Ctx, Vals));
 }
 
+void dxil::createDXILVersionMD(Module &M) {
+  Triple TT(Triple::normalize(M.getTargetTriple()));
+  VersionTuple Ver = VersionTuple(1, 0);
+  switch (TT.getSubArch()) {
+  case Triple::DXILSubArch_v1_0:
+    Ver = VersionTuple(1, 0);
+    break;
+  case Triple::DXILSubArch_v1_1:
+    Ver = VersionTuple(1, 1);
+    break;
+  case Triple::DXILSubArch_v1_2:
+    Ver = VersionTuple(1, 2);
+    break;
+  case Triple::DXILSubArch_v1_3:
+    Ver = VersionTuple(1, 3);
+    break;
+  case Triple::DXILSubArch_v1_4:
+    Ver = VersionTuple(1, 4);
+    break;
+  case Triple::DXILSubArch_v1_5:
+    Ver = VersionTuple(1, 5);
+    break;
+  case Triple::DXILSubArch_v1_6:
+    Ver = VersionTuple(1, 6);
+    break;
+  case Triple::DXILSubArch_v1_7:
+    Ver = VersionTuple(1, 7);
+    break;
+  case Triple::DXILSubArch_v1_8:
+    Ver = VersionTuple(1, 8);
+    break;
+  case Triple::NoSubArch:
+    break;
+  default:
+    llvm_unreachable("Unsupported subarch for DXIL generation.");
+    break;
+  }
+  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;
 }
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.h b/llvm/lib/Target/DirectX/DXILMetadata.h
index 2f5d7d9fe7683..c105c15f3d47a 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.h
+++ b/llvm/lib/Target/DirectX/DXILMetadata.h
@@ -33,6 +33,7 @@ class ValidatorVersionMD {
 };
 
 void createShaderModelMD(Module &M);
+void createDXILVersionMD(Module &M);
 void createEntryMD(Module &M, const uint64_t ShaderFlags);
 
 } // namespace dxil
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index 9b2c9e5873c7c..ae6d6f96904c8 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -19,7 +19,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/TargetParser/Triple.h"
-#include "llvm/Transforms/Utils/DXIL.h"
 
 using namespace llvm;
 using namespace llvm::dxil;
@@ -49,13 +48,7 @@ bool DXILTranslateMetadata::runOnModule(Module &M) {
   if (ValVerMD.isEmpty())
     ValVerMD.update(VersionTuple(1, 0));
   dxil::createShaderModelMD(M);
-  Expected<dxil::DXILVersion> DXILVer = dxil::DXILVersion::get(M);
-  if (auto E = DXILVer.takeError()) {
-    errs() << "Fail to get DXIL version " << toString(std::move(E)) << "\n";
-    return false;
-  }
-
-  DXILVer->embedDXIL(M);
+  dxil::createDXILVersionMD(M);
 
   const dxil::Resources &Res =
       getAnalysis<DXILResourceWrapper>().getDXILResource();
diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt
index a2f22144cb69d..51e8821773c3a 100644
--- a/llvm/lib/Transforms/Utils/CMakeLists.txt
+++ b/llvm/lib/Transforms/Utils/CMakeLists.txt
@@ -20,7 +20,6 @@ add_llvm_component_library(LLVMTransformUtils
   CountVisits.cpp
   Debugify.cpp
   DemoteRegToStack.cpp
-  DXIL.cpp
   DXILUpgrade.cpp
   EntryExitInstrumenter.cpp
   EscapeEnumerator.cpp
diff --git a/llvm/lib/Transforms/Utils/DXIL.cpp b/llvm/lib/Transforms/Utils/DXIL.cpp
deleted file mode 100644
index a87075fb4e1e3..0000000000000
--- a/llvm/lib/Transforms/Utils/DXIL.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//===- DXIL.cpp - Abstractions for DXIL constructs ------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Utils/DXIL.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Module.h"
-
-using namespace llvm;
-using namespace llvm::dxil;
-
-static Error errInvalid(const char *Msg) {
-  return createStringError(std::errc::invalid_argument, Msg);
-}
-
-template <typename... Ts>
-static Error errInvalid(const char *Fmt, const Ts &... Vals) {
-  return createStringError(std::errc::invalid_argument, Fmt, Vals...);
-}
-
-Expected<DXILVersion> DXILVersion::get(Module &M) {
-  Triple TT(Triple::normalize(M.getTargetTriple()));
-
-  if (!TT.isDXIL())
-    return errInvalid("Cannot get DXIL version for arch '%s'",
-                      TT.getArchName().str().c_str());
-
-  switch (TT.getSubArch()) {
-    case Triple::NoSubArch:
-    case Triple::DXILSubArch_v1_0:
-      return DXILVersion(1, 0);
-    case Triple::DXILSubArch_v1_1:
-      return DXILVersion(1, 1);
-    case Triple::DXILSubArch_v1_2:
-      return DXILVersion(1, 2);
-    case Triple::DXILSubArch_v1_3:
-      return DXILVersion(1, 3);
-    case Triple::DXILSubArch_v1_4:
-      return DXILVersion(1, 4);
-    case Triple::DXILSubArch_v1_5:
-      return DXILVersion(1, 5);
-    case Triple::DXILSubArch_v1_6:
-      return DXILVersion(1, 6);
-    case Triple::DXILSubArch_v1_7:
-      return DXILVersion(1, 7);
-    case Triple::DXILSubArch_v1_8:
-      return DXILVersion(1, 8);
-    default:
-    return errInvalid("Cannot get DXIL version for arch '%s'",
-                      TT.getArchName().str().c_str());
-  }
-}
-
-Expected<DXILVersion> DXILVersion::readDXIL(Module &M) {
-  NamedMDNode *DXILVersionMD = M.getNamedMetadata("dx.version");
-  if (!DXILVersionMD)
-    return DXILVersion();
-
-  if (DXILVersionMD->getNumOperands() != 1)
-    return errInvalid("dx.version must have one operand");
-
-  MDNode *N = DXILVersionMD->getOperand(0);
-  if (N->getNumOperands() != 2)
-    return errInvalid("dx.version must have 2 components, not %d",
-                      N->getNumOperands());
-
-  const auto *MajorOp = mdconst::dyn_extract<ConstantInt>(N->getOperand(0));
-  const auto *MinorOp = mdconst::dyn_extract<ConstantInt>(N->getOperand(1));
-  if (!MajorOp)
-    return errInvalid("dx.version major version must be an integer");
-  if (!MinorOp)
-    return errInvalid("dx.version minor version must be an integer");
-
-  return DXILVersion(MajorOp->getZExtValue(), MinorOp->getZExtValue());
-}
-
-void DXILVersion::strip(Module &M) {
-  M.setTargetTriple("dxil-ms-dx");
-}
-
-void DXILVersion::embed(Module &M) {
-  Triple TT(Triple::normalize(M.getTargetTriple()));
-  SmallString<64> Triple;
-  raw_svector_ostream OS(Triple);
-  print(OS);
-  OS << "-" << TT.getVendorName() << "-" << TT.getOSAndEnvironmentName();
-  M.setTargetTriple(OS.str());
-}
-
-void DXILVersion::stripDXIL(Module &M) {
-  if (NamedMDNode *V = M.getNamedMetadata("dx.version")) {
-    V->dropAllReferences();
-    V->eraseFromParent();
-  }
-}
-
-void DXILVersion::embedDXIL(Module &M) {
-  LLVMContext &Ctx = M.getContext();
-  IRBuilder<> B(Ctx);
-
-  Metadata *Vals[2];
-  Vals[0] = ConstantAsMetadata::get(B.getInt32(Major));
-  Vals[1] = ConstantAsMetadata::get(B.getInt32(Minor));
-  MDNode *MD = MDNode::get(Ctx, Vals);
-
-  NamedMDNode *V = M.getOrInsertNamedMetadata("dx.version");
-  if (V->getNumOperands())
-    V->setOperand(0, MD);
-  else
-    V->addOperand(MD);
-}
diff --git a/llvm/lib/Transforms/Utils/DXILUpgrade.cpp b/llvm/lib/Transforms/Utils/DXILUpgrade.cpp
index 40486e431c9fa..09991f628224c 100644
--- a/llvm/lib/Transforms/Utils/DXILUpgrade.cpp
+++ b/llvm/lib/Transforms/Utils/DXILUpgrade.cpp
@@ -11,7 +11,6 @@
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Utils/DXIL.h"
 
 using namespace llvm;
 
@@ -34,20 +33,6 @@ static bool handleValVerMetadata(Module &M) {
   return true;
 }
 
-static bool handleDXILVerMetadata(Module &M) {
-  auto V = dxil::DXILVersion::readDXIL(M);
-  if (Error E = V.takeError()) {
-    report_fatal_error(std::move(E), /*gen_crash_diag=*/false);
-  }
-  if (V->empty())
-    return false;
-
-  LLVM_DEBUG(dbgs() << "DXIL: DXIL Version " << *V << "\n");
-  V->embed(M);
-  V->stripDXIL(M);
-  return true;
-}
-
 PreservedAnalyses DXILUpgradePass::run(Module &M, ModuleAnalysisManager &AM) {
   PreservedAnalyses PA;
   // We never add, remove, or change functions here.
@@ -56,7 +41,6 @@ PreservedAnalyses DXILUpgradePass::run(Module &M, ModuleAnalysisManager &AM) {
 
   bool Changed = false;
   Changed |= handleValVerMetadata(M);
-  Changed |= handleDXILVerMetadata(M);
 
   if (!Changed)
     return PreservedAnalyses::all();
diff --git a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll b/llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll
deleted file mode 100644
index db053c1753423..0000000000000
--- a/llvm/test/CodeGen/DirectX/Metadata/dxilVer-default.ll
+++ /dev/null
@@ -1,12 +0,0 @@
-; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
-target triple = "dxil-pc-shadermodel-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" }
diff --git a/llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll b/llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll
deleted file mode 100644
index 3041eeb64d11c..0000000000000
--- a/llvm/test/Transforms/DXILUpgrade/strip-dxilver.ll
+++ /dev/null
@@ -1,18 +0,0 @@
-; RUN: opt -passes=dxil-upgrade -S < %s | FileCheck %s
-
-; Ensure that both the dxil version metadata and its operand are removed.
-; CHECK: !unrelated_md1 = !{!0}
-; CHECK-NOT: !dx.version
-; CHECK: !unrelated_md2 = !{!1}
-;
-; CHECK: !0 = !{i32 1234}
-; CHECK-NOT: !{i32 1, i32 7}
-; CHECK: !1 = !{i32 4321}
-
-!unrelated_md1 = !{!0}
-!dx.version = !{!1}
-!unrelated_md2 = !{!2}
-
-!0 = !{i32 1234}
-!1 = !{i32 1, i32 7}
-!2 = !{i32 4321}

>From de415cdf3c14d2e2cfd4ad107e2463a5204eeb30 Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Tue, 7 May 2024 16:23:27 -0400
Subject: [PATCH 7/8] Add Triple::getDXILVersion.

---
 llvm/include/llvm/TargetParser/Triple.h    |  4 ++
 llvm/lib/Target/DirectX/DXILMetadata.cpp   | 36 +---------
 llvm/lib/TargetParser/Triple.cpp           | 42 ++++++++++++
 llvm/unittests/TargetParser/TripleTest.cpp | 79 ++++++++++++++++++++++
 4 files changed, 126 insertions(+), 35 deletions(-)

diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 4e357cddcf2a4..b3bb354b38ff5 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -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 OSVersion and DXIL version
+  /// (SubArch).  This should only be called with DXIL triples.
+  VersionTuple getDXILVersion() const;
+
   /// @}
   /// @name Direct Component Access
   /// @{
diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp
index 0394b4fe0f259..c7ed93c35d083 100644
--- a/llvm/lib/Target/DirectX/DXILMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp
@@ -83,41 +83,7 @@ void dxil::createShaderModelMD(Module &M) {
 
 void dxil::createDXILVersionMD(Module &M) {
   Triple TT(Triple::normalize(M.getTargetTriple()));
-  VersionTuple Ver = VersionTuple(1, 0);
-  switch (TT.getSubArch()) {
-  case Triple::DXILSubArch_v1_0:
-    Ver = VersionTuple(1, 0);
-    break;
-  case Triple::DXILSubArch_v1_1:
-    Ver = VersionTuple(1, 1);
-    break;
-  case Triple::DXILSubArch_v1_2:
-    Ver = VersionTuple(1, 2);
-    break;
-  case Triple::DXILSubArch_v1_3:
-    Ver = VersionTuple(1, 3);
-    break;
-  case Triple::DXILSubArch_v1_4:
-    Ver = VersionTuple(1, 4);
-    break;
-  case Triple::DXILSubArch_v1_5:
-    Ver = VersionTuple(1, 5);
-    break;
-  case Triple::DXILSubArch_v1_6:
-    Ver = VersionTuple(1, 6);
-    break;
-  case Triple::DXILSubArch_v1_7:
-    Ver = VersionTuple(1, 7);
-    break;
-  case Triple::DXILSubArch_v1_8:
-    Ver = VersionTuple(1, 8);
-    break;
-  case Triple::NoSubArch:
-    break;
-  default:
-    llvm_unreachable("Unsupported subarch for DXIL generation.");
-    break;
-  }
+  VersionTuple Ver = TT.getDXILVersion();
   LLVMContext &Ctx = M.getContext();
   IRBuilder<> B(Ctx);
   NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version");
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index a6989790a98eb..d09fed051cacf 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -1488,6 +1488,48 @@ VersionTuple Triple::getVulkanVersion() const {
   return VersionTuple(0);
 }
 
+VersionTuple Triple::getDXILVersion() const {
+  if (getArch() != dxil || getOS() != ShaderModel)
+    llvm_unreachable("invalid DXIL triple");
+
+  VersionTuple DXILVersion;
+  switch (getSubArch()) {
+  case Triple::NoSubArch:
+  case Triple::DXILSubArch_v1_0:
+    DXILVersion = VersionTuple(1, 0);
+    break;
+  case Triple::DXILSubArch_v1_1:
+    DXILVersion = VersionTuple(1, 1);
+    break;
+  case Triple::DXILSubArch_v1_2:
+    DXILVersion = VersionTuple(1, 2);
+    break;
+  case Triple::DXILSubArch_v1_3:
+    DXILVersion = VersionTuple(1, 3);
+    break;
+  case Triple::DXILSubArch_v1_4:
+    DXILVersion = VersionTuple(1, 4);
+    break;
+  case Triple::DXILSubArch_v1_5:
+    DXILVersion = VersionTuple(1, 5);
+    break;
+  case Triple::DXILSubArch_v1_6:
+    DXILVersion = VersionTuple(1, 6);
+    break;
+  case Triple::DXILSubArch_v1_7:
+    DXILVersion = VersionTuple(1, 7);
+    break;
+  case Triple::DXILSubArch_v1_8:
+    DXILVersion = VersionTuple(1, 8);
+    break;
+  default:
+    llvm_unreachable("invalid DXIL SubArch");
+  }
+  // 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);
 }
diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index 3112014d9efb6..e8b731896aab8 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -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());

>From 6581b3d7b9d3f1d7592a8a1efb2eb576e3fe74e5 Mon Sep 17 00:00:00 2001
From: Xiang Li <python3kgae at outlook.com>
Date: Tue, 7 May 2024 16:38:46 -0400
Subject: [PATCH 8/8] Fix clang-format.

---
 llvm/unittests/TargetParser/TripleTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index e8b731896aab8..f93dc3671197a 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -508,7 +508,7 @@ TEST(TripleTest, ParsedIDs) {
   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());



More information about the llvm-commits mailing list