This is an automated email from the ASF dual-hosted git repository.
tlopex 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 d7282a32c2 [BugFix][LLVM] Fix `insertDeclare` API mismatch for
ROCm-bundled LLVM 20 (#19390)
d7282a32c2 is described below
commit d7282a32c21d3cc4e9b40664f98ab4cd0d73578f
Author: Soowon Jeong <[email protected]>
AuthorDate: Wed Apr 22 05:12:45 2026 +0900
[BugFix][LLVM] Fix `insertDeclare` API mismatch for ROCm-bundled LLVM 20
(#19390)
## Problem
Closes #18709.
ROCm ships its own LLVM 20 build that still uses the pre-LLVM-20
`Instruction*` overload of `DIBuilder::insertDeclare`, while upstream
LLVM 20 switched to `BasicBlock::iterator`. The previous guard `#if
TVM_LLVM_VERSION >= 200` in `codegen_llvm.cc` broke ROCm users because
their LLVM reports version 20 but lacks the new overload, causing a
compile error like:
```
error: no matching function for call to
'llvm::DIBuilder::insertDeclare(..., llvm::BasicBlock::iterator)'
note: candidate: insertDeclare(..., llvm::Instruction*)
```
## Fix
Replace the version-number guard with a CMake
`check_cxx_source_compiles` feature probe in
`cmake/utils/FindLLVM.cmake`. The probe compiles a small test program
that calls `insertDeclare` with `BasicBlock::iterator`. The result is
exposed as the preprocessor macro
`TVM_LLVM_INSERTDECLARE_USES_ITERATOR`.
`cmake_push_check_state`/`cmake_pop_check_state` is used to avoid
leaking `CMAKE_REQUIRED_*` variables into the rest of the build.
Three call sites in `src/target/llvm/codegen_llvm.cc` are updated to use
`#if TVM_LLVM_INSERTDECLARE_USES_ITERATOR` instead of `#if
TVM_LLVM_VERSION >= 200`.
**Behavior by configuration:**
| LLVM build | Probe result | Macro set | Code path |
|---|---|---|---|
| Upstream LLVM >= 20 with new overload | Compiles | Yes |
`BasicBlock::iterator` |
| ROCm LLVM 20 (old overload) | Fails | No | `Instruction*` |
| Any LLVM < 20 | Probe skipped | No | `Instruction*` |
## Testing
Tested locally with LLVM 20.1.8 (Ubuntu package):
```
tests/python/codegen/test_target_codegen_llvm.py 39 passed
```
---
cmake/utils/FindLLVM.cmake | 38 ++++++++++++++++++++++++++++++++++++++
src/target/llvm/codegen_llvm.cc | 11 ++++++-----
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/cmake/utils/FindLLVM.cmake b/cmake/utils/FindLLVM.cmake
index d35feef687..851e2acf54 100644
--- a/cmake/utils/FindLLVM.cmake
+++ b/cmake/utils/FindLLVM.cmake
@@ -237,4 +237,42 @@ macro(find_llvm use_llvm)
message(FATAL_ERROR "TVM requires LLVM 15.0 or higher.")
endif()
message(STATUS "Found TVM_LLVM_HAS_AARCH64_TARGET="
${TVM_LLVM_HAS_AARCH64_TARGET})
+
+ # Detect whether DIBuilder insertion APIs (insertDeclare,
+ # insertDbgValueIntrinsic) accept BasicBlock::iterator as the insertion point
+ # (upstream LLVM 20+) vs Instruction* (pre-LLVM 20 and ROCm-bundled LLVM 20,
+ # which reports version 200 but retains the legacy Instruction* overload).
+ if (${TVM_LLVM_VERSION} GREATER_EQUAL 200)
+ include(CheckCXXSourceCompiles)
+ include(CMakePushCheckState)
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIRS})
+ # Only force -std= when the outer project hasn't already selected a
+ # standard; signature-only probe does not need -fno-rtti. Use the
+ # compiler-appropriate form so the probe works under MSVC as well.
+ if(NOT CMAKE_CXX_STANDARD)
+ if(MSVC)
+ set(CMAKE_REQUIRED_FLAGS "/std:c++17")
+ else()
+ set(CMAKE_REQUIRED_FLAGS "-std=c++17")
+ endif()
+ endif()
+ check_cxx_source_compiles("
+ #include <llvm/IR/DIBuilder.h>
+ #include <llvm/IR/Instructions.h>
+ void f(llvm::DIBuilder* b, llvm::Value* v, llvm::DILocalVariable* var,
+ llvm::DIExpression* e, const llvm::DILocation* dl,
+ llvm::Instruction* i) {
+ b->insertDeclare(v, var, e, dl, llvm::BasicBlock::iterator(i));
+ b->insertDbgValueIntrinsic(v, var, e, dl,
llvm::BasicBlock::iterator(i));
+ }
+ " TVM_LLVM_DIBUILDER_USES_ITERATOR)
+ cmake_pop_check_state()
+ if(TVM_LLVM_DIBUILDER_USES_ITERATOR)
+ add_definitions(-DTVM_LLVM_DIBUILDER_USES_ITERATOR=1)
+ message(STATUS "LLVM DIBuilder insertion APIs use BasicBlock::iterator")
+ else()
+ message(STATUS "LLVM DIBuilder insertion APIs use Instruction* (ROCm or
older LLVM 20)")
+ endif()
+ endif()
endmacro(find_llvm)
diff --git a/src/target/llvm/codegen_llvm.cc b/src/target/llvm/codegen_llvm.cc
index 3fcaaaf46d..a78451a741 100644
--- a/src/target/llvm/codegen_llvm.cc
+++ b/src/target/llvm/codegen_llvm.cc
@@ -2147,7 +2147,7 @@ void CodeGenLLVM::AddDebugInformation(llvm::Function*
f_llvm,
auto* store = builder.CreateStore(iter_param, paramAlloca);
auto* di_loc = llvm::DILocation::get(*ctx, 0, 0, di_subprogram_);
-#if TVM_LLVM_VERSION >= 200
+#if TVM_LLVM_DIBUILDER_USES_ITERATOR
dbg_info_->di_builder_->insertDeclare(
paramAlloca, param, dbg_info_->di_builder_->createExpression(),
llvm::DebugLoc(di_loc),
llvm::BasicBlock::iterator(store));
@@ -2193,9 +2193,10 @@ void CodeGenLLVM::AddDebugInformation(llvm::Value*
llvm_value, const Var& tir_va
// the SSA value directly rather than a memory location.
if (!llvm_value->getType()->isPointerTy()) {
if (insert_before) {
- // LLVM 20+ changed insertDbgValueIntrinsic to take BasicBlock::iterator
- // instead of Instruction* for the insertion point.
-#if TVM_LLVM_VERSION >= 200
+ // Upstream LLVM 20+ changed insertDbgValueIntrinsic to take
+ // BasicBlock::iterator; ROCm-bundled LLVM 20 retains Instruction*.
+ // TVM_LLVM_DIBUILDER_USES_ITERATOR is set by CMake feature detection.
+#if TVM_LLVM_DIBUILDER_USES_ITERATOR
dbg_info_->di_builder_->insertDbgValueIntrinsic(
llvm_value, local_var, dbg_info_->di_builder_->createExpression(),
llvm::DebugLoc(di_loc),
llvm::BasicBlock::iterator(insert_before));
@@ -2213,7 +2214,7 @@ void CodeGenLLVM::AddDebugInformation(llvm::Value*
llvm_value, const Var& tir_va
}
if (insert_before) {
-#if TVM_LLVM_VERSION >= 200
+#if TVM_LLVM_DIBUILDER_USES_ITERATOR
dbg_info_->di_builder_->insertDeclare(
llvm_value, local_var, dbg_info_->di_builder_->createExpression(),
llvm::DebugLoc(di_loc),
llvm::BasicBlock::iterator(insert_before));