[llvm] 2f97ec4 - DAG: Gracefully diagnose missing FMA and ppcf128 expansion libcalls (#228094)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 05:03:46 PDT 2026


Author: Matt Arsenault
Date: 2026-10-02T14:03:38+02:00
New Revision: 2f97ec4d378c9087b69ab0ee6dc6454e15b299f0

URL: https://github.com/llvm/llvm-project/commit/2f97ec4d378c9087b69ab0ee6dc6454e15b299f0
DIFF: https://github.com/llvm/llvm-project/commit/2f97ec4d378c9087b69ab0ee6dc6454e15b299f0.diff

LOG: DAG: Gracefully diagnose missing FMA and ppcf128 expansion libcalls (#228094)

Previously this would hit a fatal error. Legalize to poison and report a proper 
context error.

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

Added: 
    llvm/test/CodeGen/X86/ppcf128-expand-no-libcall-error.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
    llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/test/CodeGen/NVPTX/f128-no-libcall-error.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index b7efd80d93fd4..8c974e461b80c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -26,6 +26,12 @@ using namespace llvm;
 
 #define DEBUG_TYPE "legalize-types"
 
+static void reportNoLibcall(SelectionDAG &DAG, SDNode *N, EVT VT) {
+  DAG.getContext()->emitError(Twine("no libcall available for ") +
+                              N->getOperationName(&DAG) + " with type " +
+                              VT.getEVTString());
+}
+
 /// GetFPLibCall - Return the right libcall for the given floating point type.
 /// FIXME: This is a local version of RTLIB::getFPLibCall that should be
 ///        refactored away (see RTLIB::getPOWI for an example).
@@ -194,8 +200,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
 // No libcall is available to soften this operation. Emit a diagnostic and
 // produce a poison result of the softened type \p NVT.
 SDValue DAGTypeLegalizer::SoftenFloatRes_NoLibcall(SDNode *N, EVT NVT) {
-  DAG.getContext()->emitError(Twine("no libcall available for ") +
-                              N->getOperationName(&DAG));
+  reportNoLibcall(DAG, N, N->getValueType(0));
   if (N->isStrictFPOpcode())
     ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
   return DAG.getPOISON(NVT);
@@ -521,9 +526,12 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FMA(SDNode *N) {
                    N->getOperand(1 + Offset).getValueType(),
                    N->getOperand(2 + Offset).getValueType() };
   CallOptions.setTypeListBeforeSoften(OpsVT, N->getValueType(0));
+  RTLIB::Libcall LC = RTLIB::getFMA(N->getValueType(0));
+  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+  if (LCImpl == RTLIB::Unsupported)
+    return SoftenFloatRes_NoLibcall(N, NVT);
   std::pair<SDValue, SDValue> Tmp =
-      TLI.makeLibCall(DAG, RTLIB::getFMA(N->getValueType(0)), NVT, Ops,
-                      CallOptions, SDLoc(N), Chain);
+      TLI.makeLibCall(DAG, LCImpl, NVT, Ops, CallOptions, SDLoc(N), Chain);
   if (IsStrict)
     ReplaceValueWith(SDValue(N, 1), Tmp.second);
   return Tmp.first;
@@ -712,8 +720,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
   SDLoc DL(N);
 
   if (LCImpl == RTLIB::Unsupported) {
-    DAG.getContext()->emitError(Twine("no libcall available for ") +
-                                N->getOperationName(&DAG));
+    reportNoLibcall(DAG, N, VT0);
     SDValue PoisonExp = DAG.getPOISON(VT1);
     ReplaceValueWith(SDValue(N, 1), PoisonExp);
     return DAG.getMergeValues({DAG.getPOISON(NVT0), PoisonExp}, DL);
@@ -1157,8 +1164,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
   RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
   if (LCImpl == RTLIB::Unsupported) {
-    DAG.getContext()->emitError(Twine("no libcall available for ") +
-                                N->getOperationName(&DAG));
+    reportNoLibcall(DAG, N, SVT);
     SDValue Poison = DAG.getPOISON(RVT);
     if (IsStrict) {
       ReplaceValueWith(SDValue(N, 1), Chain);
@@ -1244,8 +1250,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT(SDNode *N) {
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
   RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
   if (LCImpl == RTLIB::Unsupported) {
-    DAG.getContext()->emitError(Twine("no libcall available for ") +
-                                N->getOperationName(&DAG));
+    reportNoLibcall(DAG, N, SVT);
     SDValue Poison = DAG.getPOISON(RVT);
     if (IsStrict) {
       ReplaceValueWith(SDValue(N, 1), Chain);
@@ -1416,8 +1421,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_Unary(SDNode *N, RTLIB::Libcall LC) {
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
   RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
   if (LCImpl == RTLIB::Unsupported) {
-    DAG.getContext()->emitError(Twine("no libcall available for ") +
-                                N->getOperationName(&DAG));
+    reportNoLibcall(DAG, N, N->getOperand(0 + Offset).getValueType());
     SDValue Poison = DAG.getPOISON(N->getValueType(0));
     if (IsStrict) {
       ReplaceValueWith(SDValue(N, 1), Chain);
@@ -1646,16 +1650,28 @@ void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
   Hi = DAG.getConstantFP(APFloat(Sem, C.extractBits(64, 0)), dl, NVT);
 }
 
+// Diagnose a missing libcall and produce a poison expanded pair.
+void DAGTypeLegalizer::ExpandFloatRes_NoLibcall(SDNode *N, SDValue &Lo,
+                                                SDValue &Hi) {
+  reportNoLibcall(DAG, N, N->getValueType(0));
+  if (N->isStrictFPOpcode())
+    ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
+  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+  Lo = Hi = DAG.getPOISON(NVT);
+}
+
 void DAGTypeLegalizer::ExpandFloatRes_Unary(SDNode *N, RTLIB::Libcall LC,
                                             SDValue &Lo, SDValue &Hi) {
   bool IsStrict = N->isStrictFPOpcode();
   unsigned Offset = IsStrict ? 1 : 0;
   SDValue Op = N->getOperand(0 + Offset);
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+  if (LCImpl == RTLIB::Unsupported)
+    return ExpandFloatRes_NoLibcall(N, Lo, Hi);
   TargetLowering::MakeLibCallOptions CallOptions;
-  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, N->getValueType(0),
-                                                    Op, CallOptions, SDLoc(N),
-                                                    Chain);
+  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
+      DAG, LCImpl, N->getValueType(0), Op, CallOptions, SDLoc(N), Chain);
   if (IsStrict)
     ReplaceValueWith(SDValue(N, 1), Tmp.second);
   GetPairElements(Tmp.first, Lo, Hi);
@@ -1667,10 +1683,12 @@ void DAGTypeLegalizer::ExpandFloatRes_Binary(SDNode *N, RTLIB::Libcall LC,
   unsigned Offset = IsStrict ? 1 : 0;
   SDValue Ops[] = { N->getOperand(0 + Offset), N->getOperand(1 + Offset) };
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+  if (LCImpl == RTLIB::Unsupported)
+    return ExpandFloatRes_NoLibcall(N, Lo, Hi);
   TargetLowering::MakeLibCallOptions CallOptions;
-  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(DAG, LC, N->getValueType(0),
-                                                    Ops, CallOptions, SDLoc(N),
-                                                    Chain);
+  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
+      DAG, LCImpl, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain);
   if (IsStrict)
     ReplaceValueWith(SDValue(N, 1), Tmp.second);
   GetPairElements(Tmp.first, Lo, Hi);
@@ -1694,7 +1712,14 @@ void DAGTypeLegalizer::ExpandFloatRes_UnaryWithTwoFPResults(
     SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
   assert(!N->isStrictFPOpcode() && "strictfp not implemented");
   SmallVector<SDValue> Results;
-  TLI.expandMultipleResultFPLibCall(DAG, LC, N, Results, CallRetResNo);
+  if (!TLI.expandMultipleResultFPLibCall(DAG, LC, N, Results, CallRetResNo)) {
+    reportNoLibcall(DAG, N, N->getValueType(0));
+    EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+    SDValue Poison = DAG.getPOISON(NVT);
+    for (unsigned ResNo = 0, E = N->getNumValues(); ResNo != E; ++ResNo)
+      SetExpandedFloat(SDValue(N, ResNo), Poison, Poison);
+    return;
+  }
   for (auto [ResNo, Res] : enumerate(Results)) {
     SDValue Lo, Hi;
     GetPairElements(Res, Lo, Hi);
@@ -1841,10 +1866,13 @@ void DAGTypeLegalizer::ExpandFloatRes_FMA(SDNode *N, SDValue &Lo,
   SDValue Ops[3] = { N->getOperand(0 + Offset), N->getOperand(1 + Offset),
                      N->getOperand(2 + Offset) };
   SDValue Chain = IsStrict ? N->getOperand(0) : SDValue();
+  RTLIB::Libcall LC = RTLIB::getFMA(N->getValueType(0));
+  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+  if (LCImpl == RTLIB::Unsupported)
+    return ExpandFloatRes_NoLibcall(N, Lo, Hi);
   TargetLowering::MakeLibCallOptions CallOptions;
-  std::pair<SDValue, SDValue> Tmp =
-      TLI.makeLibCall(DAG, RTLIB::getFMA(N->getValueType(0)),
-                      N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain);
+  std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
+      DAG, LCImpl, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain);
   if (IsStrict)
     ReplaceValueWith(SDValue(N, 1), Tmp.second);
   GetPairElements(Tmp.first, Lo, Hi);
@@ -2066,10 +2094,14 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
     }
     assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
 
+    RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+    if (LCImpl == RTLIB::Unsupported)
+      return ExpandFloatRes_NoLibcall(N, Lo, Hi);
+
     TargetLowering::MakeLibCallOptions CallOptions;
     CallOptions.setIsSigned(true);
     std::pair<SDValue, SDValue> Tmp =
-        TLI.makeLibCall(DAG, LC, VT, Src, CallOptions, dl, Chain);
+        TLI.makeLibCall(DAG, LCImpl, VT, Src, CallOptions, dl, Chain);
     if (Strict)
       Chain = Tmp.second;
     GetPairElements(Tmp.first, Lo, Hi);
@@ -2301,9 +2333,20 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_XINT(SDNode *N) {
   RTLIB::Libcall LC = findFPToIntLibcall(Op.getValueType(), RVT, NVT, Signed);
   assert(LC != RTLIB::UNKNOWN_LIBCALL && NVT.isSimple() &&
          "Unsupported FP_TO_XINT!");
+  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+  if (LCImpl == RTLIB::Unsupported) {
+    reportNoLibcall(DAG, N, Op.getValueType());
+    SDValue Poison = DAG.getPOISON(RVT);
+    if (IsStrict) {
+      ReplaceValueWith(SDValue(N, 1), Chain);
+      ReplaceValueWith(SDValue(N, 0), Poison);
+      return SDValue();
+    }
+    return Poison;
+  }
   TargetLowering::MakeLibCallOptions CallOptions;
   std::pair<SDValue, SDValue> Tmp =
-      TLI.makeLibCall(DAG, LC, NVT, Op, CallOptions, dl, Chain);
+      TLI.makeLibCall(DAG, LCImpl, NVT, Op, CallOptions, dl, Chain);
   if (!IsStrict)
     return Tmp.first;
 
@@ -2382,8 +2425,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_XRINT_XROUND(SDNode *N,
   EVT RVT = N->getValueType(0);
   RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
   if (LCImpl == RTLIB::Unsupported) {
-    DAG.getContext()->emitError(Twine("no libcall available for ") +
-                                N->getOperationName(&DAG));
+    reportNoLibcall(DAG, N, N->getOperand(0).getValueType());
     return DAG.getPOISON(RVT);
   }
 

diff  --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 187f7ecb806b2..7dfc4c1330eca 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -670,6 +670,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   // Float Result Expansion.
   void ExpandFloatResult(SDNode *N, unsigned ResNo);
   void ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, SDValue &Hi);
+  void ExpandFloatRes_NoLibcall(SDNode *N, SDValue &Lo, SDValue &Hi);
   void ExpandFloatRes_Unary(SDNode *N, RTLIB::Libcall LC,
                             SDValue &Lo, SDValue &Hi);
   void ExpandFloatRes_Binary(SDNode *N, RTLIB::Libcall LC,

diff  --git a/llvm/test/CodeGen/NVPTX/f128-no-libcall-error.ll b/llvm/test/CodeGen/NVPTX/f128-no-libcall-error.ll
index d3286a0bf0391..506056536aca5 100644
--- a/llvm/test/CodeGen/NVPTX/f128-no-libcall-error.ll
+++ b/llvm/test/CodeGen/NVPTX/f128-no-libcall-error.ll
@@ -4,31 +4,43 @@
 ; available. Make sure they emit a proper diagnostic rather than fatal erroring
 ; in makeLibCall.
 
-; CHECK: error: no libcall available for fexp10
+; CHECK: error: no libcall available for fexp10 with type f128
 define fp128 @test_exp10(fp128 %x) nounwind {
   %r = call fp128 @llvm.exp10.f128(fp128 %x)
   ret fp128 %r
 }
 
-; CHECK: error: no libcall available for fmaximum
+; CHECK: error: no libcall available for fmaximum with type f128
 define fp128 @test_maximum(fp128 %x, fp128 %y) nounwind {
   %r = call fp128 @llvm.maximum.f128(fp128 %x, fp128 %y)
   ret fp128 %r
 }
 
-; CHECK: error: no libcall available for ffrexp
+; CHECK: error: no libcall available for fma with type f128
+define fp128 @test_fma(fp128 %x, fp128 %y, fp128 %z) nounwind {
+  %r = call fp128 @llvm.fma.f128(fp128 %x, fp128 %y, fp128 %z)
+  ret fp128 %r
+}
+
+; CHECK: error: no libcall available for strict_fma with type f128
+define fp128 @test_strict_fma(fp128 %x, fp128 %y, fp128 %z) nounwind strictfp {
+  %r = call fp128 @llvm.experimental.constrained.fma.f128(fp128 %x, fp128 %y, fp128 %z, metadata !"round.tonearest", metadata !"fpexcept.strict")
+  ret fp128 %r
+}
+
+; CHECK: error: no libcall available for ffrexp with type f128
 define { fp128, i32 } @test_frexp(fp128 %x) nounwind {
   %r = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %x)
   ret { fp128, i32 } %r
 }
 
-; CHECK: error: no libcall available for lrint
+; CHECK: error: no libcall available for lrint with type f128
 define i32 @test_lrint(fp128 %x) nounwind {
   %r = call i32 @llvm.lrint.i32.f128(fp128 %x)
   ret i32 %r
 }
 
-; CHECK: error: no libcall available for strict_fadd
+; CHECK: error: no libcall available for strict_fadd with type f128
 define fp128 @test_strict_fadd(fp128 %x, fp128 %y) nounwind strictfp {
   %r = call fp128 @llvm.experimental.constrained.fadd.f128(fp128 %x, fp128 %y, metadata !"round.tonearest", metadata !"fpexcept.strict")
   ret fp128 %r

diff  --git a/llvm/test/CodeGen/X86/ppcf128-expand-no-libcall-error.ll b/llvm/test/CodeGen/X86/ppcf128-expand-no-libcall-error.ll
new file mode 100644
index 0000000000000..f94b8737692f7
--- /dev/null
+++ b/llvm/test/CodeGen/X86/ppcf128-expand-no-libcall-error.ll
@@ -0,0 +1,100 @@
+; RUN: not llc -mtriple=x86_64-unknown-unknown -filetype=null %s 2>&1 | FileCheck %s
+
+; x86 expands ppc_fp128 but has no ppc_fp128 runtime library, so these
+; operations should diagnose a missing libcall rather than crash.
+
+; CHECK: error: no libcall available for fsqrt with type ppcf128
+define ppc_fp128 @test_sqrt(ppc_fp128 %x) nounwind {
+  %r = call ppc_fp128 @llvm.sqrt.ppcf128(ppc_fp128 %x)
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for fpow with type ppcf128
+define ppc_fp128 @test_pow(ppc_fp128 %x, ppc_fp128 %y) nounwind {
+  %r = call ppc_fp128 @llvm.pow.ppcf128(ppc_fp128 %x, ppc_fp128 %y)
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for fma with type ppcf128
+define ppc_fp128 @test_fma(ppc_fp128 %x, ppc_fp128 %y, ppc_fp128 %z) nounwind {
+  %r = call ppc_fp128 @llvm.fma.ppcf128(ppc_fp128 %x, ppc_fp128 %y, ppc_fp128 %z)
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for fldexp with type ppcf128
+define ppc_fp128 @test_ldexp(ppc_fp128 %x, i32 %y) nounwind {
+  %r = call ppc_fp128 @llvm.ldexp.ppcf128.i32(ppc_fp128 %x, i32 %y)
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for fpowi with type ppcf128
+define ppc_fp128 @test_powi(ppc_fp128 %x, i32 %y) nounwind {
+  %r = call ppc_fp128 @llvm.powi.ppcf128.i32(ppc_fp128 %x, i32 %y)
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for strict_fldexp with type ppcf128
+define ppc_fp128 @test_strict_ldexp(ppc_fp128 %x, i32 %y) nounwind strictfp {
+  %r = call ppc_fp128 @llvm.experimental.constrained.ldexp.ppcf128.i32(ppc_fp128 %x, i32 %y, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for frem with type ppcf128
+define ppc_fp128 @test_frem(ppc_fp128 %x, ppc_fp128 %y) nounwind {
+  %r = frem ppc_fp128 %x, %y
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for sint_to_fp with type ppcf128
+define ppc_fp128 @test_sitofp(i64 %x) nounwind {
+  %r = sitofp i64 %x to ppc_fp128
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for fp_to_sint with type ppcf128
+define i64 @test_fptosi(ppc_fp128 %x) nounwind {
+  %r = fptosi ppc_fp128 %x to i64
+  ret i64 %r
+}
+
+; CHECK: error: no libcall available for fsincos with type ppcf128
+define { ppc_fp128, ppc_fp128 } @test_sincos(ppc_fp128 %x) nounwind {
+  %r = call { ppc_fp128, ppc_fp128 } @llvm.sincos.ppcf128(ppc_fp128 %x)
+  ret { ppc_fp128, ppc_fp128 } %r
+}
+
+; CHECK: error: no libcall available for fmodf with type ppcf128
+define { ppc_fp128, ppc_fp128 } @test_modf(ppc_fp128 %x) nounwind {
+  %r = call { ppc_fp128, ppc_fp128 } @llvm.modf.ppcf128(ppc_fp128 %x)
+  ret { ppc_fp128, ppc_fp128 } %r
+}
+
+; CHECK: error: no libcall available for strict_fsqrt with type ppcf128
+define ppc_fp128 @test_strict_sqrt(ppc_fp128 %x) nounwind strictfp {
+  %r = call ppc_fp128 @llvm.experimental.constrained.sqrt.ppcf128(ppc_fp128 %x, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for strict_fadd with type ppcf128
+define ppc_fp128 @test_strict_fadd(ppc_fp128 %x, ppc_fp128 %y) nounwind strictfp {
+  %r = call ppc_fp128 @llvm.experimental.constrained.fadd.ppcf128(ppc_fp128 %x, ppc_fp128 %y, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for strict_fma with type ppcf128
+define ppc_fp128 @test_strict_fma(ppc_fp128 %x, ppc_fp128 %y, ppc_fp128 %z) nounwind strictfp {
+  %r = call ppc_fp128 @llvm.experimental.constrained.fma.ppcf128(ppc_fp128 %x, ppc_fp128 %y, ppc_fp128 %z, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for strict_sint_to_fp with type ppcf128
+define ppc_fp128 @test_strict_sitofp(i64 %x) nounwind strictfp {
+  %r = call ppc_fp128 @llvm.experimental.constrained.sitofp.ppcf128.i64(i64 %x, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret ppc_fp128 %r
+}
+
+; CHECK: error: no libcall available for strict_fp_to_sint with type ppcf128
+define i64 @test_strict_fptosi(ppc_fp128 %x) nounwind strictfp {
+  %r = call i64 @llvm.experimental.constrained.fptosi.i64.ppcf128(ppc_fp128 %x, metadata !"fpexcept.strict")
+  ret i64 %r
+}


        


More information about the llvm-commits mailing list