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))],