[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