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 7a41af002b [FIX][LLVM] Use isCPUStringValid for mcpu validation 
instead of enumerating processor descriptions (#18884)
7a41af002b is described below

commit 7a41af002bf1f77de7b22a7eb06333fa4ed0ceac
Author: Gabe Guralnick <[email protected]>
AuthorDate: Tue Mar 10 10:39:09 2026 -0500

    [FIX][LLVM] Use isCPUStringValid for mcpu validation instead of enumerating 
processor descriptions (#18884)
    
    ## Summary
    
    Fix false rejection of `apple-m1`, `apple-m2`, and `apple-m3` as LLVM
    CPU names when building TVM with LLVM 22+.
    
    ## Behavior
    
    After following the [installation from source
    instructions](https://tvm.apache.org/docs/install/from_source.html) and
    building against LLVM 22, every `import tvm` produces spurious error
    messages:
    
    ```
    Error: Using LLVM 22.1.0 with `-mcpu=apple-m1` is not valid in 
`-mtriple=arm64-apple-macos`, using default `-mcpu=generic`
    Error: Using LLVM 22.1.0 with `-mcpu=apple-m2` is not valid in 
`-mtriple=arm64-apple-macos`, using default `-mcpu=generic`
    ```
    
    These are triggered by the Metal target tag registrations in
    `python/tvm/target/tag_registry/metal.py`, which use `apple-m1` and
    `apple-m2` as the host `-mcpu`. The CPUs are silently downgraded to
    `generic`.
    
    ## Root cause
    
    LLVM 22 reorganized its AArch64 processor table. `apple-m1` through
    `apple-m3` are now CPU **aliases** — fully valid and accepted by
    `createTargetMachine` and `isCPUStringValid()`, but no longer returned
    by `MCSubtargetInfo::getAllProcessorDescriptions()`.
    
    TVM's `LLVMTargetInfo` constructor validates `-mcpu` by enumerating
    `getAllProcessorDescriptions()` and checking membership, so it misses
    alias-only names.
    
    ## Fix
    
    Replace the enumeration-based check with a new `IsValidCPU()` method
    that uses `MCSubtargetInfo::isCPUStringValid()`, which correctly handles
    both primary names and aliases. This API has been available since at
    least LLVM 7, well before TVM's minimum supported version.
    
    ## Validation
    
    - Built and tested on macOS (Apple Silicon) with LLVM 22.1.0
    - `python -c "import tvm; print(tvm.__file__)"` produces clean output
    with no error messages
    
    ---------
    
    Co-authored-by: Gabriel Guralnick <[email protected]>
---
 src/target/llvm/llvm_instance.cc | 21 ++++++++++++++++++---
 src/target/llvm/llvm_instance.h  |  7 +++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/target/llvm/llvm_instance.cc b/src/target/llvm/llvm_instance.cc
index 48fa1de406..90d3b65966 100644
--- a/src/target/llvm/llvm_instance.cc
+++ b/src/target/llvm/llvm_instance.cc
@@ -210,9 +210,7 @@ LLVMTargetInfo::LLVMTargetInfo(LLVMInstance& instance,
   // llvm module target
   if (Downcast<ffi::String>(target.Get("kind").value()) == "llvm") {
     // legalize -mcpu with the target -mtriple
-    auto arches = GetAllLLVMTargetArches();
-    bool has_arch =
-        std::any_of(arches.begin(), arches.end(), [&](const auto& var) { 
return var == cpu_; });
+    bool has_arch = IsValidCPU(cpu_);
     if (!has_arch) {
       // Flag an error, but don't abort. This mimicks the behaviour of 'llc' to
       // give the code a chance to run with a less-specific target.
@@ -442,6 +440,23 @@ llvm::TargetMachine* 
LLVMTargetInfo::GetOrCreateTargetMachine(bool allow_missing
   return target_machine_.get();
 }
 
+bool LLVMTargetInfo::IsValidCPU(const std::string& cpu) const {
+  auto llvm_instance = CreateLLVMTargetInstance(triple_, true);
+  if (!llvm_instance) return false;
+  // Create MCSubtargetInfo directly instead of a full TargetMachine,
+  // since we only need isCPUStringValid which correctly handles CPU aliases
+  // (e.g. apple-m1 in LLVM 22+) that don't appear in 
getAllProcessorDescriptions().
+#if TVM_LLVM_VERSION >= 220
+  llvm::Triple triple_obj(triple_);
+  std::unique_ptr<llvm::MCSubtargetInfo> mc_info(
+      llvm_instance->createMCSubtargetInfo(triple_obj, "", ""));
+#else
+  std::unique_ptr<llvm::MCSubtargetInfo> mc_info(
+      llvm_instance->createMCSubtargetInfo(triple_, "", ""));
+#endif
+  return mc_info && mc_info->isCPUStringValid(cpu);
+}
+
 std::string LLVMTargetInfo::GetTargetFeatureString() const {  //
   return Join(",", attrs_);
 }
diff --git a/src/target/llvm/llvm_instance.h b/src/target/llvm/llvm_instance.h
index 9fec366712..0cb141de99 100644
--- a/src/target/llvm/llvm_instance.h
+++ b/src/target/llvm/llvm_instance.h
@@ -317,6 +317,13 @@ class LLVMTargetInfo {
    */
   const ffi::Array<ffi::String> GetAllLLVMTargetArches() const;
 
+  /*!
+   * \brief Check if a CPU name is valid for this target triple
+   * \param cpu The CPU name to validate
+   * \return true if the CPU is recognized (including aliases)
+   */
+  bool IsValidCPU(const std::string& cpu) const;
+
   /*!
    * \brief Get all CPU features from target
    * \return Map with all valid cpu features as keys and empty string as 
value. The Map

Reply via email to