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));

Reply via email to