[llvm] RuntimeLibcalls: Fix wrongly typed x87/fp128 long double libcalls on x86 (PR #216979)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 08:47:32 PDT 2026


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/216979

>From f0c96e77115e583bf9137495261fa0e94be50113 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 14 Aug 2026 17:51:57 +0200
Subject: [PATCH 1/3] RuntimeLibcalls: Fix wrongly typed x87/fp128 long double
 libcalls on x86

The x86 and default libcall sets gated the l-suffixed long double libm
functions on OS conditions rather than the long double format. This
incorrectly provided the f80 libcalls on targets whose long double is not x87
(Windows-MSVC, UEFI, x86_64 Android), double-provided frexpl/ldexpl on musl,
and provided the fp128 sincosl on targets using double as long double (m68k).

Gate the l-suffixed libm math on the long double format, mirroring the earlier
AArch64 fix: x87 targets get the _f80 calls, fp128 targets the _f128 calls, and
double targets neither. The compiler-rt f80 helpers (__extendxftf2, __fixxfti,
__powixf2, ...) are keyed to the x86_fp80 IR type, not the long double format,
so they stay unconditional on x86.

Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
 llvm/include/llvm/IR/RuntimeLibcalls.td       |  61 ++-
 .../CodeGen/Generic/fp128-exp10-libcall.ll    |   7 +-
 llvm/test/CodeGen/X86/finite-libcalls.ll      | 359 -----------------
 .../CodeGen/X86/fp128-libcalls-longdouble.ll  |   9 +
 llvm/test/CodeGen/X86/fp80-conv-libcalls.ll   | 146 +++++++
 llvm/test/CodeGen/X86/fp80-math-libcalls.ll   | 374 ++++++++++++++++++
 .../CodeGen/X86/fp80-math-no-libcall-error.ll |  92 +++++
 llvm/test/CodeGen/X86/ldexp-avx512.ll         |  17 +-
 8 files changed, 681 insertions(+), 384 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/fp80-conv-libcalls.ll
 create mode 100644 llvm/test/CodeGen/X86/fp80-math-libcalls.ll
 create mode 100644 llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll

diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 1176b9b5d1a5a..8cbb3231571ac 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -60,6 +60,7 @@ def IsEABI4 : LibcallPredicate<[{EABIVersion == EABI::EABI4}]>;
 def IsEABI5 : LibcallPredicate<[{EABIVersion == EABI::EABI5}]>;
 
 def IsLongDoubleF128 : LibcallPredicate<[{LongDoubleFormat == LongDoubleFormat::IEEEquad}]>;
+def IsLongDoubleX87 : LibcallPredicate<[{LongDoubleFormat == LongDoubleFormat::X87DoubleExtended}]>;
 
 def IsAMDGPU : LibcallPredicate<[{TT.isAMDGPU()}]>;
 def IsARM : LibcallPredicate<[{TT.isARM()}]>;
@@ -114,6 +115,21 @@ def isNotOSOpenBSD : RuntimeLibcallAvailability<(not IsOSOpenBSD)>;
 // True when the C `long double` type is IEEE fp128.
 def isLongDoubleF128 : RuntimeLibcallAvailability<(all_of IsLongDoubleF128)>;
 
+// True when the C `long double` type is the x87 80-bit extended format.
+def isLongDoubleX87 : RuntimeLibcallAvailability<(all_of IsLongDoubleX87)>;
+
+// x87 long double variants of sincosl/exp10l, which additionally depend on
+// the libc providing the sincos/exp10 extensions.
+def isLongDoubleX87AndHasSinCos : RuntimeLibcallAvailability<
+  (all_of IsLongDoubleX87, (any_of IsGNUEnv, IsOSFuchsia, IsAndroid))>;
+def isLongDoubleX87AndHasExp10 : RuntimeLibcallAvailability<
+  (all_of IsLongDoubleX87, (not IsOSDarwin))>;
+
+// fp128 long double sincosl, which additionally depends on the libc
+// providing the sincos extension.
+def isLongDoubleF128AndHasSinCos : RuntimeLibcallAvailability<
+  (all_of IsLongDoubleF128, (any_of IsGNUEnv, IsOSFuchsia, IsAndroid))>;
+
 def isOSWindows : RuntimeLibcallAvailability<(all_of IsOSWindows)>;
 def isNotOSWindows : RuntimeLibcallAvailability<(not IsOSWindows)>;
 def isNotOSLinux : RuntimeLibcallAvailability<(not IsOSLinux)>;
@@ -1986,6 +2002,17 @@ defvar DefaultRuntimeLibcallImpls_f80 =
     !filter(entry, AllDefaultRuntimeLibcallImpls,
             !match(!cast<string>(entry.Provides), "F80"));
 
+// The l-suffixed libm math functions, only correct when long double is x87.
+defvar DefaultRuntimeLibcallImpls_longdouble_f80 =
+    !filter(entry, AllDefaultRuntimeLibcallImpls,
+            !match(!cast<string>(entry), "l_f80"));
+
+// The compiler-rt helpers, keyed to the x86_fp80 IR type and available on all
+// x86 regardless of the long double format.
+defvar DefaultRuntimeLibcallImpls_f80_helpers =
+    !listremove(DefaultRuntimeLibcallImpls_f80,
+                DefaultRuntimeLibcallImpls_longdouble_f80);
+
 defvar DefaultRuntimeLibcallImpls_ppcf128 =
     !filter(entry, AllDefaultRuntimeLibcallImpls,
             !match(!cast<string>(entry.Provides), "PPCF128"));
@@ -2046,13 +2073,11 @@ defvar SecurityCheckCookieIfWinMSVC =
 
 defvar LibmHasSinCosF32 = LibcallImpls<(add sincosf), hasSinCos>;
 defvar LibmHasSinCosF64 =  LibcallImpls<(add sincos), hasSinCos>;
-defvar LibmHasSinCosF80 = LibcallImpls<(add sincosl_f80), hasSinCos>;
 defvar LibmHasSinCosF128 = LibcallImpls<(add sincosl_f128), hasSinCos>;
 defvar LibmHasSinCosPPCF128 = LibcallImpls<(add sincosl_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>;
 
@@ -2081,9 +2106,6 @@ defvar WinDefaultLibcallImpls = (add WinDefaultLibcallImplsBaseList,
 defvar LibmHasFrexpF32 = LibcallImpls<(add frexpf), isNotOSWindowsOrIsCygwinMinGW>;
 defvar LibmHasLdexpF32 = LibcallImpls<(add ldexpf), isNotOSWindowsOrIsCygwinMinGW>;
 
-defvar LibmHasFrexpF80 = LibcallImpls<(add frexpl_f80), isNotOSWindowsOrIsCygwinMinGW>;
-defvar LibmHasLdexpF80 = LibcallImpls<(add ldexpl_f80), isNotOSWindowsOrIsCygwinMinGW>;
-
 defvar LibmHasFrexpF128 = LibcallImpls<(add frexpl_f128), isNotOSWindowsOrIsCygwinMinGW>;
 defvar LibmHasLdexpF128 = LibcallImpls<(add ldexpl_f128), isNotOSWindowsOrIsCygwinMinGW>;
 
@@ -3410,9 +3432,11 @@ def isWin64NotCygMing : RuntimeLibcallAvailability<
 def darwinHas__bzero : RuntimeLibcallAvailability<
   (all_of IsMacOSX, MacOSXVersionAtLeast<10, 6>)>;
 
-// FIXME: This is has ldexpl/frexpl plus use f128 for long double.
-def hasExpFrexplLdexplF128 : RuntimeLibcallAvailability<
-  (all_of (any_of (not IsOSWindows), IsOSCygMing), (not IsGNUEnv))>;
+// frexpl_f80/ldexpl_f80/exp10l_f80 are added separately with their own
+// libc-availability guards, so drop them from the bulk x87 body.
+defvar X86LongDoubleF80Body =
+    !listremove(DefaultRuntimeLibcallImpls_longdouble_f80,
+                [frexpl_f80, ldexpl_f80, exp10l_f80]);
 
 // Use the f128 variants of math functions on x86
 defvar X86_F128_Libcalls = LibcallImpls<(add LibmF128Libcalls, LibmF128FiniteLibcalls), isGNUEnvironment>;
@@ -3430,18 +3454,19 @@ defvar X86CommonLibcalls =
   (add (sub WinDefaultLibcallImpls, WindowsDivRemMulLibcallOverrides, MemChkLibcalls),
        DarwinSinCosStret, DarwinExp10, DarwinMemsetPattern, MacOSUnlockedIO,
        X86_F128_Libcalls,
-       LibmHasSinCosF80, // FIXME: Depends on long double
+       LibcallImpls<(add sincosl_f80), isLongDoubleX87AndHasSinCos>,
        SinCosF32F64Libcalls,
        LibcallImpls<(add __bzero), darwinHas__bzero>,
        LibmHasFrexpF32, LibmHasLdexpF32,
-       LibmHasFrexpF80, LibmHasLdexpF80,
-       LibcallImpls<(add frexpl_f128, ldexpl_f128, exp10l_f128), hasExpFrexplLdexplF128>,
-       // The l-suffixed long double math is fp128 only when long double is fp128
-       // (e.g. x86_64 Android/OHOS). frexpl/ldexpl/exp10l are added above.
+       LibcallImpls<(add frexpl_f80, ldexpl_f80), isLongDoubleX87>,
+       LibcallImpls<(add X86LongDoubleF80Body), isLongDoubleX87>,
+       // The x86_fp80 compiler-rt helpers are format-independent.
+       DefaultRuntimeLibcallImpls_f80_helpers,
+       LibcallImpls<(add frexpl_f128, ldexpl_f128, exp10l_f128), isLongDoubleF128>,
        LibcallImpls<(add X86LongDoubleF128Body), isLongDoubleF128>,
-       DefaultRuntimeLibcallImpls_f80,
-       LibmHasExp10F32, LibmHasExp10F64, LibmHasExp10F80,
-       LibcallImpls<(add MostPowI), isNotOSMSVCRT>,
+       LibmHasExp10F32, LibmHasExp10F64,
+       LibcallImpls<(add exp10l_f80), isLongDoubleX87AndHasExp10>,
+       LibcallImpls<(add __powisf2, __powidf2), isNotOSMSVCRT>,
        SecurityCheckCookieIfWinMSVC,
        // FIXME: MSVCRT doesn't have powi. The f128 case is added as a
        // hack for one test relying on it.
@@ -3630,7 +3655,9 @@ def isArch64Bit : RuntimeLibcallAvailability<(all_of IsArch64Bit)>;
 def LegacyDefaultSystemLibrary
     : SystemRuntimeLibrary<isDefaultLibcallArch,
       (add DefaultRuntimeLibcallImpls,
-         LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
+         LibmHasSinCosF32, LibmHasSinCosF64,
+         // sincosl is fp128 only when long double is fp128.
+         LibcallImpls<(add sincosl_f128), isLongDoubleF128AndHasSinCos>,
          exp10f, exp10, exp10l_f128,
          __powisf2, __powidf2, __powitf2_f128,
          LibcallImpls<(add Int128RTLibcalls), isArch64Bit>,
diff --git a/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll b/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll
index 54ac792da1374..934dc230370b8 100644
--- a/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll
+++ b/llvm/test/CodeGen/Generic/fp128-exp10-libcall.ll
@@ -10,14 +10,17 @@
 ; RUN: %if riscv-registered-target   %{ llc < %s -mtriple=riscv32-unknown-linux-gnu    | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
 ; RUN: %if systemz-registered-target %{ llc < %s -mtriple=s390x-unknown-linux-gnu      | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-S390X %}
 ; RUN: %if x86-registered-target     %{ llc < %s -mtriple=i686-unknown-linux-gnu       | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128  %}
-; RUN: %if x86-registered-target     %{ llc < %s -mtriple=i686-unknown-linux-musl      | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
+; RUN: %if x86-registered-target     %{ not llc -mtriple=i686-unknown-linux-musl   -filetype=null %s 2>&1 | FileCheck --check-prefix=ERR %s %}
 ; RUN: %if x86-registered-target     %{ llc < %s -mtriple=x86_64-unknown-linux-gnu     | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128  %}
-; RUN: %if x86-registered-target     %{ llc < %s -mtriple=x86_64-unknown-linux-musl    | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-USELD %}
+; RUN: %if x86-registered-target     %{ not llc -mtriple=x86_64-unknown-linux-musl -filetype=null %s 2>&1 | FileCheck --check-prefix=ERR %s %}
 
 ; FIXME(#144006): Windows-MSVC should also be run but has a ldexp selection failure.
 ; %if x86-registered-target     %{ llc < %s -mtriple=x86_64-pc-windows-msvc       | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128  %}
 ; %if aarch64-registered-target %{ llc < %s -mtriple=arm64ec-pc-windows-msvc      | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-F128  %}
 
+; x86 musl has x87 long double, so it provides neither exp10l_f128 (fp128 long
+; double) nor exp10f128 (a glibc _Float128 function), and must diagnose instead.
+
 ; ERR: error: no libcall available for fexp10
 define fp128 @test_exp10(fp128 %a) {
 ; CHECK-ALL-LABEL:  test_exp10:
diff --git a/llvm/test/CodeGen/X86/finite-libcalls.ll b/llvm/test/CodeGen/X86/finite-libcalls.ll
index acc7ddeb9a886..a28d87cf5ba96 100644
--- a/llvm/test/CodeGen/X86/finite-libcalls.ll
+++ b/llvm/test/CodeGen/X86/finite-libcalls.ll
@@ -75,63 +75,6 @@ define double @exp_f64(double %x) #0 {
   ret double %r
 }
 
-define x86_fp80 @exp_f80(x86_fp80 %x) #0 {
-; GNU-LABEL: exp_f80:
-; GNU:       # %bb.0:
-; GNU-NEXT:    subq $24, %rsp
-; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fstpt (%rsp)
-; GNU-NEXT:    callq expl at PLT
-; GNU-NEXT:    addq $24, %rsp
-; GNU-NEXT:    retq
-;
-; WIN-LABEL: exp_f80:
-; WIN:       # %bb.0:
-; WIN-NEXT:    pushq %rsi
-; WIN-NEXT:    subq $64, %rsp
-; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    fldt (%rdx)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN-NEXT:    callq expl
-; WIN-NEXT:    fldt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt (%rsi)
-; WIN-NEXT:    movq %rsi, %rax
-; WIN-NEXT:    addq $64, %rsp
-; WIN-NEXT:    popq %rsi
-; WIN-NEXT:    retq
-;
-; MAC-LABEL: exp_f80:
-; MAC:       ## %bb.0:
-; MAC-NEXT:    subq $24, %rsp
-; MAC-NEXT:    fldt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fstpt (%rsp)
-; MAC-NEXT:    callq _expl
-; MAC-NEXT:    addq $24, %rsp
-; MAC-NEXT:    retq
-;
-; GISEL-X86-LABEL: exp_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 expl
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: exp_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 expl
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %r = tail call nnan ninf x86_fp80 @llvm.exp.f80(x86_fp80 %x)
-  ret x86_fp80 %r
-}
-
 define float @exp2_f32(float %x) #0 {
 ; GNU-LABEL: exp2_f32:
 ; GNU:       # %bb.0:
@@ -199,63 +142,6 @@ define double @exp2_f64(double %x) #0 {
   ret double %r
 }
 
-define x86_fp80 @exp2_f80(x86_fp80 %x) #0 {
-; GNU-LABEL: exp2_f80:
-; GNU:       # %bb.0:
-; GNU-NEXT:    subq $24, %rsp
-; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fstpt (%rsp)
-; GNU-NEXT:    callq exp2l at PLT
-; GNU-NEXT:    addq $24, %rsp
-; GNU-NEXT:    retq
-;
-; WIN-LABEL: exp2_f80:
-; WIN:       # %bb.0:
-; WIN-NEXT:    pushq %rsi
-; WIN-NEXT:    subq $64, %rsp
-; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    fldt (%rdx)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN-NEXT:    callq exp2l
-; WIN-NEXT:    fldt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt (%rsi)
-; WIN-NEXT:    movq %rsi, %rax
-; WIN-NEXT:    addq $64, %rsp
-; WIN-NEXT:    popq %rsi
-; WIN-NEXT:    retq
-;
-; MAC-LABEL: exp2_f80:
-; MAC:       ## %bb.0:
-; MAC-NEXT:    subq $24, %rsp
-; MAC-NEXT:    fldt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fstpt (%rsp)
-; MAC-NEXT:    callq _exp2l
-; MAC-NEXT:    addq $24, %rsp
-; MAC-NEXT:    retq
-;
-; GISEL-X86-LABEL: exp2_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 exp2l
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: exp2_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 exp2l
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %r = tail call nnan ninf x86_fp80 @llvm.exp2.f80(x86_fp80 %x)
-  ret x86_fp80 %r
-}
-
 define float @log_f32(float %x) #0 {
 ; GNU-LABEL: log_f32:
 ; GNU:       # %bb.0:
@@ -323,63 +209,6 @@ define double @log_f64(double %x) #0 {
   ret double %r
 }
 
-define x86_fp80 @log_f80(x86_fp80 %x) #0 {
-; GNU-LABEL: log_f80:
-; GNU:       # %bb.0:
-; GNU-NEXT:    subq $24, %rsp
-; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fstpt (%rsp)
-; GNU-NEXT:    callq logl at PLT
-; GNU-NEXT:    addq $24, %rsp
-; GNU-NEXT:    retq
-;
-; WIN-LABEL: log_f80:
-; WIN:       # %bb.0:
-; WIN-NEXT:    pushq %rsi
-; WIN-NEXT:    subq $64, %rsp
-; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    fldt (%rdx)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN-NEXT:    callq logl
-; WIN-NEXT:    fldt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt (%rsi)
-; WIN-NEXT:    movq %rsi, %rax
-; WIN-NEXT:    addq $64, %rsp
-; WIN-NEXT:    popq %rsi
-; WIN-NEXT:    retq
-;
-; MAC-LABEL: log_f80:
-; MAC:       ## %bb.0:
-; MAC-NEXT:    subq $24, %rsp
-; MAC-NEXT:    fldt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fstpt (%rsp)
-; MAC-NEXT:    callq _logl
-; MAC-NEXT:    addq $24, %rsp
-; MAC-NEXT:    retq
-;
-; GISEL-X86-LABEL: log_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 logl
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: log_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 logl
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %r = tail call nnan ninf x86_fp80 @llvm.log.f80(x86_fp80 %x)
-  ret x86_fp80 %r
-}
-
 define float @log2_f32(float %x) #0 {
 ; GNU-LABEL: log2_f32:
 ; GNU:       # %bb.0:
@@ -447,63 +276,6 @@ define double @log2_f64(double %x) #0 {
   ret double %r
 }
 
-define x86_fp80 @log2_f80(x86_fp80 %x) #0 {
-; GNU-LABEL: log2_f80:
-; GNU:       # %bb.0:
-; GNU-NEXT:    subq $24, %rsp
-; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fstpt (%rsp)
-; GNU-NEXT:    callq log2l at PLT
-; GNU-NEXT:    addq $24, %rsp
-; GNU-NEXT:    retq
-;
-; WIN-LABEL: log2_f80:
-; WIN:       # %bb.0:
-; WIN-NEXT:    pushq %rsi
-; WIN-NEXT:    subq $64, %rsp
-; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    fldt (%rdx)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN-NEXT:    callq log2l
-; WIN-NEXT:    fldt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt (%rsi)
-; WIN-NEXT:    movq %rsi, %rax
-; WIN-NEXT:    addq $64, %rsp
-; WIN-NEXT:    popq %rsi
-; WIN-NEXT:    retq
-;
-; MAC-LABEL: log2_f80:
-; MAC:       ## %bb.0:
-; MAC-NEXT:    subq $24, %rsp
-; MAC-NEXT:    fldt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fstpt (%rsp)
-; MAC-NEXT:    callq _log2l
-; MAC-NEXT:    addq $24, %rsp
-; MAC-NEXT:    retq
-;
-; GISEL-X86-LABEL: log2_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 log2l
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: log2_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 log2l
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %r = tail call nnan ninf x86_fp80 @llvm.log2.f80(x86_fp80 %x)
-  ret x86_fp80 %r
-}
-
 define float @log10_f32(float %x) #0 {
 ; GNU-LABEL: log10_f32:
 ; GNU:       # %bb.0:
@@ -571,63 +343,6 @@ define double @log10_f64(double %x) #0 {
   ret double %r
 }
 
-define x86_fp80 @log10_f80(x86_fp80 %x) #0 {
-; GNU-LABEL: log10_f80:
-; GNU:       # %bb.0:
-; GNU-NEXT:    subq $24, %rsp
-; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fstpt (%rsp)
-; GNU-NEXT:    callq log10l at PLT
-; GNU-NEXT:    addq $24, %rsp
-; GNU-NEXT:    retq
-;
-; WIN-LABEL: log10_f80:
-; WIN:       # %bb.0:
-; WIN-NEXT:    pushq %rsi
-; WIN-NEXT:    subq $64, %rsp
-; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    fldt (%rdx)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN-NEXT:    callq log10l
-; WIN-NEXT:    fldt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt (%rsi)
-; WIN-NEXT:    movq %rsi, %rax
-; WIN-NEXT:    addq $64, %rsp
-; WIN-NEXT:    popq %rsi
-; WIN-NEXT:    retq
-;
-; MAC-LABEL: log10_f80:
-; MAC:       ## %bb.0:
-; MAC-NEXT:    subq $24, %rsp
-; MAC-NEXT:    fldt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fstpt (%rsp)
-; MAC-NEXT:    callq _log10l
-; MAC-NEXT:    addq $24, %rsp
-; MAC-NEXT:    retq
-;
-; GISEL-X86-LABEL: log10_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 log10l
-; GISEL-X86-NEXT:    addl $12, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: log10_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 log10l
-; GISEL-X64-NEXT:    addq $24, %rsp
-; GISEL-X64-NEXT:    retq
-  %r = tail call nnan ninf x86_fp80 @llvm.log10.f80(x86_fp80 %x)
-  ret x86_fp80 %r
-}
-
 define float @pow_f32(float %x) #0 {
 ; GNU-LABEL: pow_f32:
 ; GNU:       # %bb.0:
@@ -708,97 +423,23 @@ define double @pow_f64(double %x) #0 {
   ret double %r
 }
 
-define x86_fp80 @pow_f80(x86_fp80 %x) #0 {
-; GNU-LABEL: pow_f80:
-; GNU:       # %bb.0:
-; GNU-NEXT:    subq $40, %rsp
-; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fld %st(0)
-; GNU-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; GNU-NEXT:    fstpt (%rsp)
-; GNU-NEXT:    callq powl at PLT
-; GNU-NEXT:    addq $40, %rsp
-; GNU-NEXT:    retq
-;
-; WIN-LABEL: pow_f80:
-; WIN:       # %bb.0:
-; WIN-NEXT:    pushq %rsi
-; WIN-NEXT:    subq $80, %rsp
-; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    fldt (%rdx)
-; WIN-NEXT:    fld %st(0)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
-; WIN-NEXT:    callq powl
-; WIN-NEXT:    fldt {{[0-9]+}}(%rsp)
-; WIN-NEXT:    fstpt (%rsi)
-; WIN-NEXT:    movq %rsi, %rax
-; WIN-NEXT:    addq $80, %rsp
-; WIN-NEXT:    popq %rsi
-; WIN-NEXT:    retq
-;
-; MAC-LABEL: pow_f80:
-; MAC:       ## %bb.0:
-; MAC-NEXT:    subq $40, %rsp
-; MAC-NEXT:    fldt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fld %st(0)
-; MAC-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; MAC-NEXT:    fstpt (%rsp)
-; MAC-NEXT:    callq _powl
-; MAC-NEXT:    addq $40, %rsp
-; MAC-NEXT:    retq
-;
-; GISEL-X86-LABEL: pow_f80:
-; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $28, %esp
-; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fld %st(0)
-; GISEL-X86-NEXT:    fstpt (%esp)
-; GISEL-X86-NEXT:    fstpt {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    calll powl
-; GISEL-X86-NEXT:    addl $28, %esp
-; GISEL-X86-NEXT:    retl
-;
-; GISEL-X64-LABEL: pow_f80:
-; GISEL-X64:       # %bb.0:
-; GISEL-X64-NEXT:    subq $40, %rsp
-; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fld %st(0)
-; GISEL-X64-NEXT:    fstpt (%rsp)
-; GISEL-X64-NEXT:    fstpt {{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    callq powl
-; GISEL-X64-NEXT:    addq $40, %rsp
-; GISEL-X64-NEXT:    retq
-  %r = tail call nnan ninf x86_fp80 @llvm.pow.f80(x86_fp80 %x, x86_fp80 %x)
-  ret x86_fp80 %r
-}
-
 declare float @llvm.exp.f32(float) #1
 declare double @llvm.exp.f64(double) #1
-declare x86_fp80 @llvm.exp.f80(x86_fp80) #1
 
 declare float @llvm.exp2.f32(float) #1
 declare double @llvm.exp2.f64(double) #1
-declare x86_fp80 @llvm.exp2.f80(x86_fp80) #1
 
 declare float @llvm.log.f32(float) #1
 declare double @llvm.log.f64(double) #1
-declare x86_fp80 @llvm.log.f80(x86_fp80) #1
 
 declare float @llvm.log2.f32(float) #1
 declare double @llvm.log2.f64(double) #1
-declare x86_fp80 @llvm.log2.f80(x86_fp80) #1
 
 declare float @llvm.log10.f32(float) #1
 declare double @llvm.log10.f64(double) #1
-declare x86_fp80 @llvm.log10.f80(x86_fp80) #1
 
 declare float @llvm.pow.f32(float, float) #1
 declare double @llvm.pow.f64(double, double) #1
-declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) #1
 
 attributes #0 = { nounwind "no-infs-fp-math"="true" "no-nans-fp-math"="true" }
 attributes #1 = { nounwind readnone speculatable }
diff --git a/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll b/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll
index d3020bcbcd961..767da1ee190f1 100644
--- a/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll
+++ b/llvm/test/CodeGen/X86/fp128-libcalls-longdouble.ll
@@ -90,9 +90,18 @@ define dso_local void @Test128Rint(fp128 %d1) nounwind {
   ret void
 }
 
+define fp128 @Test128Ldexp(fp128 %x, i32 %exp) nounwind {
+; ANDROID-LABEL: Test128Ldexp:
+; ANDROID:       # %bb.0:
+; ANDROID-NEXT:    jmp ldexpl at PLT # TAILCALL
+  %r = tail call fp128 @llvm.ldexp.f128.i32(fp128 %x, i32 %exp)
+  ret fp128 %r
+}
+
 declare fp128 @llvm.maxnum.f128(fp128, fp128)
 declare fp128 @llvm.minnum.f128(fp128, fp128)
 declare fp128 @llvm.sqrt.f128(fp128)
 declare fp128 @llvm.sin.f128(fp128)
 declare fp128 @llvm.pow.f128(fp128, fp128)
 declare fp128 @llvm.rint.f128(fp128)
+declare fp128 @llvm.ldexp.f128.i32(fp128, i32)
diff --git a/llvm/test/CodeGen/X86/fp80-conv-libcalls.ll b/llvm/test/CodeGen/X86/fp80-conv-libcalls.ll
new file mode 100644
index 0000000000000..9a41d25feb030
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp80-conv-libcalls.ll
@@ -0,0 +1,146 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=x86_64-linux-gnu    -mattr=+sse < %s | FileCheck %s --check-prefix=GNU
+; RUN: llc -mtriple=x86_64-linux-android -mattr=+sse < %s | FileCheck %s --check-prefix=ANDROID
+; RUN: llc -mtriple=x86_64-pc-windows-msvc          < %s | FileCheck %s --check-prefix=MSVC
+
+; The x86_fp80 compiler-rt helpers are keyed to the IR type, which is legal on
+; all x86 regardless of the long double format, so they are available even when
+; long double is not x87 (IEEE double on windows-msvc, IEEE quad on Android).
+
+define fp128 @test_extend(x86_fp80 %x) nounwind {
+; GNU-LABEL: test_extend:
+; GNU:       # %bb.0:
+; GNU-NEXT:    jmp __extendxftf2 at PLT # TAILCALL
+;
+; ANDROID-LABEL: test_extend:
+; ANDROID:       # %bb.0:
+; ANDROID-NEXT:    jmp __extendxftf2 at PLT # TAILCALL
+;
+; MSVC-LABEL: test_extend:
+; MSVC:       # %bb.0:
+; MSVC-NEXT:    pushq %rsi
+; MSVC-NEXT:    subq $64, %rsp
+; MSVC-NEXT:    movq %rcx, %rsi
+; MSVC-NEXT:    fldt (%rdx)
+; MSVC-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; MSVC-NEXT:    callq __extendxftf2
+; MSVC-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; MSVC-NEXT:    movaps %xmm0, (%rsi)
+; MSVC-NEXT:    movq %rsi, %rax
+; MSVC-NEXT:    addq $64, %rsp
+; MSVC-NEXT:    popq %rsi
+; MSVC-NEXT:    retq
+  %r = fpext x86_fp80 %x to fp128
+  ret fp128 %r
+}
+
+define x86_fp80 @test_trunc(fp128 %x) nounwind {
+; GNU-LABEL: test_trunc:
+; GNU:       # %bb.0:
+; GNU-NEXT:    pushq %rax
+; GNU-NEXT:    callq __trunctfxf2 at PLT
+; GNU-NEXT:    popq %rax
+; GNU-NEXT:    retq
+;
+; ANDROID-LABEL: test_trunc:
+; ANDROID:       # %bb.0:
+; ANDROID-NEXT:    pushq %rax
+; ANDROID-NEXT:    callq __trunctfxf2 at PLT
+; ANDROID-NEXT:    popq %rax
+; ANDROID-NEXT:    retq
+;
+; MSVC-LABEL: test_trunc:
+; MSVC:       # %bb.0:
+; MSVC-NEXT:    pushq %rsi
+; MSVC-NEXT:    subq $64, %rsp
+; MSVC-NEXT:    movq %rcx, %rsi
+; MSVC-NEXT:    movaps (%rdx), %xmm0
+; MSVC-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; MSVC-NEXT:    callq __trunctfxf2
+; MSVC-NEXT:    fldt {{[0-9]+}}(%rsp)
+; MSVC-NEXT:    fstpt (%rsi)
+; MSVC-NEXT:    movq %rsi, %rax
+; MSVC-NEXT:    addq $64, %rsp
+; MSVC-NEXT:    popq %rsi
+; MSVC-NEXT:    retq
+  %r = fptrunc fp128 %x to x86_fp80
+  ret x86_fp80 %r
+}
+
+define i128 @test_fptosi(x86_fp80 %x) nounwind {
+; GNU-LABEL: test_fptosi:
+; GNU:       # %bb.0:
+; GNU-NEXT:    subq $24, %rsp
+; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT:    fstpt (%rsp)
+; GNU-NEXT:    callq __fixxfti at PLT
+; GNU-NEXT:    addq $24, %rsp
+; GNU-NEXT:    retq
+;
+; ANDROID-LABEL: test_fptosi:
+; ANDROID:       # %bb.0:
+; ANDROID-NEXT:    subq $24, %rsp
+; ANDROID-NEXT:    fldt {{[0-9]+}}(%rsp)
+; ANDROID-NEXT:    fstpt (%rsp)
+; ANDROID-NEXT:    callq __fixxfti at PLT
+; ANDROID-NEXT:    addq $24, %rsp
+; ANDROID-NEXT:    retq
+;
+; MSVC-LABEL: test_fptosi:
+; MSVC:       # %bb.0:
+; MSVC-NEXT:    subq $56, %rsp
+; MSVC-NEXT:    fldt (%rcx)
+; MSVC-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; MSVC-NEXT:    callq __fixxfti
+; MSVC-NEXT:    movq %xmm0, %rax
+; MSVC-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
+; MSVC-NEXT:    movq %xmm0, %rdx
+; MSVC-NEXT:    addq $56, %rsp
+; MSVC-NEXT:    retq
+  %r = fptosi x86_fp80 %x to i128
+  ret i128 %r
+}
+
+define x86_fp80 @test_powi(x86_fp80 %x, i32 %n) nounwind {
+; GNU-LABEL: test_powi:
+; GNU:       # %bb.0:
+; GNU-NEXT:    subq $24, %rsp
+; GNU-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GNU-NEXT:    fstpt (%rsp)
+; GNU-NEXT:    callq __powixf2 at PLT
+; GNU-NEXT:    addq $24, %rsp
+; GNU-NEXT:    retq
+;
+; ANDROID-LABEL: test_powi:
+; ANDROID:       # %bb.0:
+; ANDROID-NEXT:    subq $24, %rsp
+; ANDROID-NEXT:    fldt {{[0-9]+}}(%rsp)
+; ANDROID-NEXT:    fstpt (%rsp)
+; ANDROID-NEXT:    callq __powixf2 at PLT
+; ANDROID-NEXT:    addq $24, %rsp
+; ANDROID-NEXT:    retq
+;
+; MSVC-LABEL: test_powi:
+; MSVC:       # %bb.0:
+; MSVC-NEXT:    pushq %rsi
+; MSVC-NEXT:    subq $64, %rsp
+; MSVC-NEXT:    movq %rcx, %rsi
+; MSVC-NEXT:    fldt (%rdx)
+; MSVC-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; MSVC-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; MSVC-NEXT:    callq __powixf2
+; MSVC-NEXT:    fldt {{[0-9]+}}(%rsp)
+; MSVC-NEXT:    fstpt (%rsi)
+; MSVC-NEXT:    movq %rsi, %rax
+; MSVC-NEXT:    addq $64, %rsp
+; MSVC-NEXT:    popq %rsi
+; MSVC-NEXT:    retq
+  %r = call x86_fp80 @llvm.powi.f80.i32(x86_fp80 %x, i32 %n)
+  ret x86_fp80 %r
+}
diff --git a/llvm/test/CodeGen/X86/fp80-math-libcalls.ll b/llvm/test/CodeGen/X86/fp80-math-libcalls.ll
new file mode 100644
index 0000000000000..463b1cf77b01a
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp80-math-libcalls.ll
@@ -0,0 +1,374 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=x86_64-linux-gnu < %s | FileCheck %s --check-prefix=X64
+; RUN: llc -mtriple=i686-linux-gnu   < %s | FileCheck %s --check-prefix=X86
+
+; On x87-long-double targets, x86_fp80 math intrinsics lower to the l-suffixed
+; libm long double libcalls. On targets whose long double is not x87 (IEEE
+; double on windows-msvc, IEEE quad on Android) these libm calls are not
+; available for x86_fp80 and are diagnosed instead (see
+; fp80-math-no-libcall-error.ll). The nnan ninf variants confirm the finite-math
+; flags still use the plain l-suffixed libcall (there is no x86_fp80 __*_finite).
+
+define x86_fp80 @test_acos(x86_fp80 %x) nounwind {
+; X64-LABEL: test_acos:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq acosl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_acos:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll acosl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.acos.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_sin(x86_fp80 %x) nounwind {
+; X64-LABEL: test_sin:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq sinl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_sin:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll sinl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.sin.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_pow(x86_fp80 %x, x86_fp80 %y) nounwind {
+; X64-LABEL: test_pow:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $40, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq powl at PLT
+; X64-NEXT:    addq $40, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_pow:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $28, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll powl
+; X86-NEXT:    addl $28, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.pow.f80(x86_fp80 %x, x86_fp80 %y)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_pow_finite(x86_fp80 %x, x86_fp80 %y) nounwind {
+; X64-LABEL: test_pow_finite:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $40, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq powl at PLT
+; X64-NEXT:    addq $40, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_pow_finite:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $28, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll powl
+; X86-NEXT:    addl $28, %esp
+; X86-NEXT:    retl
+  %r = call nnan ninf x86_fp80 @llvm.pow.f80(x86_fp80 %x, x86_fp80 %y)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_rint(x86_fp80 %x) nounwind {
+; X64-LABEL: test_rint:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq rintl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_rint:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll rintl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.rint.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_maxnum(x86_fp80 %x, x86_fp80 %y) nounwind {
+; X64-LABEL: test_maxnum:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $40, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq fmaxl at PLT
+; X64-NEXT:    addq $40, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_maxnum:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $28, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll fmaxl
+; X86-NEXT:    addl $28, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.maxnum.f80(x86_fp80 %x, x86_fp80 %y)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_exp(x86_fp80 %x) nounwind {
+; X64-LABEL: test_exp:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq expl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_exp:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll expl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.exp.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_exp_finite(x86_fp80 %x) nounwind {
+; X64-LABEL: test_exp_finite:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq expl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_exp_finite:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll expl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call nnan ninf x86_fp80 @llvm.exp.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_exp2(x86_fp80 %x) nounwind {
+; X64-LABEL: test_exp2:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq exp2l at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_exp2:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll exp2l
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.exp2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_exp2_finite(x86_fp80 %x) nounwind {
+; X64-LABEL: test_exp2_finite:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq exp2l at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_exp2_finite:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll exp2l
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call nnan ninf x86_fp80 @llvm.exp2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_log(x86_fp80 %x) nounwind {
+; X64-LABEL: test_log:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq logl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_log:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll logl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.log.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_log_finite(x86_fp80 %x) nounwind {
+; X64-LABEL: test_log_finite:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq logl at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_log_finite:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll logl
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call nnan ninf x86_fp80 @llvm.log.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_log2(x86_fp80 %x) nounwind {
+; X64-LABEL: test_log2:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq log2l at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_log2:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll log2l
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.log2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_log2_finite(x86_fp80 %x) nounwind {
+; X64-LABEL: test_log2_finite:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq log2l at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_log2_finite:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll log2l
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call nnan ninf x86_fp80 @llvm.log2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_log10(x86_fp80 %x) nounwind {
+; X64-LABEL: test_log10:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq log10l at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_log10:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll log10l
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call x86_fp80 @llvm.log10.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+define x86_fp80 @test_log10_finite(x86_fp80 %x) nounwind {
+; X64-LABEL: test_log10_finite:
+; X64:       # %bb.0:
+; X64-NEXT:    subq $24, %rsp
+; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpt (%rsp)
+; X64-NEXT:    callq log10l at PLT
+; X64-NEXT:    addq $24, %rsp
+; X64-NEXT:    retq
+;
+; X86-LABEL: test_log10_finite:
+; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpt (%esp)
+; X86-NEXT:    calll log10l
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    retl
+  %r = call nnan ninf x86_fp80 @llvm.log10.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
diff --git a/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll b/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll
new file mode 100644
index 0000000000000..a2d69cfe20b87
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll
@@ -0,0 +1,92 @@
+; RUN: not llc -mtriple=x86_64-pc-windows-msvc -filetype=null %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=x86_64-linux-android -filetype=null %s 2>&1 | FileCheck %s
+
+; The l-suffixed long double math libcalls only exist when long double is x87.
+; On windows-msvc (IEEE double) and Android (fp128) an x86_fp80 math intrinsic
+; must diagnose a missing libcall rather than emit a wrongly-typed call. The
+; nnan ninf variants confirm the finite-math flags do not route to a different
+; (still missing) libcall.
+
+; CHECK: error: no libcall available for facos
+define x86_fp80 @test_acos(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.acos.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fsin
+define x86_fp80 @test_sin(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.sin.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fpow
+define x86_fp80 @test_pow(x86_fp80 %x, x86_fp80 %y) nounwind {
+  %r = call x86_fp80 @llvm.pow.f80(x86_fp80 %x, x86_fp80 %y)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fpow
+define x86_fp80 @test_pow_finite(x86_fp80 %x, x86_fp80 %y) nounwind {
+  %r = call nnan ninf x86_fp80 @llvm.pow.f80(x86_fp80 %x, x86_fp80 %y)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fexp
+define x86_fp80 @test_exp(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.exp.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fexp
+define x86_fp80 @test_exp_finite(x86_fp80 %x) nounwind {
+  %r = call nnan ninf x86_fp80 @llvm.exp.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fexp2
+define x86_fp80 @test_exp2(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.exp2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for fexp2
+define x86_fp80 @test_exp2_finite(x86_fp80 %x) nounwind {
+  %r = call nnan ninf x86_fp80 @llvm.exp2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for flog
+define x86_fp80 @test_log(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.log.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for flog
+define x86_fp80 @test_log_finite(x86_fp80 %x) nounwind {
+  %r = call nnan ninf x86_fp80 @llvm.log.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for flog2
+define x86_fp80 @test_log2(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.log2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for flog2
+define x86_fp80 @test_log2_finite(x86_fp80 %x) nounwind {
+  %r = call nnan ninf x86_fp80 @llvm.log2.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for flog10
+define x86_fp80 @test_log10(x86_fp80 %x) nounwind {
+  %r = call x86_fp80 @llvm.log10.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for flog10
+define x86_fp80 @test_log10_finite(x86_fp80 %x) nounwind {
+  %r = call nnan ninf x86_fp80 @llvm.log10.f80(x86_fp80 %x)
+  ret x86_fp80 %r
+}
diff --git a/llvm/test/CodeGen/X86/ldexp-avx512.ll b/llvm/test/CodeGen/X86/ldexp-avx512.ll
index 874596ed3e41d..cce76e969ffff 100644
--- a/llvm/test/CodeGen/X86/ldexp-avx512.ll
+++ b/llvm/test/CodeGen/X86/ldexp-avx512.ll
@@ -62,15 +62,20 @@ entry:
 }
 declare double @ldexp(double, i32) memory(none)
 
-define fp128 @testExpl(fp128 %x, i32 %exp) nounwind {
-; CHECK-LABEL: testExpl:
+define x86_fp80 @test_fp80(x86_fp80 %x, i32 %exp) nounwind {
+; CHECK-LABEL: test_fp80:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    jmp ldexpl at PLT # TAILCALL
+; CHECK-NEXT:    subq $24, %rsp
+; CHECK-NEXT:    fldt {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    fstpt (%rsp)
+; CHECK-NEXT:    callq ldexpl at PLT
+; CHECK-NEXT:    addq $24, %rsp
+; CHECK-NEXT:    retq
 entry:
-  %r = tail call fast fp128 @ldexpl(fp128 %x, i32 %exp)
-  ret fp128 %r
+  %r = tail call x86_fp80 @llvm.ldexp.f80.i32(x86_fp80 %x, i32 %exp)
+  ret x86_fp80 %r
 }
-declare fp128 @ldexpl(fp128, i32) memory(none)
+declare x86_fp80 @llvm.ldexp.f80.i32(x86_fp80, i32) memory(none)
 
 define <8 x half> @test_ldexp_8xhalf(<8 x half> %x, <8 x i16> %exp) nounwind {
 ; AVX512F-LABEL: test_ldexp_8xhalf:

>From af76f11ad7d73beffae992719dd83f23660980b9 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 18 Aug 2026 15:10:55 +0200
Subject: [PATCH 2/3] split mips fp128 sincosl test

---
 llvm/test/CodeGen/Mips/llvm.sincos.f128.ll |  78 ++++++
 llvm/test/CodeGen/Mips/llvm.sincos.ll      | 266 ---------------------
 2 files changed, 78 insertions(+), 266 deletions(-)
 create mode 100644 llvm/test/CodeGen/Mips/llvm.sincos.f128.ll

diff --git a/llvm/test/CodeGen/Mips/llvm.sincos.f128.ll b/llvm/test/CodeGen/Mips/llvm.sincos.f128.ll
new file mode 100644
index 0000000000000..d3388fabc8397
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/llvm.sincos.f128.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=mips64 < %s | FileCheck %s -check-prefix=SOFT-FLOAT-64
+; RUN: not llc -mtriple=mipsel -filetype=null < %s 2>&1 | FileCheck %s -check-prefix=ERR
+; RUN: not llc -mtriple=mips   -filetype=null < %s 2>&1 | FileCheck %s -check-prefix=ERR
+
+; fp128 sincos lowers to the sincosl long double libcall only where long double
+; is IEEE quad (mips64/n64). On 32-bit MIPS long double is IEEE double, so
+; sincosl is the wrong type and no libcall is available; it must diagnose rather
+; than emit a wrongly-typed call.
+
+; ERR: error: do not know how to soften fsincos
+define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
+; SOFT-FLOAT-64-LABEL: test_sincos_f128:
+; SOFT-FLOAT-64:       # %bb.0:
+; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, -48
+; SOFT-FLOAT-64-NEXT:    sd $ra, 40($sp) # 8-byte Folded Spill
+; SOFT-FLOAT-64-NEXT:    daddiu $6, $sp, 16
+; SOFT-FLOAT-64-NEXT:    jal sincosl
+; SOFT-FLOAT-64-NEXT:    daddiu $7, $sp, 0
+; SOFT-FLOAT-64-NEXT:    ldc1 $f0, 16($sp)
+; SOFT-FLOAT-64-NEXT:    ldc1 $f2, 24($sp)
+; SOFT-FLOAT-64-NEXT:    ld $2, 0($sp)
+; SOFT-FLOAT-64-NEXT:    ld $3, 8($sp)
+; SOFT-FLOAT-64-NEXT:    ld $ra, 40($sp) # 8-byte Folded Reload
+; SOFT-FLOAT-64-NEXT:    jr $ra
+; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, 48
+  %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
+  ret { fp128, fp128 } %result
+}
+
+define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
+; SOFT-FLOAT-64-LABEL: test_sincos_v2f128:
+; SOFT-FLOAT-64:       # %bb.0:
+; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, -96
+; SOFT-FLOAT-64-NEXT:    sd $ra, 88($sp) # 8-byte Folded Spill
+; SOFT-FLOAT-64-NEXT:    sd $18, 80($sp) # 8-byte Folded Spill
+; SOFT-FLOAT-64-NEXT:    sd $17, 72($sp) # 8-byte Folded Spill
+; SOFT-FLOAT-64-NEXT:    sd $16, 64($sp) # 8-byte Folded Spill
+; SOFT-FLOAT-64-NEXT:    move $16, $6
+; SOFT-FLOAT-64-NEXT:    move $17, $5
+; SOFT-FLOAT-64-NEXT:    move $18, $4
+; SOFT-FLOAT-64-NEXT:    dmtc1 $7, $f12
+; SOFT-FLOAT-64-NEXT:    dmtc1 $8, $f13
+; SOFT-FLOAT-64-NEXT:    daddiu $6, $sp, 48
+; SOFT-FLOAT-64-NEXT:    jal sincosl
+; SOFT-FLOAT-64-NEXT:    daddiu $7, $sp, 32
+; SOFT-FLOAT-64-NEXT:    dmtc1 $17, $f12
+; SOFT-FLOAT-64-NEXT:    dmtc1 $16, $f13
+; SOFT-FLOAT-64-NEXT:    daddiu $6, $sp, 16
+; SOFT-FLOAT-64-NEXT:    jal sincosl
+; SOFT-FLOAT-64-NEXT:    daddiu $7, $sp, 0
+; SOFT-FLOAT-64-NEXT:    ld $1, 56($sp)
+; SOFT-FLOAT-64-NEXT:    ld $2, 0($sp)
+; SOFT-FLOAT-64-NEXT:    ld $3, 8($sp)
+; SOFT-FLOAT-64-NEXT:    ld $4, 32($sp)
+; SOFT-FLOAT-64-NEXT:    ld $5, 40($sp)
+; SOFT-FLOAT-64-NEXT:    sd $5, 56($18)
+; SOFT-FLOAT-64-NEXT:    sd $4, 48($18)
+; SOFT-FLOAT-64-NEXT:    sd $3, 40($18)
+; SOFT-FLOAT-64-NEXT:    sd $2, 32($18)
+; SOFT-FLOAT-64-NEXT:    sd $1, 24($18)
+; SOFT-FLOAT-64-NEXT:    ld $1, 48($sp)
+; SOFT-FLOAT-64-NEXT:    sd $1, 16($18)
+; SOFT-FLOAT-64-NEXT:    ld $1, 24($sp)
+; SOFT-FLOAT-64-NEXT:    sd $1, 8($18)
+; SOFT-FLOAT-64-NEXT:    ld $1, 16($sp)
+; SOFT-FLOAT-64-NEXT:    sd $1, 0($18)
+; SOFT-FLOAT-64-NEXT:    ld $16, 64($sp) # 8-byte Folded Reload
+; SOFT-FLOAT-64-NEXT:    ld $17, 72($sp) # 8-byte Folded Reload
+; SOFT-FLOAT-64-NEXT:    ld $18, 80($sp) # 8-byte Folded Reload
+; SOFT-FLOAT-64-NEXT:    ld $ra, 88($sp) # 8-byte Folded Reload
+; SOFT-FLOAT-64-NEXT:    jr $ra
+; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, 96
+  %result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
+  ret { <2 x fp128>, <2 x fp128> } %result
+}
+
+attributes #0 = { nounwind }
diff --git a/llvm/test/CodeGen/Mips/llvm.sincos.ll b/llvm/test/CodeGen/Mips/llvm.sincos.ll
index 58eb427d3a69b..014d36aa07dce 100644
--- a/llvm/test/CodeGen/Mips/llvm.sincos.ll
+++ b/llvm/test/CodeGen/Mips/llvm.sincos.ll
@@ -765,270 +765,4 @@ define { <2 x double>, <2 x double> } @test_sincos_v2f64(<2 x double> %a) #0 {
   ret { <2 x double>, <2 x double> } %result
 }
 
-define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
-; MIPSEL-LABEL: test_sincos_f128:
-; MIPSEL:       # %bb.0:
-; MIPSEL-NEXT:    addiu $sp, $sp, -64
-; MIPSEL-NEXT:    sw $ra, 60($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT:    sw $16, 56($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT:    move $1, $7
-; MIPSEL-NEXT:    move $16, $4
-; MIPSEL-NEXT:    addiu $2, $sp, 24
-; MIPSEL-NEXT:    sw $2, 20($sp)
-; MIPSEL-NEXT:    addiu $2, $sp, 40
-; MIPSEL-NEXT:    sw $2, 16($sp)
-; MIPSEL-NEXT:    lw $7, 80($sp)
-; MIPSEL-NEXT:    move $4, $5
-; MIPSEL-NEXT:    move $5, $6
-; MIPSEL-NEXT:    jal sincosl
-; MIPSEL-NEXT:    move $6, $1
-; MIPSEL-NEXT:    lw $1, 52($sp)
-; MIPSEL-NEXT:    lw $2, 24($sp)
-; MIPSEL-NEXT:    lw $3, 28($sp)
-; MIPSEL-NEXT:    lw $4, 32($sp)
-; MIPSEL-NEXT:    lw $5, 36($sp)
-; MIPSEL-NEXT:    sw $5, 28($16)
-; MIPSEL-NEXT:    sw $4, 24($16)
-; MIPSEL-NEXT:    sw $3, 20($16)
-; MIPSEL-NEXT:    sw $2, 16($16)
-; MIPSEL-NEXT:    sw $1, 12($16)
-; MIPSEL-NEXT:    lw $1, 48($sp)
-; MIPSEL-NEXT:    sw $1, 8($16)
-; MIPSEL-NEXT:    lw $1, 44($sp)
-; MIPSEL-NEXT:    sw $1, 4($16)
-; MIPSEL-NEXT:    lw $1, 40($sp)
-; MIPSEL-NEXT:    sw $1, 0($16)
-; MIPSEL-NEXT:    lw $16, 56($sp) # 4-byte Folded Reload
-; MIPSEL-NEXT:    lw $ra, 60($sp) # 4-byte Folded Reload
-; MIPSEL-NEXT:    jr $ra
-; MIPSEL-NEXT:    addiu $sp, $sp, 64
-;
-; SOFT-FLOAT-32-LABEL: test_sincos_f128:
-; SOFT-FLOAT-32:       # %bb.0:
-; SOFT-FLOAT-32-NEXT:    addiu $sp, $sp, -64
-; SOFT-FLOAT-32-NEXT:    sw $ra, 60($sp) # 4-byte Folded Spill
-; SOFT-FLOAT-32-NEXT:    sw $16, 56($sp) # 4-byte Folded Spill
-; SOFT-FLOAT-32-NEXT:    move $1, $7
-; SOFT-FLOAT-32-NEXT:    move $16, $4
-; SOFT-FLOAT-32-NEXT:    addiu $2, $sp, 24
-; SOFT-FLOAT-32-NEXT:    sw $2, 20($sp)
-; SOFT-FLOAT-32-NEXT:    addiu $2, $sp, 40
-; SOFT-FLOAT-32-NEXT:    sw $2, 16($sp)
-; SOFT-FLOAT-32-NEXT:    lw $7, 80($sp)
-; SOFT-FLOAT-32-NEXT:    move $4, $5
-; SOFT-FLOAT-32-NEXT:    move $5, $6
-; SOFT-FLOAT-32-NEXT:    jal sincosl
-; SOFT-FLOAT-32-NEXT:    move $6, $1
-; SOFT-FLOAT-32-NEXT:    lw $1, 52($sp)
-; SOFT-FLOAT-32-NEXT:    lw $2, 24($sp)
-; SOFT-FLOAT-32-NEXT:    lw $3, 28($sp)
-; SOFT-FLOAT-32-NEXT:    lw $4, 32($sp)
-; SOFT-FLOAT-32-NEXT:    lw $5, 36($sp)
-; SOFT-FLOAT-32-NEXT:    sw $5, 28($16)
-; SOFT-FLOAT-32-NEXT:    sw $4, 24($16)
-; SOFT-FLOAT-32-NEXT:    sw $3, 20($16)
-; SOFT-FLOAT-32-NEXT:    sw $2, 16($16)
-; SOFT-FLOAT-32-NEXT:    sw $1, 12($16)
-; SOFT-FLOAT-32-NEXT:    lw $1, 48($sp)
-; SOFT-FLOAT-32-NEXT:    sw $1, 8($16)
-; SOFT-FLOAT-32-NEXT:    lw $1, 44($sp)
-; SOFT-FLOAT-32-NEXT:    sw $1, 4($16)
-; SOFT-FLOAT-32-NEXT:    lw $1, 40($sp)
-; SOFT-FLOAT-32-NEXT:    sw $1, 0($16)
-; SOFT-FLOAT-32-NEXT:    lw $16, 56($sp) # 4-byte Folded Reload
-; SOFT-FLOAT-32-NEXT:    lw $ra, 60($sp) # 4-byte Folded Reload
-; SOFT-FLOAT-32-NEXT:    jr $ra
-; SOFT-FLOAT-32-NEXT:    addiu $sp, $sp, 64
-;
-; SOFT-FLOAT-64-LABEL: test_sincos_f128:
-; SOFT-FLOAT-64:       # %bb.0:
-; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, -48
-; SOFT-FLOAT-64-NEXT:    sd $ra, 40($sp) # 8-byte Folded Spill
-; SOFT-FLOAT-64-NEXT:    daddiu $6, $sp, 16
-; SOFT-FLOAT-64-NEXT:    jal sincosl
-; SOFT-FLOAT-64-NEXT:    daddiu $7, $sp, 0
-; SOFT-FLOAT-64-NEXT:    ldc1 $f0, 16($sp)
-; SOFT-FLOAT-64-NEXT:    ldc1 $f2, 24($sp)
-; SOFT-FLOAT-64-NEXT:    ld $2, 0($sp)
-; SOFT-FLOAT-64-NEXT:    ld $3, 8($sp)
-; SOFT-FLOAT-64-NEXT:    ld $ra, 40($sp) # 8-byte Folded Reload
-; SOFT-FLOAT-64-NEXT:    jr $ra
-; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, 48
-  %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
-  ret { fp128, fp128 } %result
-}
-
-define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
-; MIPSEL-LABEL: test_sincos_v2f128:
-; MIPSEL:       # %bb.0:
-; MIPSEL-NEXT:    addiu $sp, $sp, -96
-; MIPSEL-NEXT:    sw $ra, 92($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT:    sw $16, 88($sp) # 4-byte Folded Spill
-; MIPSEL-NEXT:    move $5, $7
-; MIPSEL-NEXT:    move $1, $6
-; MIPSEL-NEXT:    move $16, $4
-; MIPSEL-NEXT:    addiu $2, $sp, 24
-; MIPSEL-NEXT:    sw $2, 20($sp)
-; MIPSEL-NEXT:    addiu $2, $sp, 40
-; MIPSEL-NEXT:    sw $2, 16($sp)
-; MIPSEL-NEXT:    lw $6, 112($sp)
-; MIPSEL-NEXT:    lw $7, 116($sp)
-; MIPSEL-NEXT:    jal sincosl
-; MIPSEL-NEXT:    move $4, $1
-; MIPSEL-NEXT:    addiu $1, $sp, 56
-; MIPSEL-NEXT:    sw $1, 20($sp)
-; MIPSEL-NEXT:    addiu $1, $sp, 72
-; MIPSEL-NEXT:    sw $1, 16($sp)
-; MIPSEL-NEXT:    lw $4, 120($sp)
-; MIPSEL-NEXT:    lw $5, 124($sp)
-; MIPSEL-NEXT:    lw $6, 128($sp)
-; MIPSEL-NEXT:    lw $7, 132($sp)
-; MIPSEL-NEXT:    jal sincosl
-; MIPSEL-NEXT:    nop
-; MIPSEL-NEXT:    lw $1, 36($sp)
-; MIPSEL-NEXT:    lw $2, 56($sp)
-; MIPSEL-NEXT:    lw $3, 60($sp)
-; MIPSEL-NEXT:    lw $4, 64($sp)
-; MIPSEL-NEXT:    lw $5, 52($sp)
-; MIPSEL-NEXT:    lw $6, 72($sp)
-; MIPSEL-NEXT:    lw $7, 76($sp)
-; MIPSEL-NEXT:    lw $8, 80($sp)
-; MIPSEL-NEXT:    lw $9, 84($sp)
-; MIPSEL-NEXT:    lw $10, 24($sp)
-; MIPSEL-NEXT:    lw $11, 28($sp)
-; MIPSEL-NEXT:    lw $12, 32($sp)
-; MIPSEL-NEXT:    lw $13, 68($sp)
-; MIPSEL-NEXT:    sw $13, 60($16)
-; MIPSEL-NEXT:    sw $4, 56($16)
-; MIPSEL-NEXT:    sw $3, 52($16)
-; MIPSEL-NEXT:    sw $2, 48($16)
-; MIPSEL-NEXT:    sw $1, 44($16)
-; MIPSEL-NEXT:    sw $12, 40($16)
-; MIPSEL-NEXT:    sw $11, 36($16)
-; MIPSEL-NEXT:    sw $10, 32($16)
-; MIPSEL-NEXT:    sw $9, 28($16)
-; MIPSEL-NEXT:    sw $8, 24($16)
-; MIPSEL-NEXT:    sw $7, 20($16)
-; MIPSEL-NEXT:    sw $6, 16($16)
-; MIPSEL-NEXT:    sw $5, 12($16)
-; MIPSEL-NEXT:    lw $1, 48($sp)
-; MIPSEL-NEXT:    sw $1, 8($16)
-; MIPSEL-NEXT:    lw $1, 44($sp)
-; MIPSEL-NEXT:    sw $1, 4($16)
-; MIPSEL-NEXT:    lw $1, 40($sp)
-; MIPSEL-NEXT:    sw $1, 0($16)
-; MIPSEL-NEXT:    lw $16, 88($sp) # 4-byte Folded Reload
-; MIPSEL-NEXT:    lw $ra, 92($sp) # 4-byte Folded Reload
-; MIPSEL-NEXT:    jr $ra
-; MIPSEL-NEXT:    addiu $sp, $sp, 96
-;
-; SOFT-FLOAT-32-LABEL: test_sincos_v2f128:
-; SOFT-FLOAT-32:       # %bb.0:
-; SOFT-FLOAT-32-NEXT:    addiu $sp, $sp, -96
-; SOFT-FLOAT-32-NEXT:    sw $ra, 92($sp) # 4-byte Folded Spill
-; SOFT-FLOAT-32-NEXT:    sw $16, 88($sp) # 4-byte Folded Spill
-; SOFT-FLOAT-32-NEXT:    move $5, $7
-; SOFT-FLOAT-32-NEXT:    move $1, $6
-; SOFT-FLOAT-32-NEXT:    move $16, $4
-; SOFT-FLOAT-32-NEXT:    addiu $2, $sp, 24
-; SOFT-FLOAT-32-NEXT:    sw $2, 20($sp)
-; SOFT-FLOAT-32-NEXT:    addiu $2, $sp, 40
-; SOFT-FLOAT-32-NEXT:    sw $2, 16($sp)
-; SOFT-FLOAT-32-NEXT:    lw $6, 112($sp)
-; SOFT-FLOAT-32-NEXT:    lw $7, 116($sp)
-; SOFT-FLOAT-32-NEXT:    jal sincosl
-; SOFT-FLOAT-32-NEXT:    move $4, $1
-; SOFT-FLOAT-32-NEXT:    addiu $1, $sp, 56
-; SOFT-FLOAT-32-NEXT:    sw $1, 20($sp)
-; SOFT-FLOAT-32-NEXT:    addiu $1, $sp, 72
-; SOFT-FLOAT-32-NEXT:    sw $1, 16($sp)
-; SOFT-FLOAT-32-NEXT:    lw $4, 120($sp)
-; SOFT-FLOAT-32-NEXT:    lw $5, 124($sp)
-; SOFT-FLOAT-32-NEXT:    lw $6, 128($sp)
-; SOFT-FLOAT-32-NEXT:    lw $7, 132($sp)
-; SOFT-FLOAT-32-NEXT:    jal sincosl
-; SOFT-FLOAT-32-NEXT:    nop
-; SOFT-FLOAT-32-NEXT:    lw $1, 36($sp)
-; SOFT-FLOAT-32-NEXT:    lw $2, 56($sp)
-; SOFT-FLOAT-32-NEXT:    lw $3, 60($sp)
-; SOFT-FLOAT-32-NEXT:    lw $4, 64($sp)
-; SOFT-FLOAT-32-NEXT:    lw $5, 52($sp)
-; SOFT-FLOAT-32-NEXT:    lw $6, 72($sp)
-; SOFT-FLOAT-32-NEXT:    lw $7, 76($sp)
-; SOFT-FLOAT-32-NEXT:    lw $8, 80($sp)
-; SOFT-FLOAT-32-NEXT:    lw $9, 84($sp)
-; SOFT-FLOAT-32-NEXT:    lw $10, 24($sp)
-; SOFT-FLOAT-32-NEXT:    lw $11, 28($sp)
-; SOFT-FLOAT-32-NEXT:    lw $12, 32($sp)
-; SOFT-FLOAT-32-NEXT:    lw $13, 68($sp)
-; SOFT-FLOAT-32-NEXT:    sw $13, 60($16)
-; SOFT-FLOAT-32-NEXT:    sw $4, 56($16)
-; SOFT-FLOAT-32-NEXT:    sw $3, 52($16)
-; SOFT-FLOAT-32-NEXT:    sw $2, 48($16)
-; SOFT-FLOAT-32-NEXT:    sw $1, 44($16)
-; SOFT-FLOAT-32-NEXT:    sw $12, 40($16)
-; SOFT-FLOAT-32-NEXT:    sw $11, 36($16)
-; SOFT-FLOAT-32-NEXT:    sw $10, 32($16)
-; SOFT-FLOAT-32-NEXT:    sw $9, 28($16)
-; SOFT-FLOAT-32-NEXT:    sw $8, 24($16)
-; SOFT-FLOAT-32-NEXT:    sw $7, 20($16)
-; SOFT-FLOAT-32-NEXT:    sw $6, 16($16)
-; SOFT-FLOAT-32-NEXT:    sw $5, 12($16)
-; SOFT-FLOAT-32-NEXT:    lw $1, 48($sp)
-; SOFT-FLOAT-32-NEXT:    sw $1, 8($16)
-; SOFT-FLOAT-32-NEXT:    lw $1, 44($sp)
-; SOFT-FLOAT-32-NEXT:    sw $1, 4($16)
-; SOFT-FLOAT-32-NEXT:    lw $1, 40($sp)
-; SOFT-FLOAT-32-NEXT:    sw $1, 0($16)
-; SOFT-FLOAT-32-NEXT:    lw $16, 88($sp) # 4-byte Folded Reload
-; SOFT-FLOAT-32-NEXT:    lw $ra, 92($sp) # 4-byte Folded Reload
-; SOFT-FLOAT-32-NEXT:    jr $ra
-; SOFT-FLOAT-32-NEXT:    addiu $sp, $sp, 96
-;
-; SOFT-FLOAT-64-LABEL: test_sincos_v2f128:
-; SOFT-FLOAT-64:       # %bb.0:
-; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, -96
-; SOFT-FLOAT-64-NEXT:    sd $ra, 88($sp) # 8-byte Folded Spill
-; SOFT-FLOAT-64-NEXT:    sd $18, 80($sp) # 8-byte Folded Spill
-; SOFT-FLOAT-64-NEXT:    sd $17, 72($sp) # 8-byte Folded Spill
-; SOFT-FLOAT-64-NEXT:    sd $16, 64($sp) # 8-byte Folded Spill
-; SOFT-FLOAT-64-NEXT:    move $16, $6
-; SOFT-FLOAT-64-NEXT:    move $17, $5
-; SOFT-FLOAT-64-NEXT:    move $18, $4
-; SOFT-FLOAT-64-NEXT:    dmtc1 $7, $f12
-; SOFT-FLOAT-64-NEXT:    dmtc1 $8, $f13
-; SOFT-FLOAT-64-NEXT:    daddiu $6, $sp, 48
-; SOFT-FLOAT-64-NEXT:    jal sincosl
-; SOFT-FLOAT-64-NEXT:    daddiu $7, $sp, 32
-; SOFT-FLOAT-64-NEXT:    dmtc1 $17, $f12
-; SOFT-FLOAT-64-NEXT:    dmtc1 $16, $f13
-; SOFT-FLOAT-64-NEXT:    daddiu $6, $sp, 16
-; SOFT-FLOAT-64-NEXT:    jal sincosl
-; SOFT-FLOAT-64-NEXT:    daddiu $7, $sp, 0
-; SOFT-FLOAT-64-NEXT:    ld $1, 56($sp)
-; SOFT-FLOAT-64-NEXT:    ld $2, 0($sp)
-; SOFT-FLOAT-64-NEXT:    ld $3, 8($sp)
-; SOFT-FLOAT-64-NEXT:    ld $4, 32($sp)
-; SOFT-FLOAT-64-NEXT:    ld $5, 40($sp)
-; SOFT-FLOAT-64-NEXT:    sd $5, 56($18)
-; SOFT-FLOAT-64-NEXT:    sd $4, 48($18)
-; SOFT-FLOAT-64-NEXT:    sd $3, 40($18)
-; SOFT-FLOAT-64-NEXT:    sd $2, 32($18)
-; SOFT-FLOAT-64-NEXT:    sd $1, 24($18)
-; SOFT-FLOAT-64-NEXT:    ld $1, 48($sp)
-; SOFT-FLOAT-64-NEXT:    sd $1, 16($18)
-; SOFT-FLOAT-64-NEXT:    ld $1, 24($sp)
-; SOFT-FLOAT-64-NEXT:    sd $1, 8($18)
-; SOFT-FLOAT-64-NEXT:    ld $1, 16($sp)
-; SOFT-FLOAT-64-NEXT:    sd $1, 0($18)
-; SOFT-FLOAT-64-NEXT:    ld $16, 64($sp) # 8-byte Folded Reload
-; SOFT-FLOAT-64-NEXT:    ld $17, 72($sp) # 8-byte Folded Reload
-; SOFT-FLOAT-64-NEXT:    ld $18, 80($sp) # 8-byte Folded Reload
-; SOFT-FLOAT-64-NEXT:    ld $ra, 88($sp) # 8-byte Folded Reload
-; SOFT-FLOAT-64-NEXT:    jr $ra
-; SOFT-FLOAT-64-NEXT:    daddiu $sp, $sp, 96
-  %result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
-  ret { <2 x fp128>, <2 x fp128> } %result
-}
-
 attributes #0 = { nounwind }

>From 87ff8f315077ffbc0f756ed56238e24e57001d45 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 18 Aug 2026 17:31:26 +0200
Subject: [PATCH 3/3] Add x86_fp80 ldexp/frexp no-libcall error coverage

---
 llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll b/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll
index a2d69cfe20b87..38991855dcb5b 100644
--- a/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll
+++ b/llvm/test/CodeGen/X86/fp80-math-no-libcall-error.ll
@@ -90,3 +90,15 @@ define x86_fp80 @test_log10_finite(x86_fp80 %x) nounwind {
   %r = call nnan ninf x86_fp80 @llvm.log10.f80(x86_fp80 %x)
   ret x86_fp80 %r
 }
+
+; CHECK: error: no libcall available for fldexp
+define x86_fp80 @test_ldexp(x86_fp80 %x, i32 %exp) nounwind {
+  %r = call x86_fp80 @llvm.ldexp.f80.i32(x86_fp80 %x, i32 %exp)
+  ret x86_fp80 %r
+}
+
+; CHECK: error: no libcall available for ffrexp
+define { x86_fp80, i32 } @test_frexp(x86_fp80 %x) nounwind {
+  %r = call { x86_fp80, i32 } @llvm.frexp.f80.i32(x86_fp80 %x)
+  ret { x86_fp80, i32 } %r
+}



More information about the llvm-commits mailing list