This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 994e0216d7 [Codegen][LLVM] Add LLVM 23 compatibility (#20189)
994e0216d7 is described below

commit 994e0216d734bf3e02806d8ebf383dafa80e41b9
Author: Shushi Hong <[email protected]>
AuthorDate: Wed Aug 26 09:47:21 2026 -0400

    [Codegen][LLVM] Add LLVM 23 compatibility (#20189)
    
    This PR adds LLVM 23 compatibility after the unbounded `llvmdev >=11` CI
    dependency began resolving to LLVM 23.1.0, updating the changed
    intrinsic, target/subtarget, and ORC JIT APIs while preserving LLVM
    11–22 code paths.
    
    It also fix the lint issue
---
 python/tvm/relax/frontend/onnx/onnx_frontend.py |  7 ++-----
 src/target/llvm/codegen_llvm.cc                 |  4 ++++
 src/target/llvm/llvm_instance.cc                | 23 +++++++++++++++++++++++
 src/target/llvm/llvm_module.cc                  |  9 ++++++++-
 tests/python/relax/test_frontend_onnx.py        |  7 +++++--
 5 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/python/tvm/relax/frontend/onnx/onnx_frontend.py 
b/python/tvm/relax/frontend/onnx/onnx_frontend.py
index 054efa9f0c..a6a2a3152e 100644
--- a/python/tvm/relax/frontend/onnx/onnx_frontend.py
+++ b/python/tvm/relax/frontend/onnx/onnx_frontend.py
@@ -2484,12 +2484,9 @@ class MultiInputBase(OnnxOpConverter):
             # then reduce along it — mirrors the non-constant path below.
             input_shapes = [inp.ty.shape for inp in inputs]
             target_shape = tuple(
-                int(dim)
-                for dim in functools.reduce(compute_broadcast_shape, 
input_shapes)
-            )
-            stacked = _np.stack(
-                [_np.broadcast_to(x, target_shape) for x in np_inputs], axis=0
+                int(dim) for dim in functools.reduce(compute_broadcast_shape, 
input_shapes)
             )
+            stacked = _np.stack([_np.broadcast_to(x, target_shape) for x in 
np_inputs], axis=0)
             output = cls.numpy_op(stacked, axis=0)  # pylint: 
disable=not-callable
             return relax.const(output, output.dtype)
 
diff --git a/src/target/llvm/codegen_llvm.cc b/src/target/llvm/codegen_llvm.cc
index dc454de5ad..24da88e24e 100644
--- a/src/target/llvm/codegen_llvm.cc
+++ b/src/target/llvm/codegen_llvm.cc
@@ -1101,6 +1101,9 @@ llvm::Function* 
CodeGenLLVM::GetIntrinsicDecl(llvm::Intrinsic::ID id, llvm::Type
                                               llvm::ArrayRef<llvm::Type*> 
arg_types) {
   llvm::Module* module = module_.get();
 
+#if TVM_LLVM_VERSION >= 230
+  return llvm::Intrinsic::getOrInsertDeclaration(module, id, ret_type, 
arg_types);
+#else
   if (!llvm::Intrinsic::isOverloaded(id)) {
 #if TVM_LLVM_VERSION >= 200
     return 
llvm::cast<llvm::Function>(llvm::Intrinsic::getOrInsertDeclaration(module, id, 
{}));
@@ -1160,6 +1163,7 @@ llvm::Function* 
CodeGenLLVM::GetIntrinsicDecl(llvm::Intrinsic::ID id, llvm::Type
   }
   // Failed to identify the type.
   return nullptr;
+#endif
 }
 
 void CodeGenLLVM::SetTargetAttributes(llvm::Function* func) {
diff --git a/src/target/llvm/llvm_instance.cc b/src/target/llvm/llvm_instance.cc
index 3f2e1e50c9..0b1275498c 100644
--- a/src/target/llvm/llvm_instance.cc
+++ b/src/target/llvm/llvm_instance.cc
@@ -315,8 +315,10 @@ LLVMTargetInfo::LLVMTargetInfo(LLVMInstance& instance,
 #if TVM_LLVM_VERSION < 220
   target_options_.UnsafeFPMath = false;
 #endif
+#if TVM_LLVM_VERSION < 230
   target_options_.NoInfsFPMath = false;
   target_options_.NoNaNsFPMath = true;
+#endif
   target_options_.FloatABIType = float_abi;
   if (target.find("mabi") != target.end()) {
     target_options_.MCOptions.ABIName = 
target.Get("mabi").value().as_or_throw<ffi::String>();
@@ -467,7 +469,11 @@ bool LLVMTargetInfo::IsValidCPU(const std::string& cpu) 
const {
   if (mc_info) {
 #if TVM_LLVM_VERSION >= 170
     for (const auto& desc : mc_info->getAllProcessorDescriptions()) {
+#if TVM_LLVM_VERSION >= 230
+      if (cpu == desc.key()) {
+#else
       if (cpu == desc.Key) {
+#endif
         return true;
       }
     }
@@ -888,7 +894,11 @@ const ffi::Array<ffi::String> 
LLVMTargetInfo::GetAllLLVMTargetArches() const {
   auto llvm_instance = CreateLLVMTargetInstance(triple_, true);
   std::unique_ptr<llvm::TargetMachine> target_machine =
       CreateLLVMTargetMachine(llvm_instance, triple_, "", "");
+#if TVM_LLVM_VERSION >= 230
+  const auto* MCInfo = &target_machine->getMCSubtargetInfo();
+#else
   const auto MCInfo = target_machine->getMCSubtargetInfo();
+#endif
 
   if (!MCInfo) {
     return cpu_arches;
@@ -901,7 +911,11 @@ const ffi::Array<ffi::String> 
LLVMTargetInfo::GetAllLLVMTargetArches() const {
       MCInfo->getAllProcessorDescriptions();
 #endif
   for (const auto& arch : llvm_arches) {
+#if TVM_LLVM_VERSION >= 230
+    cpu_arches.push_back(arch.key());
+#else
     cpu_arches.push_back(arch.Key);
+#endif
   }
 
   return cpu_arches;
@@ -916,7 +930,11 @@ const ffi::Map<ffi::String, ffi::String> 
LLVMTargetInfo::GetAllLLVMCpuFeatures()
   auto llvm_instance = CreateLLVMTargetInstance(triple_, true);
   std::unique_ptr<llvm::TargetMachine> target_machine =
       CreateLLVMTargetMachine(llvm_instance, triple_, cpu_.c_str(), feats);
+#if TVM_LLVM_VERSION >= 230
+  const auto* MCInfo = &target_machine->getMCSubtargetInfo();
+#else
   const auto MCInfo = target_machine->getMCSubtargetInfo();
+#endif
 
   // get all features for CPU
   llvm::ArrayRef<llvm::SubtargetFeatureKV> llvm_features =
@@ -928,8 +946,13 @@ const ffi::Map<ffi::String, ffi::String> 
LLVMTargetInfo::GetAllLLVMCpuFeatures()
   // TVM doesn't have an FFI friendly Set, so use a Map instead for now
   ffi::Map<ffi::String, ffi::String> cpu_features;
   for (const auto& feat : llvm_features) {
+#if TVM_LLVM_VERSION >= 230
+    if (MCInfo->checkFeatures("+" + std::string(feat.key()))) {
+      cpu_features.Set(feat.key(), "");
+#else
     if (MCInfo->checkFeatures("+" + std::string(feat.Key))) {
       cpu_features.Set(feat.Key, "");
+#endif
     }
   }
 
diff --git a/src/target/llvm/llvm_module.cc b/src/target/llvm/llvm_module.cc
index 637ddb6487..a2226c5dec 100644
--- a/src/target/llvm/llvm_module.cc
+++ b/src/target/llvm/llvm_module.cc
@@ -484,7 +484,10 @@ void LLVMModuleNode::InitORCJIT() {
 
   // linker
   const auto linkerBuilder =
-#if TVM_LLVM_VERSION >= 210
+#if TVM_LLVM_VERSION >= 230
+      [&](llvm::orc::ExecutionSession& session, 
llvm::jitlink::JITLinkMemoryManager& mem_mgr)
+      -> llvm::Expected<std::unique_ptr<llvm::orc::ObjectLayer>> {
+#elif TVM_LLVM_VERSION >= 210
       [&](llvm::orc::ExecutionSession& session)
       -> llvm::Expected<std::unique_ptr<llvm::orc::ObjectLayer>> {
 #else
@@ -501,9 +504,13 @@ void LLVMModuleNode::InitORCJIT() {
 #endif
     auto ObjLinkingLayer =
         std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(session, 
std::move(GetMemMgr));
+#else
+#if TVM_LLVM_VERSION >= 230
+    auto ObjLinkingLayer = 
std::make_unique<llvm::orc::ObjectLinkingLayer>(session, mem_mgr);
 #else
     auto ObjLinkingLayer = 
std::make_unique<llvm::orc::ObjectLinkingLayer>(session);
 #endif
+#endif
 #if TVM_LLVM_VERSION >= 210
     if (tm_builder.getTargetTriple().isOSBinFormatCOFF()) {
 #else
diff --git a/tests/python/relax/test_frontend_onnx.py 
b/tests/python/relax/test_frontend_onnx.py
index 60046d44df..4654a4082a 100644
--- a/tests/python/relax/test_frontend_onnx.py
+++ b/tests/python/relax/test_frontend_onnx.py
@@ -887,12 +887,15 @@ def test_multi_input_constant_rank_axis_bounds(op_name, 
rank):
                 inputs=[],
                 outputs=[name],
                 value=helper.make_tensor(
-                    f"{name}_v", TensorProto.FLOAT, list(shape), 
np.ones(shape, np.float32).flatten().tolist()
+                    f"{name}_v",
+                    TensorProto.FLOAT,
+                    list(shape),
+                    np.ones(shape, np.float32).flatten().tolist(),
                 ),
             )
         )
     graph = helper.make_graph(
-        const_nodes + [helper.make_node(op_name, ["c0", "c1"], ["output"])],
+        [*const_nodes, helper.make_node(op_name, ["c0", "c1"], ["output"])],
         f"const_rank_{op_name}",
         inputs=[],
         outputs=[helper.make_tensor_value_info("output", TensorProto.FLOAT, 
list(shape))],

Reply via email to