Skip to content

RuntimeLibcalls: Stop opting out of exp10 #148604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

arsenm
Copy link
Contributor

@arsenm arsenm commented Jul 14, 2025

This changes the behavior on old darwin triples for x86_fp80;
it now turns into an error instead of emitting exp10l. The comments
in TargetLibraryInfo suggest it never existed.

Copy link
Contributor Author

arsenm commented Jul 14, 2025

@arsenm arsenm marked this pull request as ready for review July 14, 2025 10:16
@llvmbot
Copy link
Member

llvmbot commented Jul 14, 2025

@llvm/pr-subscribers-backend-x86

Author: Matt Arsenault (arsenm)

Changes

This changes the behavior on old darwin triples for x86_fp80;
it now turns into an error instead of emitting exp10l. The comments
in TargetLibraryInfo suggest it never existed.


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

4 Files Affected:

  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+27-8)
  • (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+6-8)
  • (modified) llvm/test/CodeGen/X86/exp10-libcall-names.ll (+1-44)
  • (added) llvm/test/CodeGen/X86/exp10l-libcall-names.ll (+46)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 7aa30f5491d73..6579ba43df918 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -29,6 +29,9 @@ def isNotOSWindowsOrIsCygwinMinGW
 def isGNUEnvironment : RuntimeLibcallPredicate<"TT.isGNUEnvironment()">;
 def darwinHasSinCosStret : RuntimeLibcallPredicate<"darwinHasSinCosStret(TT)">;
 def darwinHasExp10 : RuntimeLibcallPredicate<"darwinHasExp10(TT)">;
+
+def hasExp10 : RuntimeLibcallPredicate<[{!TT.isOSDarwin()}]>;
+
 def hasSinCos : RuntimeLibcallPredicate<"hasSinCos(TT)">;
 
 // FIXME: Way to combine predicates
@@ -776,12 +779,6 @@ def __exp2l_finite_f80 : RuntimeLibcallImpl<EXP2_FINITE_F80, "__exp2l_finite">;
 def __exp2l_finite_f128 : RuntimeLibcallImpl<EXP2_FINITE_F128, "__exp2l_finite">;
 def __exp2l_finite_ppcf128 : RuntimeLibcallImpl<EXP2_FINITE_PPCF128, "__exp2l_finite">;
 
-def exp10f : RuntimeLibcallImpl<EXP10_F32>;
-def exp10 : RuntimeLibcallImpl<EXP10_F64>;
-def exp10l_f80 : RuntimeLibcallImpl<EXP10_F80, "exp10l">;
-def exp10l_f128 : RuntimeLibcallImpl<EXP10_F128, "exp10l">;
-def exp10l_ppcf128 : RuntimeLibcallImpl<EXP10_PPCF128, "exp10l">;
-
 def sinf : RuntimeLibcallImpl<SIN_F32>;
 def sin : RuntimeLibcallImpl<SIN_F64>;
 defm sin : LibmLongDoubleLibCall;
@@ -942,6 +939,12 @@ def calloc : RuntimeLibcallImpl<CALLOC>;
 
 } // End let IsDefault = true
 
+def exp10f : RuntimeLibcallImpl<EXP10_F32>;
+def exp10 : RuntimeLibcallImpl<EXP10_F64>;
+def exp10l_f80 : RuntimeLibcallImpl<EXP10_F80, "exp10l">;
+def exp10l_f128 : RuntimeLibcallImpl<EXP10_F128, "exp10l">;
+def exp10l_ppcf128 : RuntimeLibcallImpl<EXP10_PPCF128, "exp10l">;
+
 //--------------------------------------------------------------------
 // compiler-rt/libgcc but 64-bit only, not available by default
 //--------------------------------------------------------------------
@@ -1101,6 +1104,12 @@ defvar LibmHasSinCosF80 = LibcallImpls<(add sincos_f80), hasSinCos>;
 defvar LibmHasSinCosF128 = LibcallImpls<(add sincos_f128), hasSinCos>;
 defvar LibmHasSinCosPPCF128 = LibcallImpls<(add sincos_ppcf128), hasSinCos>;
 
+defvar LibmHasExp10F32 = LibcallImpls<(add exp10f), hasExp10>;
+defvar LibmHasExp10F64 = LibcallImpls<(add exp10), hasExp10>;
+defvar LibmHasExp10F80 = LibcallImpls<(add exp10l_f80), hasExp10>;
+defvar LibmHasExp10F128 = LibcallImpls<(add exp10l_f128), hasExp10>;
+defvar LibmHasExp10PPCF128 = LibcallImpls<(add exp10l_ppcf128), hasExp10>;
+
 defvar WindowsMathRemovals = [
   ldexpf, ldexp_f80, ldexp_f128, ldexp_ppcf128,
   frexpf, frexp_f80, frexp_f128, frexp_ppcf128
@@ -1199,7 +1208,8 @@ def AArch64SystemLibrary : SystemRuntimeLibrary<
        LibcallImpls<(add Int128RTLibcalls), isAArch64_ILP64>,
        LibcallImpls<(add bzero), isOSDarwin>,
        DarwinExp10, DarwinSinCosStret,
-       LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128)
+       LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+       LibmHasExp10F32, LibmHasExp10F64, LibmHasExp10F128)
 >;
 
 // Prepend a # to every name
@@ -1470,6 +1480,7 @@ def ARMSystemLibrary
            AEABIDivRemCalls,
            DarwinSinCosStret, DarwinExp10,
            LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+           LibmHasExp10F32, LibmHasExp10F64,  LibmHasExp10F128,
 
            // Use divmod compiler-rt calls for iOS 5.0 and later.
            LibcallImpls<(add __divmodsi4, __udivmodsi4),
@@ -1962,6 +1973,7 @@ def PPCSystemLibrary
                 DefaultRuntimeLibcallImpls_f128),
            __extendkftf2, __trunctfkf2,
            DefaultRuntimeLibcallImpls_ppcf128,
+           exp10f, exp10, exp10l_ppcf128,
            LibmF128Libcalls, AIX32Calls, AIX64Calls,
            LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
            LibmHasSinCosPPCF128,
@@ -1977,7 +1989,9 @@ def isRISCV64 : RuntimeLibcallPredicate<"TT.isRISCV64()">;
 
 def RISCVSystemLibrary
     : SystemRuntimeLibrary<isRISCV,
-      (add DefaultRuntimeLibcallImpls, __riscv_flush_icache,
+      (add DefaultRuntimeLibcallImpls,
+           exp10f, exp10, exp10l_f128,
+           __riscv_flush_icache,
            LibcallImpls<(add Int128RTLibcalls), isRISCV64>)>;
 
 //===----------------------------------------------------------------------===//
@@ -2086,6 +2100,10 @@ defvar X86CommonLibcalls =
        LibmHasFrexpF32, LibmHasLdexpF32,
        LibmHasFrexpF80, LibmHasLdexpF80,
        DefaultRuntimeLibcallImpls_f80,
+
+       LibmHasExp10F32, LibmHasExp10F64, LibmHasExp10F80,
+       LibmHasExp10F128,
+
        // MSVCRT doesn't have powi
        // FIXME: It's almost certainly correct that MSVCRT has
        // __powitf2_f128, but at least one test is relying on it.
@@ -2230,4 +2248,5 @@ def WasmSystemLibrary
     : SystemRuntimeLibrary<isWasm,
       (add DefaultRuntimeLibcallImpls, Int128RTLibcalls,
            CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls,
+           exp10f, exp10,
            emscripten_return_address)>;
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 60da0047291a9..038a511ed2e68 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -99,21 +99,15 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
       setLibcallImplCallingConv(RTLIB::__sincos_stret,
                                 CallingConv::ARM_AAPCS_VFP);
     }
-
-    if (!darwinHasExp10(TT)) {
-      // FIXME: Remove exp10 from default set
-      setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported);
-      setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported);
-    }
   }
 
   if (TT.isOSOpenBSD()) {
     setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported);
   }
 
-  // Skip default manual processing for targets that have been fully ported to
+  // Skip default manual processing for targets that have been mostly ported to
   // tablegen for now. Eventually the rest of this should be deleted.
-  if (TT.isX86() || TT.isAArch64() || TT.isWasm())
+  if (TT.isX86() || TT.isAArch64() || TT.isWasm() || TT.isPPC())
     return;
 
   if (TT.isARM() || TT.isThumb()) {
@@ -127,6 +121,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
     setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128);
   }
 
+  setLibcallImpl(RTLIB::EXP10_F32, RTLIB::exp10f);
+  setLibcallImpl(RTLIB::EXP10_F64, RTLIB::exp10);
+  setLibcallImpl(RTLIB::EXP10_F128, RTLIB::exp10l_f128);
+
   // These libcalls are only available in compiler-rt, not libgcc.
   if (TT.isArch64Bit()) {
     setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3);
diff --git a/llvm/test/CodeGen/X86/exp10-libcall-names.ll b/llvm/test/CodeGen/X86/exp10-libcall-names.ll
index 96e3aae408e94..2688474b2ce5c 100644
--- a/llvm/test/CodeGen/X86/exp10-libcall-names.ll
+++ b/llvm/test/CodeGen/X86/exp10-libcall-names.ll
@@ -13,10 +13,7 @@
 ; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X86
 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X64
 
-; RUN: not llc -mtriple=x86_64-apple-macos10.8 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
-; Check exp10/exp10f is emitted as __exp10/__exp10f on assorted systems.
-
-; ERR: no libcall available for fexp10
+; Check exp10/exp10f is emitted as __exp10/__exp10f on assorted darwin systems.
 
 define float @test_exp10_f32(float %x) nounwind {
 ; LINUX-LABEL: test_exp10_f32:
@@ -78,43 +75,3 @@ define double @test_exp10_f64(double %x) nounwind {
   %ret = call double @llvm.exp10.f64(double %x)
   ret double %ret
 }
-
-define x86_fp80 @test_exp10_f80(x86_fp80 %x) nounwind {
-; LINUX-LABEL: test_exp10_f80:
-; LINUX:       # %bb.0:
-; LINUX-NEXT:    subq $24, %rsp
-; LINUX-NEXT:    fldt {{[0-9]+}}(%rsp)
-; LINUX-NEXT:    fstpt (%rsp)
-; LINUX-NEXT:    callq exp10l@PLT
-; LINUX-NEXT:    addq $24, %rsp
-; LINUX-NEXT:    retq
-;
-; APPLE-LABEL: test_exp10_f80:
-; APPLE:       ## %bb.0:
-; APPLE-NEXT:    subq $24, %rsp
-; APPLE-NEXT:    fldt {{[0-9]+}}(%rsp)
-; APPLE-NEXT:    fstpt (%rsp)
-; APPLE-NEXT:    callq _exp10l
-; APPLE-NEXT:    addq $24, %rsp
-; APPLE-NEXT:    retq
-;
-; GISEL-X86-LABEL: test_exp10_f80:
-; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $12, %esp
-; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstpt (%esp)
-; GISEL-X86-NEXT:    calll exp10l
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: test_exp10_f80:
-; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    subq $24, %rsp
-; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstpt (%rsp)
-; GISEL-X64-NEXT:    callq exp10l
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %ret = call x86_fp80 @llvm.exp10.f80(x86_fp80 %x)
-  ret x86_fp80 %ret
-}
diff --git a/llvm/test/CodeGen/X86/exp10l-libcall-names.ll b/llvm/test/CodeGen/X86/exp10l-libcall-names.ll
new file mode 100644
index 0000000000000..2e7f9e34f662a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/exp10l-libcall-names.ll
@@ -0,0 +1,46 @@
+; RUN: llc -mtriple=x86_64-linux-gnu < %s | FileCheck -check-prefix=LINUX %s
+; RUN: not llc -mtriple=x86_64-apple-macos10.9 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-ios9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-tvos9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-watchos9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-xros9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-ios8.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-tvos8.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-xros8.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-driverkit < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-driverkit24.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X86
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X64
+
+; ERR: no libcall available for fexp10
+
+define x86_fp80 @test_exp10_f80(x86_fp80 %x) nounwind {
+; LINUX-LABEL: test_exp10_f80:
+; LINUX:       # %bb.0:
+; LINUX-NEXT:    subq $24, %rsp
+; LINUX-NEXT:    fldt {{[0-9]+}}(%rsp)
+; LINUX-NEXT:    fstpt (%rsp)
+; LINUX-NEXT:    callq exp10l@PLT
+; LINUX-NEXT:    addq $24, %rsp
+; LINUX-NEXT:    retq
+;
+; GISEL-X86-LABEL: test_exp10_f80:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $12, %esp
+; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstpt (%esp)
+; GISEL-X86-NEXT:    calll exp10l
+; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    retl
+;
+; GISEL-X64-LABEL: test_exp10_f80:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    subq $24, %rsp
+; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpt (%rsp)
+; GISEL-X64-NEXT:    callq exp10l
+; GISEL-X64-NEXT:    addq $24, %rsp
+; GISEL-X64-NEXT:    retq
+  %ret = call x86_fp80 @llvm.exp10.f80(x86_fp80 %x)
+  ret x86_fp80 %ret
+}

@llvmbot
Copy link
Member

llvmbot commented Jul 14, 2025

@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)

Changes

This changes the behavior on old darwin triples for x86_fp80;
it now turns into an error instead of emitting exp10l. The comments
in TargetLibraryInfo suggest it never existed.


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

4 Files Affected:

  • (modified) llvm/include/llvm/IR/RuntimeLibcalls.td (+27-8)
  • (modified) llvm/lib/IR/RuntimeLibcalls.cpp (+6-8)
  • (modified) llvm/test/CodeGen/X86/exp10-libcall-names.ll (+1-44)
  • (added) llvm/test/CodeGen/X86/exp10l-libcall-names.ll (+46)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 7aa30f5491d73..6579ba43df918 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -29,6 +29,9 @@ def isNotOSWindowsOrIsCygwinMinGW
 def isGNUEnvironment : RuntimeLibcallPredicate<"TT.isGNUEnvironment()">;
 def darwinHasSinCosStret : RuntimeLibcallPredicate<"darwinHasSinCosStret(TT)">;
 def darwinHasExp10 : RuntimeLibcallPredicate<"darwinHasExp10(TT)">;
+
+def hasExp10 : RuntimeLibcallPredicate<[{!TT.isOSDarwin()}]>;
+
 def hasSinCos : RuntimeLibcallPredicate<"hasSinCos(TT)">;
 
 // FIXME: Way to combine predicates
@@ -776,12 +779,6 @@ def __exp2l_finite_f80 : RuntimeLibcallImpl<EXP2_FINITE_F80, "__exp2l_finite">;
 def __exp2l_finite_f128 : RuntimeLibcallImpl<EXP2_FINITE_F128, "__exp2l_finite">;
 def __exp2l_finite_ppcf128 : RuntimeLibcallImpl<EXP2_FINITE_PPCF128, "__exp2l_finite">;
 
-def exp10f : RuntimeLibcallImpl<EXP10_F32>;
-def exp10 : RuntimeLibcallImpl<EXP10_F64>;
-def exp10l_f80 : RuntimeLibcallImpl<EXP10_F80, "exp10l">;
-def exp10l_f128 : RuntimeLibcallImpl<EXP10_F128, "exp10l">;
-def exp10l_ppcf128 : RuntimeLibcallImpl<EXP10_PPCF128, "exp10l">;
-
 def sinf : RuntimeLibcallImpl<SIN_F32>;
 def sin : RuntimeLibcallImpl<SIN_F64>;
 defm sin : LibmLongDoubleLibCall;
@@ -942,6 +939,12 @@ def calloc : RuntimeLibcallImpl<CALLOC>;
 
 } // End let IsDefault = true
 
+def exp10f : RuntimeLibcallImpl<EXP10_F32>;
+def exp10 : RuntimeLibcallImpl<EXP10_F64>;
+def exp10l_f80 : RuntimeLibcallImpl<EXP10_F80, "exp10l">;
+def exp10l_f128 : RuntimeLibcallImpl<EXP10_F128, "exp10l">;
+def exp10l_ppcf128 : RuntimeLibcallImpl<EXP10_PPCF128, "exp10l">;
+
 //--------------------------------------------------------------------
 // compiler-rt/libgcc but 64-bit only, not available by default
 //--------------------------------------------------------------------
@@ -1101,6 +1104,12 @@ defvar LibmHasSinCosF80 = LibcallImpls<(add sincos_f80), hasSinCos>;
 defvar LibmHasSinCosF128 = LibcallImpls<(add sincos_f128), hasSinCos>;
 defvar LibmHasSinCosPPCF128 = LibcallImpls<(add sincos_ppcf128), hasSinCos>;
 
+defvar LibmHasExp10F32 = LibcallImpls<(add exp10f), hasExp10>;
+defvar LibmHasExp10F64 = LibcallImpls<(add exp10), hasExp10>;
+defvar LibmHasExp10F80 = LibcallImpls<(add exp10l_f80), hasExp10>;
+defvar LibmHasExp10F128 = LibcallImpls<(add exp10l_f128), hasExp10>;
+defvar LibmHasExp10PPCF128 = LibcallImpls<(add exp10l_ppcf128), hasExp10>;
+
 defvar WindowsMathRemovals = [
   ldexpf, ldexp_f80, ldexp_f128, ldexp_ppcf128,
   frexpf, frexp_f80, frexp_f128, frexp_ppcf128
@@ -1199,7 +1208,8 @@ def AArch64SystemLibrary : SystemRuntimeLibrary<
        LibcallImpls<(add Int128RTLibcalls), isAArch64_ILP64>,
        LibcallImpls<(add bzero), isOSDarwin>,
        DarwinExp10, DarwinSinCosStret,
-       LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128)
+       LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+       LibmHasExp10F32, LibmHasExp10F64, LibmHasExp10F128)
 >;
 
 // Prepend a # to every name
@@ -1470,6 +1480,7 @@ def ARMSystemLibrary
            AEABIDivRemCalls,
            DarwinSinCosStret, DarwinExp10,
            LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+           LibmHasExp10F32, LibmHasExp10F64,  LibmHasExp10F128,
 
            // Use divmod compiler-rt calls for iOS 5.0 and later.
            LibcallImpls<(add __divmodsi4, __udivmodsi4),
@@ -1962,6 +1973,7 @@ def PPCSystemLibrary
                 DefaultRuntimeLibcallImpls_f128),
            __extendkftf2, __trunctfkf2,
            DefaultRuntimeLibcallImpls_ppcf128,
+           exp10f, exp10, exp10l_ppcf128,
            LibmF128Libcalls, AIX32Calls, AIX64Calls,
            LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
            LibmHasSinCosPPCF128,
@@ -1977,7 +1989,9 @@ def isRISCV64 : RuntimeLibcallPredicate<"TT.isRISCV64()">;
 
 def RISCVSystemLibrary
     : SystemRuntimeLibrary<isRISCV,
-      (add DefaultRuntimeLibcallImpls, __riscv_flush_icache,
+      (add DefaultRuntimeLibcallImpls,
+           exp10f, exp10, exp10l_f128,
+           __riscv_flush_icache,
            LibcallImpls<(add Int128RTLibcalls), isRISCV64>)>;
 
 //===----------------------------------------------------------------------===//
@@ -2086,6 +2100,10 @@ defvar X86CommonLibcalls =
        LibmHasFrexpF32, LibmHasLdexpF32,
        LibmHasFrexpF80, LibmHasLdexpF80,
        DefaultRuntimeLibcallImpls_f80,
+
+       LibmHasExp10F32, LibmHasExp10F64, LibmHasExp10F80,
+       LibmHasExp10F128,
+
        // MSVCRT doesn't have powi
        // FIXME: It's almost certainly correct that MSVCRT has
        // __powitf2_f128, but at least one test is relying on it.
@@ -2230,4 +2248,5 @@ def WasmSystemLibrary
     : SystemRuntimeLibrary<isWasm,
       (add DefaultRuntimeLibcallImpls, Int128RTLibcalls,
            CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls,
+           exp10f, exp10,
            emscripten_return_address)>;
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 60da0047291a9..038a511ed2e68 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -99,21 +99,15 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
       setLibcallImplCallingConv(RTLIB::__sincos_stret,
                                 CallingConv::ARM_AAPCS_VFP);
     }
-
-    if (!darwinHasExp10(TT)) {
-      // FIXME: Remove exp10 from default set
-      setLibcallImpl(RTLIB::EXP10_F32, RTLIB::Unsupported);
-      setLibcallImpl(RTLIB::EXP10_F64, RTLIB::Unsupported);
-    }
   }
 
   if (TT.isOSOpenBSD()) {
     setLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL, RTLIB::Unsupported);
   }
 
-  // Skip default manual processing for targets that have been fully ported to
+  // Skip default manual processing for targets that have been mostly ported to
   // tablegen for now. Eventually the rest of this should be deleted.
-  if (TT.isX86() || TT.isAArch64() || TT.isWasm())
+  if (TT.isX86() || TT.isAArch64() || TT.isWasm() || TT.isPPC())
     return;
 
   if (TT.isARM() || TT.isThumb()) {
@@ -127,6 +121,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
     setLibcallImpl(RTLIB::SINCOS_F128, RTLIB::sincos_f128);
   }
 
+  setLibcallImpl(RTLIB::EXP10_F32, RTLIB::exp10f);
+  setLibcallImpl(RTLIB::EXP10_F64, RTLIB::exp10);
+  setLibcallImpl(RTLIB::EXP10_F128, RTLIB::exp10l_f128);
+
   // These libcalls are only available in compiler-rt, not libgcc.
   if (TT.isArch64Bit()) {
     setLibcallImpl(RTLIB::SHL_I128, RTLIB::__ashlti3);
diff --git a/llvm/test/CodeGen/X86/exp10-libcall-names.ll b/llvm/test/CodeGen/X86/exp10-libcall-names.ll
index 96e3aae408e94..2688474b2ce5c 100644
--- a/llvm/test/CodeGen/X86/exp10-libcall-names.ll
+++ b/llvm/test/CodeGen/X86/exp10-libcall-names.ll
@@ -13,10 +13,7 @@
 ; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X86
 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X64
 
-; RUN: not llc -mtriple=x86_64-apple-macos10.8 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
-; Check exp10/exp10f is emitted as __exp10/__exp10f on assorted systems.
-
-; ERR: no libcall available for fexp10
+; Check exp10/exp10f is emitted as __exp10/__exp10f on assorted darwin systems.
 
 define float @test_exp10_f32(float %x) nounwind {
 ; LINUX-LABEL: test_exp10_f32:
@@ -78,43 +75,3 @@ define double @test_exp10_f64(double %x) nounwind {
   %ret = call double @llvm.exp10.f64(double %x)
   ret double %ret
 }
-
-define x86_fp80 @test_exp10_f80(x86_fp80 %x) nounwind {
-; LINUX-LABEL: test_exp10_f80:
-; LINUX:       # %bb.0:
-; LINUX-NEXT:    subq $24, %rsp
-; LINUX-NEXT:    fldt {{[0-9]+}}(%rsp)
-; LINUX-NEXT:    fstpt (%rsp)
-; LINUX-NEXT:    callq exp10l@PLT
-; LINUX-NEXT:    addq $24, %rsp
-; LINUX-NEXT:    retq
-;
-; APPLE-LABEL: test_exp10_f80:
-; APPLE:       ## %bb.0:
-; APPLE-NEXT:    subq $24, %rsp
-; APPLE-NEXT:    fldt {{[0-9]+}}(%rsp)
-; APPLE-NEXT:    fstpt (%rsp)
-; APPLE-NEXT:    callq _exp10l
-; APPLE-NEXT:    addq $24, %rsp
-; APPLE-NEXT:    retq
-;
-; GISEL-X86-LABEL: test_exp10_f80:
-; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $12, %esp
-; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstpt (%esp)
-; GISEL-X86-NEXT:    calll exp10l
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: test_exp10_f80:
-; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    subq $24, %rsp
-; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstpt (%rsp)
-; GISEL-X64-NEXT:    callq exp10l
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %ret = call x86_fp80 @llvm.exp10.f80(x86_fp80 %x)
-  ret x86_fp80 %ret
-}
diff --git a/llvm/test/CodeGen/X86/exp10l-libcall-names.ll b/llvm/test/CodeGen/X86/exp10l-libcall-names.ll
new file mode 100644
index 0000000000000..2e7f9e34f662a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/exp10l-libcall-names.ll
@@ -0,0 +1,46 @@
+; RUN: llc -mtriple=x86_64-linux-gnu < %s | FileCheck -check-prefix=LINUX %s
+; RUN: not llc -mtriple=x86_64-apple-macos10.9 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-ios9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-tvos9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-watchos9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-xros9.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-ios8.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-tvos8.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-xros8.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-driverkit < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -mtriple=x86_64-apple-driverkit24.0 < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X86
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL-X64
+
+; ERR: no libcall available for fexp10
+
+define x86_fp80 @test_exp10_f80(x86_fp80 %x) nounwind {
+; LINUX-LABEL: test_exp10_f80:
+; LINUX:       # %bb.0:
+; LINUX-NEXT:    subq $24, %rsp
+; LINUX-NEXT:    fldt {{[0-9]+}}(%rsp)
+; LINUX-NEXT:    fstpt (%rsp)
+; LINUX-NEXT:    callq exp10l@PLT
+; LINUX-NEXT:    addq $24, %rsp
+; LINUX-NEXT:    retq
+;
+; GISEL-X86-LABEL: test_exp10_f80:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $12, %esp
+; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstpt (%esp)
+; GISEL-X86-NEXT:    calll exp10l
+; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    retl
+;
+; GISEL-X64-LABEL: test_exp10_f80:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    subq $24, %rsp
+; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpt (%rsp)
+; GISEL-X64-NEXT:    callq exp10l
+; GISEL-X64-NEXT:    addq $24, %rsp
+; GISEL-X64-NEXT:    retq
+  %ret = call x86_fp80 @llvm.exp10.f80(x86_fp80 %x)
+  ret x86_fp80 %ret
+}

@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/stop-opt-out-exp10 branch from d2d9452 to b2fc78b Compare July 15, 2025 05:05
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/x86-mostly-move-libcalls-tablegen branch from 1a5ee21 to 5915e12 Compare July 15, 2025 05:05
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/stop-opt-out-exp10 branch from a64799d to c35ac3c Compare July 15, 2025 06:19
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/x86-mostly-move-libcalls-tablegen branch from 5915e12 to 27fd017 Compare July 15, 2025 06:19
Base automatically changed from users/arsenm/runtime-libcalls/x86-mostly-move-libcalls-tablegen to main July 15, 2025 07:18
@arsenm arsenm force-pushed the users/arsenm/runtime-libcalls/stop-opt-out-exp10 branch from c35ac3c to 465db65 Compare July 15, 2025 07:20
@tgross35
Copy link
Contributor

For my understanding: this is expected to ICE because there is no possible libcall here (since exp10l is f64 on Apple) and not because ICEs are expected when the default target lib isn't known to provide a symbol, right? Otherwise I would be a bit concerned about our ability to make fp128 work cross-platform by vendoring needed symbols (unrelated to this change of course).

@arsenm
Copy link
Contributor Author

arsenm commented Jul 15, 2025

For my understanding: this is expected to ICE because there is no possible libcall here (since exp10l is f64 on Apple) and not because ICEs are expected when the default target lib isn't known to provide a symbol, right?

These are equivalent. There needs to be a known symbol that provides the behavior needed to implement exp10.fp128. The "default target lib" concept doesn't really exist, it's a historical implementation artifact. The compiler needs accurate knowledge about a concrete target

Otherwise I would be a bit concerned about our ability to make fp128 work cross-platform by vendoring needed symbols (unrelated to this change of course).

In theory the backend needs to do something to provide the intrinsic behavior. This is currently built on top of emitting libm calls to shoddy host math libraries. In a better world we would have complete coverage of all functions x types in compiler-rt and ignore the host libraries, or rip out most math intrinsics and disallow types we don't have a direct compiler implementation of

@nikic
Copy link
Contributor

nikic commented Jul 15, 2025

Except for target specific types (x86_fp80 and ppc_fp128) I think it is preferable if missing FP libcalls that cannot be legalized result in a linker error instead of a compiler error, which allows the user to provide them. At least when considering the world we live in now, rather than possible future designs.

@tgross35
Copy link
Contributor

tgross35 commented Jul 15, 2025

Actually, is there anything unique about exp10 here? All x86_fp80 intrinsics on Apple (as well as Windows) that get lowered to libm calls have the same problem.

Except for target specific types (x86_fp80 and ppc_fp128) I think it is preferable if missing FP libcalls that cannot be legalized result in a linker error instead of a compiler error, which allows the user to provide them. At least when considering the world we live in now, rather than possible future designs.

In theory this could lower to the C23 exp10f64x symbol rather than having an error (supported by glibc but not much else, yet). The long-term correctness of this depends on an assumption that Windows and Apple will either never specify _Float64x, or if they do specify it, make it x86_fp80 (cc #97335).

Edit: sorry, I see you aren't talking about x86_fp80 here.

@tgross35
Copy link
Contributor

In theory the backend needs to do something to provide the intrinsic behavior. This is currently built on top of emitting libm calls to shoddy host math libraries. In a better world we would have complete coverage of all functions x types in compiler-rt and ignore the host libraries, or rip out most math intrinsics and disallow types we don't have a direct compiler implementation of

It would be nice if there was a triple flag to indicate presence of a backend-agnostic C23-compliant library, so e.g. sqrtf16, sqrtf32, sqrtf64, sqrtf64x (for x87 f80), and sqrtf128 can be lowered to and long double never needs to be considered. Glibc has already had these for a while. ppc_fp128 would still be a bit weird since I don't believe it can classify as _Float64x.

I know we talked about something like this on Discord a while back.

@nikic
Copy link
Contributor

nikic commented Jul 15, 2025

Actually, is there anything unique about exp10 here? All x86_fp80 intrinsics on Apple (as well as Windows) that get lowered to libm calls have the same problem.

Yeah, that's my understanding as well.

Except for target specific types (x86_fp80 and ppc_fp128) I think it is preferable if missing FP libcalls that cannot be legalized result in a linker error instead of a compiler error, which allows the user to provide them. At least when considering the world we live in now, rather than possible future designs.

In theory this could lower to the C23 exp10f64x symbol rather than having an error (supported by glibc but not much else, yet). The long-term correctness of this depends on an assumption that Windows and Apple will either never specify _Float64x, or if they do specify it, make it x86_fp80 (cc #97335).

Edit: sorry, I see you aren't talking about x86_fp80 here.

Yes, what specifically concerns me is that change to fp128 behavior in this PR. I don't think that should ever result in a hard compiler error.

I wasn't aware that the f64x suffix is a thing. That does seem like a reasonable fallback for targets where long double is not x86_fp80. But I'm also not sure this is really worth bothering with. Is there any real interest in having fp80 work across all x86 targets?

@arsenm
Copy link
Contributor Author

arsenm commented Jul 15, 2025

I think it is preferable if missing FP libcalls that cannot be legalized result in a linker error instead of a compiler error, which allows the user to provide them

Yes, what specifically concerns me is that change to fp128 behavior in this PR. I don't think that should ever result in a hard compiler error.

I don't think it's reasonable to support this kind of use case for a known triple. Maybe for something defined as freestanding, but not a definitive target. In theory the compiler should be using this knowledge of this-call-exists-or-not to use a fallback path to avoid using that call. If we have to pretend phantom calls exist in the off chance someone is hacking around library defects, I don't see how you can ever move beyond broken host libraries

@arsenm
Copy link
Contributor Author

arsenm commented Jul 15, 2025

Plus this is one of the odd cases that happened to emit some kind of code. Most of these untested, accidental libcall cases hit asserts and crashes in codegen so it's not like a designed system

@tgross35
Copy link
Contributor

For rust I suppose we could switch to calling the *f128 functions directly on all platforms rather than going via intrinsics. That would allow us to avoid #44744 anyway. I expect other languages may get a bit of a surprise though (cc @alexrp for Zig).

Regardless whether the fp128 changes are kept or if this gets reduced to only x86_f80, is there any reason not to treat all libcalls the same rather than only exp10?

Is there any real interest in having fp80 work across all x86 targets?

I'd like to add the type to core::arch eventually (have a branch floating around somewhere). But this would most likely only be arithmetic, probably not all math symbols. If that changes we could always call sqrtf64x without going through intrinsics, though something like #148604 (comment) would make that nicer.

@alexrp
Copy link
Member

alexrp commented Jul 15, 2025

Except for target specific types (x86_fp80 and ppc_fp128) I think it is preferable if missing FP libcalls that cannot be legalized result in a linker error instead of a compiler error, which allows the user to provide them. At least when considering the world we live in now, rather than possible future designs.

I agree with this. A linker error we can straightforwardly address by implementing the missing function in Zig's compiler-rt. An ICE from LLVM is significantly more annoying to work around.

Is there any real interest in having fp80 work across all x86 targets?

In Zig, we currently lower f80 to i80 and manual soft float calls if the target is not x86 with long double = x86_fp80. It would be nice if we didn't have to do that, I suppose, but it's not terribly important.

I expect other languages may get a bit of a surprise though (cc @alexrp for Zig).

I don't believe Zig emits exp10 intrinsic calls at the moment, FWIW.

@nikic
Copy link
Contributor

nikic commented Jul 15, 2025

I think it is preferable if missing FP libcalls that cannot be legalized result in a linker error instead of a compiler error, which allows the user to provide them

Yes, what specifically concerns me is that change to fp128 behavior in this PR. I don't think that should ever result in a hard compiler error.

I don't think it's reasonable to support this kind of use case for a known triple. Maybe for something defined as freestanding, but not a definitive target. In theory the compiler should be using this knowledge of this-call-exists-or-not to use a fallback path to avoid using that call. If we have to pretend phantom calls exist in the off chance someone is hacking around library defects, I don't see how you can ever move beyond broken host libraries

I think that would be a reasonable position to take if the fallback path to avoid the call actually existed. But it does not, so we should not unnecessarily force an error.

The longer term solution here would be along the lines of what @tgross35 suggested, that is the ability to override LLVM's default assumptions about libcalls for the targets, to be able to say things like "I'm actually linking against compiler-rt rather than libgcc" or "I will link against a full featured (glibc-style) libm".

But I think that until that is supported, we should not change the status quo of how the FP libcall fallbacks work.

For rust I suppose we could switch to calling the *f128 functions directly on all platforms rather than going via intrinsics. That would allow us to avoid #44744 anyway. I expect other languages may get a bit of a surprise though (cc @alexrp for Zig).

I don't think that's a great option, as LLVM will no longer understand these libcalls and won't be able to e.g. constant fold them.

I don't believe Zig emits exp10 intrinsic calls at the moment, FWIW.

I think neither does Rust, so the behavior for this particular builtin changing wouldn't be a big deal. But if this were to extend to other FP libcalls, there'd be a problem.

@dpaoliello
Copy link
Contributor

Can darwinHasExp10 be removed (or unified) with this change?

@arsenm
Copy link
Contributor Author

arsenm commented Jul 26, 2025

The longer term solution here would be along the lines of what @tgross35 suggested, that is the ability to override LLVM's default assumptions about libcalls for the targets, to be able to say things like "I'm actually linking against compiler-rt rather than libgcc" or "I will link against a full featured (glibc-style) libm".

I'm more or less working towards this

But I think that until that is supported, we should not change the status quo of how the FP libcall fallbacks work.

We don't actually have a notion of FP libcall fallbacks. We have a configured set of calls to provide a feature, with a set of defaults. It's a poorly maintained opt-out system that has always errored on missing calls. Other intrinsics that require a libcall to implement will also hard error. e.g. you will get the same error in the exp10 f32 and f64 cases on Darwin. This change just makes the long double cases consistent. I could lie and add only exp10l but that does not seem like the intended behavior

I don't think that's a great option, as LLVM will no longer understand these libcalls and won't be able to e.g. constant fold them.

It also doesn't address the problem. The compiler needs to know the set of target library calls, and can synthesize calls that were not in the original program.

I think neither does Rust, so the behavior for this particular builtin changing wouldn't be a big deal. But if this were to extend to other FP libcalls, there'd be a problem.

exp10 is unique in that it had explicit opt-outs from the default. I don't think there is another example like this among the math functions. The closest would be a few missing f32 calls on windows, but those have legalization paths to promote or expand. If there are other platform unsupported math calls, the work to properly report that was not done.

It's also unique in that TargetLibraryInfo deliberately does not report it as available by default, so there's a mismatch with RuntimeLibcalls

@arsenm
Copy link
Contributor Author

arsenm commented Jul 28, 2025

Here is the status quo: https://godbolt.org/z/PPzn9zMs8

The f32 and f64 cases hard error. The f128 case incorrectly codegens to exp10l, and the x86_fp80 case codegens to a function which does not exist. This makes all 4 cases consistently error

arsenm and others added 2 commits July 28, 2025 11:07
This changes the behavior on old darwin triples for x86_fp80;
it now turns into an error instead of emitting exp10l. The comments
in TargetLibraryInfo suggest it never existed.
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not really convinced that your general approach here is an improvement over the status quo. exp10 is going to be available on any platform using glibc/musl, regardless of architecture. Excluding it from the default set for the sake of darwin platforms, and then having to add it back for every single architecture does not seem like a good tradeoff to me. Wouldn't it be better to remove it instead for the two arches where darwin is actually relevant?

Alternatively, it seems to me like you need a mechanism that allows you to exclude exp10 on darwin in a way that does not require listing this for each arch.

; CHECK-ALL-LABEL: test_exp10:
; CHECK-F128: exp10f128
; CHECK-USELD: exp10l
; CHECK-S390X: exp10l
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for separate S390X prefix.

@arsenm
Copy link
Contributor Author

arsenm commented Jul 28, 2025

I'm still not really convinced that your general approach here is an improvement over the status quo. exp10 is going to be available on any platform using glibc/musl, regardless of architecture. Excluding it from the default set for the sake of darwin platforms, and then having to add it back for every single architecture does not seem like a good tradeoff to me. Wouldn't it be better to remove it instead for the two arches where darwin is actually relevant?

Alternatively, it seems to me like you need a mechanism that allows you to exclude exp10 on darwin in a way that does not require listing this for each arch.

I very deliberately do not want any opt-out mechanism. All target based decisions should be explicitly opt-in, and all the places that are opt-out were a mistake. It results in falsely reporting things that don't exist as available, like this. And hard to untangle messes. This is a staging step to getting all logic into tablegen to work towards that

@nikic
Copy link
Contributor

nikic commented Jul 28, 2025

I very deliberately do not want any opt-out mechanism. All target based decisions should be explicitly opt-in, and all the places that are opt-out were a mistake. It results in falsely reporting things that don't exist as available, like this. And hard to untangle messes. This is a staging step to getting all logic into tablegen to work towards that

I don't mind it being opt-in, my concern here is that you require a per-arch opt-in, even though the decision should be largely arch-independent (it should depend on os/env).

Like for example, you added the exp10 functions to most of the target system libraries here, but not to all of them. What about hexagon, msp430 and xcore? Were those intentionally omitted?

Even if it's not part of the default set, I think this can be structured in a better way that does not require repeating certain parts of the system library in each arch. We should extract the commonalities to the degree it is possible.

@nikic
Copy link
Contributor

nikic commented Jul 28, 2025

Looking at the follow-up patch #148780 answers my questions about hexagon/msp/xcore...

I guess what I'm looking for is to basically have most targets share this libcall list...

def LegacyDefaultSystemLibrary
    : SystemRuntimeLibrary<isDefaultLibcallArch,
      (add DefaultRuntimeLibcallImpls,
         LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
         exp10f, exp10, exp10l_f128,
         __powisf2, __powidf2, __powitf2_f128,
         LibcallImpls<(add Int128RTLibcalls), isArch64Bit>
)>;

...without having to repeat it in each target.

@nikic
Copy link
Contributor

nikic commented Jul 28, 2025

This also seems to be a recurring problem in patches later in the stack, like #148789 and #150870 needs to add libcalls to lots of arch specific lists, instead of keeping things mostly centralized.

@arsenm
Copy link
Contributor Author

arsenm commented Jul 28, 2025

This also seems to be a recurring problem in patches later in the stack, like #148789 and #150870 needs to add libcalls to lots of arch specific lists, instead of keeping things mostly centralized.

That's the end of it though, this series is enough to get all of the generic code into tablegen which makes doing anything else easier. Nowhere else in llvm treats the OS/environment as the top target concept, but this could be transposed if it makes it smaller, I guess.

Eventually I want to delete DefaultRuntimeLibcallImpls and replace it with named subsets of libc and compiler-rt, but I have to reverse engineer what is actually intended to be added and what combinations are meaningful. It's a pain figuring it out from what we have now, where there's no documentation and barely any tests. The current logic is special casing these specific cases, so that's what it gets ported to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants