[llvm] 5c38ca1 - DAG: Gracefully diagnose missing floating-point state libcalls (#228426)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 2 09:45:53 PDT 2026
Author: Matt Arsenault
Date: 2026-10-02T16:45:46Z
New Revision: 5c38ca153312ea29871fcdd89a0a9ec678c9fb72
URL: https://github.com/llvm/llvm-project/commit/5c38ca153312ea29871fcdd89a0a9ec678c9fb72
DIFF: https://github.com/llvm/llvm-project/commit/5c38ca153312ea29871fcdd89a0a9ec678c9fb72.diff
LOG: DAG: Gracefully diagnose missing floating-point state libcalls (#228426)
Previously makeStateFunctionCall would hit a fatal error if the target has no
fegetenv/fesetenv/fegetmode/fesetmode implementation. Report a proper
context error and emit nothing.
Co-authored-by: Claude Opus 5 <noreply at anthropic.com>
Added:
llvm/test/CodeGen/NVPTX/fenv-no-libcall-error.ll
Modified:
llvm/include/llvm/CodeGen/SelectionDAG.h
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index 764858702b732..a345c90ae9c0a 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -2757,7 +2757,7 @@ class SelectionDAG {
}
LLVM_ABI SDValue makeStateFunctionCall(unsigned LibFunc, SDValue Ptr,
- SDValue InChain, const SDLoc &DLoc);
+ SDValue InChain, SDNode *Node);
/// Returns the maximum runtime number of elements in VT if known, or 0
/// otherwise.
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 15d82359e8682..d8e5e23e21337 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -5350,21 +5350,21 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
SDValue Ptr = DAG.getAllOnesConstant(dl, PtrTy);
SDValue Chain = Node->getOperand(0);
Results.push_back(
- DAG.makeStateFunctionCall(RTLIB::FESETENV, Ptr, Chain, dl));
+ DAG.makeStateFunctionCall(RTLIB::FESETENV, Ptr, Chain, Node));
break;
}
case ISD::GET_FPENV_MEM: {
SDValue Chain = Node->getOperand(0);
SDValue EnvPtr = Node->getOperand(1);
Results.push_back(
- DAG.makeStateFunctionCall(RTLIB::FEGETENV, EnvPtr, Chain, dl));
+ DAG.makeStateFunctionCall(RTLIB::FEGETENV, EnvPtr, Chain, Node));
break;
}
case ISD::SET_FPENV_MEM: {
SDValue Chain = Node->getOperand(0);
SDValue EnvPtr = Node->getOperand(1);
Results.push_back(
- DAG.makeStateFunctionCall(RTLIB::FESETENV, EnvPtr, Chain, dl));
+ DAG.makeStateFunctionCall(RTLIB::FESETENV, EnvPtr, Chain, Node));
break;
}
case ISD::GET_FPMODE: {
@@ -5374,7 +5374,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
SDValue StackPtr = DAG.CreateStackTemporary(ModeVT);
int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
SDValue Chain = DAG.makeStateFunctionCall(RTLIB::FEGETMODE, StackPtr,
- Node->getOperand(0), dl);
+ Node->getOperand(0), Node);
SDValue LdInst = DAG.getLoad(
ModeVT, dl, Chain, StackPtr,
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI));
@@ -5393,7 +5393,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
Node->getOperand(0), dl, Mode, StackPtr,
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI));
Results.push_back(
- DAG.makeStateFunctionCall(RTLIB::FESETMODE, StackPtr, StInst, dl));
+ DAG.makeStateFunctionCall(RTLIB::FESETMODE, StackPtr, StInst, Node));
break;
}
case ISD::RESET_FPMODE: {
@@ -5404,7 +5404,7 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
EVT PtrTy = TLI.getPointerTy(DL);
SDValue Mode = DAG.getAllOnesConstant(dl, PtrTy);
Results.push_back(DAG.makeStateFunctionCall(RTLIB::FESETMODE, Mode,
- Node->getOperand(0), dl));
+ Node->getOperand(0), Node));
break;
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index abc8172fb67b5..48aaeca8e80a8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -15232,24 +15232,28 @@ SDValue SelectionDAG::getPartialReduceMLS(unsigned Opc, const SDLoc &DL,
/// \param LibFunc Reference to library function (value of RTLIB::Libcall).
/// \param Ptr Pointer used to save/load state.
/// \param InChain Ingoing token chain.
+/// \param Node Node being legalized
/// \returns Outgoing chain token.
SDValue SelectionDAG::makeStateFunctionCall(unsigned LibFunc, SDValue Ptr,
- SDValue InChain,
- const SDLoc &DLoc) {
+ SDValue InChain, SDNode *Node) {
assert(InChain.getValueType() == MVT::Other && "Expected token chain");
- TargetLowering::ArgListTy Args;
- Args.emplace_back(Ptr, Ptr.getValueType().getTypeForEVT(*getContext()));
RTLIB::LibcallImpl LibcallImpl =
Libcalls->getLibcallImpl(static_cast<RTLIB::Libcall>(LibFunc));
- if (LibcallImpl == RTLIB::Unsupported)
- reportFatalUsageError("emitting call to unsupported libcall");
+ if (LibcallImpl == RTLIB::Unsupported) {
+ getContext()->emitError(Twine("no libcall available for ") +
+ Node->getOperationName(this));
+ return InChain;
+ }
+ TargetLowering::ArgListTy Args;
+ Args.emplace_back(Ptr, Ptr.getValueType().getTypeForEVT(*getContext()));
SDValue Callee =
getExternalSymbol(LibcallImpl, TLI->getPointerTy(getDataLayout()));
TargetLowering::CallLoweringInfo CLI(*this);
- CLI.setDebugLoc(DLoc).setChain(InChain).setLibCallee(
- Libcalls->getLibcallImplCallingConv(LibcallImpl),
- Type::getVoidTy(*getContext()), Callee, std::move(Args));
+ CLI.setDebugLoc(SDLoc(Node))
+ .setChain(InChain)
+ .setLibCallee(Libcalls->getLibcallImplCallingConv(LibcallImpl),
+ Type::getVoidTy(*getContext()), Callee, std::move(Args));
return TLI->LowerCallTo(CLI).second;
}
diff --git a/llvm/test/CodeGen/NVPTX/fenv-no-libcall-error.ll b/llvm/test/CodeGen/NVPTX/fenv-no-libcall-error.ll
new file mode 100644
index 0000000000000..163926b03d56d
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/fenv-no-libcall-error.ll
@@ -0,0 +1,41 @@
+; RUN: not llc -mtriple=nvptx64 -filetype=null %s 2>&1 | FileCheck %s
+
+; NVPTX has no fenv library, so these operations have no libcall
+; available. Make sure they emit a diagnostic and do not fatally
+; error.
+
+; CHECK: error: no libcall available for reset_fpenv
+define void @test_reset_fpenv() nounwind {
+ call void @llvm.reset.fpenv()
+ ret void
+}
+
+; CHECK: error: no libcall available for get_fpenv_mem
+define i256 @test_get_fpenv() nounwind {
+ %e = call i256 @llvm.get.fpenv.i256()
+ ret i256 %e
+}
+
+; CHECK: error: no libcall available for set_fpenv_mem
+define void @test_set_fpenv(i256 %e) nounwind {
+ call void @llvm.set.fpenv.i256(i256 %e)
+ ret void
+}
+
+; CHECK: error: no libcall available for get_fpmode
+define i32 @test_get_fpmode() nounwind {
+ %m = call i32 @llvm.get.fpmode.i32()
+ ret i32 %m
+}
+
+; CHECK: error: no libcall available for set_fpmode
+define void @test_set_fpmode(i32 %m) nounwind {
+ call void @llvm.set.fpmode.i32(i32 %m)
+ ret void
+}
+
+; CHECK: error: no libcall available for reset_fpmode
+define void @test_reset_fpmode() nounwind {
+ call void @llvm.reset.fpmode()
+ ret void
+}
More information about the llvm-commits
mailing list