[llvm] 58f94bc - DAG: Gracefully diagnose missing fp128 ldexp/frexp libcalls (#215626)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 02:13:29 PDT 2026


Author: Matt Arsenault
Date: 2026-08-12T11:13:24+02:00
New Revision: 58f94bcc789167e659f7059a0836da7ae6ae5795

URL: https://github.com/llvm/llvm-project/commit/58f94bcc789167e659f7059a0836da7ae6ae5795
DIFF: https://github.com/llvm/llvm-project/commit/58f94bcc789167e659f7059a0836da7ae6ae5795.diff

LOG: DAG: Gracefully diagnose missing fp128 ldexp/frexp libcalls (#215626)

When the fp128 ldexp/frexp libcall is unavailable (e.g. MSVC),
LegalizeDAG crashed instead of emitting a diagnostic. The expansion
path introduces a cast to an integer type, so we can't introduce that
wide integer if it's not legal at this point.

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

Added: 
    llvm/test/CodeGen/X86/fp128-ldexp-frexp-no-libcall-error.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index e86d83a72ba75..9f58ee4024c3a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2568,6 +2568,12 @@ SDValue SelectionDAGLegalize::expandLdexp(SDNode *Node) const {
   if (AsIntVT == EVT()) // TODO: How to handle f80?
     return SDValue();
 
+  // The expansion works through the integer-equivalent type; if that is not
+  // legal, bail out and let the caller use a libcall (or diagnose a missing
+  // one).
+  if (!TLI.isTypeLegal(AsIntVT))
+    return SDValue();
+
   if (Node->getOpcode() == ISD::STRICT_FLDEXP) // TODO
     return SDValue();
 
@@ -2679,6 +2685,12 @@ SDValue SelectionDAGLegalize::expandFrexp(SDNode *Node) const {
   if (AsIntVT == EVT()) // TODO: How to handle f80?
     return SDValue();
 
+  // The expansion works through the integer-equivalent type; if that is not
+  // legal, bail out and let the caller use a libcall (or diagnose a missing
+  // one).
+  if (!TLI.isTypeLegal(AsIntVT))
+    return SDValue();
+
   const fltSemantics &FltSem = VT.getFltSemantics();
   const APFloat::ExponentType MinExpVal = APFloat::semanticsMinExponent(FltSem);
   const unsigned Precision = APFloat::semanticsPrecision(FltSem);
@@ -5060,8 +5072,12 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
                                                         : RTLIB::getFREXP(VT);
     bool Expanded = TLI.expandMultipleResultFPLibCall(DAG, LC, Node, Results,
                                                       /*CallRetResNo=*/0);
-    if (!Expanded)
-      llvm_unreachable("Expected scalar FFREXP/FMODF to expand to libcall!");
+    if (!Expanded) {
+      DAG.getContext()->emitError(Twine("no libcall available for ") +
+                                  Node->getOperationName(&DAG));
+      for (unsigned I = 0, E = Node->getNumValues(); I != E; ++I)
+        Results.push_back(DAG.getPOISON(Node->getValueType(I)));
+    }
     break;
   }
   case ISD::FPOWI:

diff  --git a/llvm/test/CodeGen/X86/fp128-ldexp-frexp-no-libcall-error.ll b/llvm/test/CodeGen/X86/fp128-ldexp-frexp-no-libcall-error.ll
new file mode 100644
index 0000000000000..e156583c96631
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp128-ldexp-frexp-no-libcall-error.ll
@@ -0,0 +1,17 @@
+; RUN: not llc -mtriple=x86_64-pc-windows-msvc -filetype=null %s 2>&1 | FileCheck %s
+
+; The Windows math runtime has no fp128 ldexpl/frexpl. fp128 is a legal type on
+; x86-64 while i128 is not, so the generic software expansion cannot run;
+; legalization must diagnose the missing libcall instead of crashing.
+
+; CHECK: error: no libcall available for fldexp
+define fp128 @test_ldexp_f128_i32(fp128 %val, i32 %a) {
+  %call = call fp128 @llvm.ldexp.f128.i32(fp128 %val, i32 %a)
+  ret fp128 %call
+}
+
+; CHECK: error: no libcall available for ffrexp
+define { fp128, i32 } @test_frexp_f128_i32(fp128 %a) {
+  %result = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %a)
+  ret { fp128, i32 } %result
+}


        


More information about the llvm-commits mailing list