[llvm] RuntimeLibcalls: Emit all available impls for a libcall, not just one (PR #210915)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 21 02:21:30 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-tablegen

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

The intent is RuntimeLibcalls should represent all functions that are
callable from the module, which may have contextually selectable alternatives.
Previously we had this warning since there was no mechanism to select which
one you want, and as a workaround the library call sets avoided adding the
variants which should nto be selected.

Now targets can use initLibcallLoweringInfo, so remove the warning to unblock
more libcall cleanups. Eventually initLibcallLoweringInfo should also be tablegen
driven.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply@<!-- -->anthropic.com>

---
Full diff: https://github.com/llvm/llvm-project/pull/210915.diff


2 Files Affected:

- (renamed) llvm/test/TableGen/RuntimeLibcallEmitter-multiple-impls.td (+10-7) 
- (modified) llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp (+3-25) 


``````````diff
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td b/llvm/test/TableGen/RuntimeLibcallEmitter-multiple-impls.td
similarity index 83%
rename from llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
rename to llvm/test/TableGen/RuntimeLibcallEmitter-multiple-impls.td
index dd485f1a3c445..06a37467a3fef 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-conflict-warning.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-multiple-impls.td
@@ -1,8 +1,11 @@
 // RUN: llvm-tblgen -gen-runtime-libcalls -I %p/../../include %s 2> %t.err | FileCheck %s
-// RUN: FileCheck -check-prefix=ERR %s < %t.err
+// RUN: count 0 < %t.err
 
 // Check behavior of libcall emission when multiple RuntimeLibcallImpl
-// implementations provide the same RuntimeLibcall
+// implementations provide the same RuntimeLibcall. This table records which
+// implementations are available, not which one is selected, so all of the
+// implementations are emitted; selection of the preferred one is a separate
+// concern handled by LibcallLoweringInfo. No diagnostic is emitted.
 
 include "llvm/IR/RuntimeLibcallsImpl.td"
 
@@ -33,6 +36,7 @@ def dup1 : RuntimeLibcallImpl<ANOTHER_DUP>;
 
 // CHECK-NEXT:    static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:        RTLIB::impl_func_b, // func_b
+// CHECK-NEXT:        RTLIB::impl_func_a, // func_a
 // CHECK-NEXT:    };
 // CHECK-EMPTY:
 // CHECK-NEXT:    for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
@@ -42,7 +46,6 @@ def dup1 : RuntimeLibcallImpl<ANOTHER_DUP>;
 // CHECK-NEXT:    return;
 // CHECK-NEXT:  }
 
-// ERR: :[[@LINE+1]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_b, func_a
 def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
   (add func_b, func_a)
 >;
@@ -56,6 +59,7 @@ def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
 // CHECK-NEXT:    static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:        RTLIB::impl_other_func, // other_func
 // CHECK-NEXT:        RTLIB::impl_func_a, // func_a
+// CHECK-NEXT:        RTLIB::impl_func_b, // func_b
 // CHECK-NEXT:    };
 // CHECK-EMPTY:
 // CHECK-NEXT:    for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
@@ -65,7 +69,6 @@ def TheSystemLibraryA : SystemRuntimeLibrary<isTargetArchA,
 // CHECK-NEXT:    return;
 // CHECK-NEXT:  }
 
-// ERR: :[[@LINE+1]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_a, func_b
 def TheSystemLibraryB : SystemRuntimeLibrary<isTargetArchB,
   (add func_a, other_func, func_b)
 >;
@@ -78,8 +81,11 @@ def TheSystemLibraryB : SystemRuntimeLibrary<isTargetArchB,
 // CHECK-EMPTY:
 // CHECK-NEXT:     static const RTLIB::LibcallImpl LibraryCalls[] = {
 // CHECK-NEXT:         RTLIB::impl_dup1, // dup1
+// CHECK-NEXT:         RTLIB::impl_dup0, // dup0
 // CHECK-NEXT:         RTLIB::impl_other_func, // other_func
 // CHECK-NEXT:         RTLIB::impl_func_a, // func_a
+// CHECK-NEXT:         RTLIB::impl_func_b, // func_b
+// CHECK-NEXT:         RTLIB::impl_func_c, // func_c
 // CHECK-NEXT:     };
 // CHECK-EMPTY:
 // CHECK-NEXT:     for (const RTLIB::LibcallImpl Impl : LibraryCalls) {
@@ -89,9 +95,6 @@ def TheSystemLibraryB : SystemRuntimeLibrary<isTargetArchB,
 // CHECK-NEXT:    return;
 // CHECK-NEXT:  }
 
-// ERR: :[[@LINE+3]]:5: warning: conflicting implementations for libcall ANOTHER_DUP: dup1, dup0
-// ERR: :[[@LINE+2]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_a, func_b
-// ERR: :[[@LINE+1]]:5: warning: conflicting implementations for libcall SOME_FUNC: func_a, func_c
 def TheSystemLibraryC : SystemRuntimeLibrary<isTargetArchC,
   (add func_a, dup1, other_func, func_b, func_c, dup0)
 >;
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
index e8746c6dcfcdb..7a0bd4228117c 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
@@ -476,36 +476,14 @@ void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
 
       std::vector<const RuntimeLibcallImpl *> &Funcs = FuncsWithCC.LibcallImpls;
 
-      // Ensure we only emit a unique implementation per libcall in the
-      // selection table.
-      //
-      // FIXME: We need to generate separate functions for
-      // is-libcall-available and should-libcall-be-used to avoid this.
-      //
-      // This also makes it annoying to make use of the default set, since the
-      // entries from the default set may win over the replacements unless
-      // they are explicitly removed.
+      // This table records which implementations are available, not which one
+      // is selected, so a libcall may legitimately have more than one available
+      // implementation
       stable_sort(Funcs, [](const RuntimeLibcallImpl *A,
                             const RuntimeLibcallImpl *B) {
         return A->getProvides()->getEnumVal() < B->getProvides()->getEnumVal();
       });
 
-      auto UniqueI = llvm::unique(
-          Funcs, [&](const RuntimeLibcallImpl *A, const RuntimeLibcallImpl *B) {
-            if (A->getProvides() == B->getProvides()) {
-              PrintWarning(R->getLoc(),
-                           Twine("conflicting implementations for libcall " +
-                                 A->getProvides()->getName() + ": " +
-                                 A->getLibcallFuncName() + ", " +
-                                 B->getLibcallFuncName()));
-              return true;
-            }
-
-            return false;
-          });
-
-      Funcs.erase(UniqueI, Funcs.end());
-
       OS << indent(IndentDepth + 2)
          << "static const RTLIB::LibcallImpl LibraryCalls";
       SubsetPredicate.emitTableVariableNameSuffix(OS);

``````````

</details>


https://github.com/llvm/llvm-project/pull/210915


More information about the llvm-commits mailing list