[Mlir-commits] [mlir] [MLIR][XeVM] Update XeVM target (PR #179557)

Sang Ik Lee llvmlistbot at llvm.org
Wed Feb 18 10:25:14 PST 2026


https://github.com/silee2 updated https://github.com/llvm/llvm-project/pull/179557

>From 731e7ec146a25fc39dcecdf5cbd801a6d6ebfb7a Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Tue, 3 Feb 2026 21:11:40 +0000
Subject: [PATCH 1/5] [MLIR][XeVM] Enable Intel cache control extension.

---
 mlir/lib/Target/LLVM/CMakeLists.txt  |  7 ++
 mlir/lib/Target/LLVM/XeVM/Target.cpp | 97 +++++++++++++++++++++++++---
 2 files changed, 96 insertions(+), 8 deletions(-)

diff --git a/mlir/lib/Target/LLVM/CMakeLists.txt b/mlir/lib/Target/LLVM/CMakeLists.txt
index 9a0e4d45693b8..2a16160267174 100644
--- a/mlir/lib/Target/LLVM/CMakeLists.txt
+++ b/mlir/lib/Target/LLVM/CMakeLists.txt
@@ -234,3 +234,10 @@ add_mlir_dialect_library(MLIRXeVMTarget
   MLIRTargetLLVM
   MLIRXeVMToLLVMIRTranslation
 )
+
+target_include_directories(MLIRXeVMTarget
+  PRIVATE
+    ${PROJECT_SOURCE_DIR}/lib/Target/SPIRV
+    ${PROJECT_BINARY_DIR}/lib/Target/SPIRV
+)
+
diff --git a/mlir/lib/Target/LLVM/XeVM/Target.cpp b/mlir/lib/Target/LLVM/XeVM/Target.cpp
index 4285a4e37becf..6410aeac8cde0 100644
--- a/mlir/lib/Target/LLVM/XeVM/Target.cpp
+++ b/mlir/lib/Target/LLVM/XeVM/Target.cpp
@@ -13,6 +13,7 @@
 
 #include "mlir/Target/LLVM/XeVM/Target.h"
 
+#include "MCTargetDesc/SPIRVBaseInfo.h"
 #include "mlir/Dialect/GPU/IR/CompilationInterfaces.h"
 #include "mlir/Dialect/GPU/IR/GPUDialect.h"
 #include "mlir/Dialect/LLVMIR/XeVMDialect.h"
@@ -39,6 +40,12 @@
 #include "llvm/Support/Program.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
+// From llvm/lib/Target/SPIRV
+#if LLVM_HAS_SPIRV_TARGET
+#include "SPIRVCommandLine.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
+#endif
 
 #include <cstdint>
 #include <cstdlib>
@@ -239,6 +246,10 @@ class SPIRVSerializer : public SerializeGPUModuleBase {
 
   static void init();
 
+  /// Runs the serialization pipeline, returning `std::nullopt` on error.
+  std::optional<SmallVector<char, 0>> run() override;
+
+protected:
   /// Serializes the LLVM module to an object format, depending on the
   /// compilation target selected in target options.
   FailureOr<SmallVector<char, 0>>
@@ -265,27 +276,97 @@ void SPIRVSerializer::init() {
   });
 }
 
-FailureOr<SmallVector<char, 0>>
-SPIRVSerializer::moduleToObject(llvm::Module &llvmModule) {
+static const std::vector<std::string> getDefaultSPIRVExtensions() {
+  return {
+      "SPV_INTEL_cache_controls",
+  };
+}
+
+std::optional<SmallVector<char, 0>> SPIRVSerializer::run() {
+  // Translate the module to LLVM IR.
+  llvm::LLVMContext llvmContext;
+  std::unique_ptr<llvm::Module> llvmModule = translateToLLVMIR(llvmContext);
+  if (!llvmModule) {
+    getOperation().emitError() << "Failed creating the llvm::Module.";
+    return std::nullopt;
+  }
+
 #define DEBUG_TYPE "serialize-to-llvm"
   LLVM_DEBUG({
     llvm::dbgs() << "LLVM IR for module: " << getGPUModuleOp().getNameAttr()
                  << "\n";
-    llvm::dbgs() << llvmModule << "\n";
+    llvm::dbgs() << *llvmModule << "\n";
     llvm::dbgs().flush();
   });
 #undef DEBUG_TYPE
 
   // Return LLVM IR if the compilation target is `offload`.
   if (targetOptions.getCompilationTarget() == gpu::CompilationTarget::Offload)
-    return SerializeGPUModuleBase::moduleToObject(llvmModule);
+    return SerializeGPUModuleBase::moduleToObject(*llvmModule);
 
-#if !LLVM_HAS_SPIRV_TARGET
-  return getGPUModuleOp()->emitError(
-      "The `SPIRV` target was not built. Please enable "
-      "it when building LLVM.");
+#if LLVM_HAS_SPIRV_TARGET
+  setDataLayoutAndTriple(*llvmModule);
+
+  // Create the target machine.
+  FailureOr<llvm::TargetMachine *> targetMachine = getOrCreateTargetMachine();
+  if (failed(targetMachine)) {
+    getOperation().emitError()
+        << "Target Machine unavailable for triple " << triple
+        << ", can't output compilation target.\n";
+    return std::nullopt;
+  }
+  // Setup allowed SPIR-V extensions.
+  std::set<llvm::SPIRV::Extension::Extension> AllowedExtIds;
+  llvm::StringRef UnknownExt = llvm::SPIRVExtensionsParser::checkExtensions(
+      getDefaultSPIRVExtensions(), AllowedExtIds);
+  if (!UnknownExt.empty()) {
+    std::string ErrMsg{"Unknown SPIR-V extension: "};
+    ErrMsg.append(UnknownExt.str());
+    getOperation().emitError() << ErrMsg;
+    return std::nullopt;
+  }
+
+  llvm::SPIRVTargetMachine *STM =
+      static_cast<llvm::SPIRVTargetMachine *>(*targetMachine);
+  const_cast<llvm::SPIRVSubtarget *>(STM->getSubtargetImpl())
+      ->initAvailableExtensions(AllowedExtIds);
+
+  if (initialLlvmIRCallback)
+    initialLlvmIRCallback(*llvmModule);
+
+  // Link bitcode files.
+  handleModulePreLink(*llvmModule);
+  {
+    auto libs = loadBitcodeFiles(*llvmModule);
+    if (!libs)
+      return std::nullopt;
+    if (!libs->empty())
+      if (failed(linkFiles(*llvmModule, std::move(*libs))))
+        return std::nullopt;
+    handleModulePostLink(*llvmModule);
+  }
+
+  if (linkedLlvmIRCallback)
+    linkedLlvmIRCallback(*llvmModule);
+
+  // Optimize the module.
+  if (failed(optimizeModule(*llvmModule, optLevel)))
+    return std::nullopt;
+
+  if (optimizedLlvmIRCallback)
+    optimizedLlvmIRCallback(*llvmModule);
+
+  // Return the serialized object.
+  return moduleToObject(*llvmModule);
+#else
+  getOperation().emitError("The `SPIRV` target was not built. Please enable "
+                           "it when building LLVM.");
+  return std::nullopt;
 #endif // LLVM_HAS_SPIRV_TARGET
+}
 
+FailureOr<SmallVector<char, 0>>
+SPIRVSerializer::moduleToObject(llvm::Module &llvmModule) {
   FailureOr<llvm::TargetMachine *> targetMachine = getOrCreateTargetMachine();
   if (failed(targetMachine))
     return getGPUModuleOp().emitError()

>From c4048dc0401611773baeaffa2108f62aa107b00c Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Tue, 3 Feb 2026 21:31:57 +0000
Subject: [PATCH 2/5] Enable SPV_INTEL_variable_length_array

---
 mlir/lib/Target/LLVM/XeVM/Target.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mlir/lib/Target/LLVM/XeVM/Target.cpp b/mlir/lib/Target/LLVM/XeVM/Target.cpp
index 6410aeac8cde0..00a90ab6bd0c1 100644
--- a/mlir/lib/Target/LLVM/XeVM/Target.cpp
+++ b/mlir/lib/Target/LLVM/XeVM/Target.cpp
@@ -279,6 +279,7 @@ void SPIRVSerializer::init() {
 static const std::vector<std::string> getDefaultSPIRVExtensions() {
   return {
       "SPV_INTEL_cache_controls",
+      "SPV_INTEL_variable_length_array",
   };
 }
 

>From 0ce914e6ac3872c4beef67349d778e67cc307d97 Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Mon, 9 Feb 2026 19:46:12 +0000
Subject: [PATCH 3/5] Disable optimization during serialization.

---
 mlir/lib/Target/LLVM/XeVM/Target.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/mlir/lib/Target/LLVM/XeVM/Target.cpp b/mlir/lib/Target/LLVM/XeVM/Target.cpp
index 00a90ab6bd0c1..5d6a6ad452d85 100644
--- a/mlir/lib/Target/LLVM/XeVM/Target.cpp
+++ b/mlir/lib/Target/LLVM/XeVM/Target.cpp
@@ -332,6 +332,9 @@ std::optional<SmallVector<char, 0>> SPIRVSerializer::run() {
   const_cast<llvm::SPIRVSubtarget *>(STM->getSubtargetImpl())
       ->initAvailableExtensions(AllowedExtIds);
 
+  // Disable optimizations
+  (*targetMachine)->setOptLevel(llvm::CodeGenOptLevel::None);
+
   if (initialLlvmIRCallback)
     initialLlvmIRCallback(*llvmModule);
 
@@ -350,12 +353,8 @@ std::optional<SmallVector<char, 0>> SPIRVSerializer::run() {
   if (linkedLlvmIRCallback)
     linkedLlvmIRCallback(*llvmModule);
 
-  // Optimize the module.
-  if (failed(optimizeModule(*llvmModule, optLevel)))
-    return std::nullopt;
-
-  if (optimizedLlvmIRCallback)
-    optimizedLlvmIRCallback(*llvmModule);
+  // Note: Optimizing module discards metadata for cache hints.
+  // Just directly serialize the module.
 
   // Return the serialized object.
   return moduleToObject(*llvmModule);

>From a7e8afd8b6ed770a5f2c9bdde3ea9821e078615d Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Tue, 17 Feb 2026 19:23:40 +0000
Subject: [PATCH 4/5] Put back LLVM optimizer and enable
 SPV_EXT_relaxed_printf_string_address_space

---
 mlir/lib/Target/LLVM/XeVM/Target.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Target/LLVM/XeVM/Target.cpp b/mlir/lib/Target/LLVM/XeVM/Target.cpp
index 5d6a6ad452d85..1e896c1c215ff 100644
--- a/mlir/lib/Target/LLVM/XeVM/Target.cpp
+++ b/mlir/lib/Target/LLVM/XeVM/Target.cpp
@@ -278,6 +278,7 @@ void SPIRVSerializer::init() {
 
 static const std::vector<std::string> getDefaultSPIRVExtensions() {
   return {
+      "SPV_EXT_relaxed_printf_string_address_space",
       "SPV_INTEL_cache_controls",
       "SPV_INTEL_variable_length_array",
   };
@@ -353,8 +354,12 @@ std::optional<SmallVector<char, 0>> SPIRVSerializer::run() {
   if (linkedLlvmIRCallback)
     linkedLlvmIRCallback(*llvmModule);
 
-  // Note: Optimizing module discards metadata for cache hints.
-  // Just directly serialize the module.
+  // Optimize the module.
+  if (failed(optimizeModule(*llvmModule, optLevel)))
+    return std::nullopt;
+
+  if (optimizedLlvmIRCallback)
+    optimizedLlvmIRCallback(*llvmModule);
 
   // Return the serialized object.
   return moduleToObject(*llvmModule);

>From 47819e1e303e179a444ed4c4e12f3fe33fd12500 Mon Sep 17 00:00:00 2001
From: "Lee, Sang Ik" <sang.ik.lee at intel.com>
Date: Wed, 18 Feb 2026 18:25:00 +0000
Subject: [PATCH 5/5] Don't override codegen opt level.

---
 mlir/lib/Target/LLVM/XeVM/Target.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/mlir/lib/Target/LLVM/XeVM/Target.cpp b/mlir/lib/Target/LLVM/XeVM/Target.cpp
index 1e896c1c215ff..de69dd84d8f6e 100644
--- a/mlir/lib/Target/LLVM/XeVM/Target.cpp
+++ b/mlir/lib/Target/LLVM/XeVM/Target.cpp
@@ -333,9 +333,6 @@ std::optional<SmallVector<char, 0>> SPIRVSerializer::run() {
   const_cast<llvm::SPIRVSubtarget *>(STM->getSubtargetImpl())
       ->initAvailableExtensions(AllowedExtIds);
 
-  // Disable optimizations
-  (*targetMachine)->setOptLevel(llvm::CodeGenOptLevel::None);
-
   if (initialLlvmIRCallback)
     initialLlvmIRCallback(*llvmModule);
 



More information about the Mlir-commits mailing list