[llvm] f4f973e - RuntimeLibcalls: Split soft-float three-way compares into distinct libcall kinds (#211617)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 5 04:30:16 PDT 2026
Author: Matt Arsenault
Date: 2026-08-05T13:30:10+02:00
New Revision: f4f973e3cdf8076209d462ae918dfd9299b741f4
URL: https://github.com/llvm/llvm-project/commit/f4f973e3cdf8076209d462ae918dfd9299b741f4
DIFF: https://github.com/llvm/llvm-project/commit/f4f973e3cdf8076209d462ae918dfd9299b741f4.diff
LOG: RuntimeLibcalls: Split soft-float three-way compares into distinct libcall kinds (#211617)
Added:
Modified:
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/include/llvm/IR/RuntimeLibcalls.td
llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/lib/CodeGen/TargetLoweringBase.cpp
llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
llvm/lib/Target/ARM/ARMSubtarget.cpp
llvm/lib/Target/MSP430/MSP430Subtarget.cpp
llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index c663bb8ea65b7..f18a3362d4af7 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3734,11 +3734,6 @@ class LLVM_ABI TargetLoweringBase {
return RuntimeLibcallInfo.getSupportedLibcallImpl(FuncName);
}
- /// Get the comparison predicate that's to be used to test the result of the
- /// comparison libcall against zero. This should only be used with
- /// floating-point compare libcalls.
- ISD::CondCode getSoftFloatCmpLibcallPredicate(RTLIB::LibcallImpl Call) const;
-
/// Get the CallingConv that should be used for the specified libcall
/// implementation.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const {
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 74c51391aad2d..19b32fe029799 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -479,7 +479,11 @@ def UINTTOFP_I128_PPCF128 : RuntimeLibcall;
def CONVERT_F128_PPCF128 : RuntimeLibcall;
def CONVERT_PPCF128_F128 : RuntimeLibcall;
-// Comparisons
+// Comparisons.
+//
+// The O*_F* and UO_F* libcalls return a simple 0/1 boolean value.
+//
+// The FCMP3_PRED_*_F* libcalls return a three-way (-1/0/1) result.
foreach FPTy = ["F32", "F64", "F128", "PPCF128"] in {
def OEQ_#FPTy : RuntimeLibcall;
def UNE_#FPTy : RuntimeLibcall;
@@ -488,6 +492,13 @@ foreach FPTy = ["F32", "F64", "F128", "PPCF128"] in {
def OLE_#FPTy : RuntimeLibcall;
def OGT_#FPTy : RuntimeLibcall;
def UO_#FPTy : RuntimeLibcall;
+
+ def FCMP3_PRED_OEQ_#FPTy : RuntimeLibcall;
+ def FCMP3_PRED_UNE_#FPTy : RuntimeLibcall;
+ def FCMP3_PRED_OGE_#FPTy : RuntimeLibcall;
+ def FCMP3_PRED_OLT_#FPTy : RuntimeLibcall;
+ def FCMP3_PRED_OLE_#FPTy : RuntimeLibcall;
+ def FCMP3_PRED_OGT_#FPTy : RuntimeLibcall;
}
// Memory
@@ -1214,31 +1225,32 @@ def __floatuntitf_ppcf128 : RuntimeLibcallImpl<UINTTOFP_I128_PPCF128, "__floatun
def __extendkftf2 : RuntimeLibcallImpl<CONVERT_F128_PPCF128>;
def __trunctfkf2 : RuntimeLibcallImpl<CONVERT_PPCF128_F128>;
-// Comparison
-def __eqsf2 : RuntimeLibcallImpl<OEQ_F32>;
-def __eqdf2 : RuntimeLibcallImpl<OEQ_F64>;
-def __eqtf2 : RuntimeLibcallImpl<OEQ_F128>;
-def __gcc_qeq : RuntimeLibcallImpl<OEQ_PPCF128>;
-def __nesf2 : RuntimeLibcallImpl<UNE_F32>;
-def __nedf2 : RuntimeLibcallImpl<UNE_F64>;
-def __netf2 : RuntimeLibcallImpl<UNE_F128>;
-def __gcc_qne : RuntimeLibcallImpl<UNE_PPCF128>;
-def __gesf2 : RuntimeLibcallImpl<OGE_F32>;
-def __gedf2 : RuntimeLibcallImpl<OGE_F64>;
-def __getf2 : RuntimeLibcallImpl<OGE_F128>;
-def __gcc_qge : RuntimeLibcallImpl<OGE_PPCF128>;
-def __ltsf2 : RuntimeLibcallImpl<OLT_F32>;
-def __ltdf2 : RuntimeLibcallImpl<OLT_F64>;
-def __lttf2 : RuntimeLibcallImpl<OLT_F128>;
-def __gcc_qlt : RuntimeLibcallImpl<OLT_PPCF128>;
-def __lesf2 : RuntimeLibcallImpl<OLE_F32>;
-def __ledf2 : RuntimeLibcallImpl<OLE_F64>;
-def __letf2 : RuntimeLibcallImpl<OLE_F128>;
-def __gcc_qle : RuntimeLibcallImpl<OLE_PPCF128>;
-def __gtsf2 : RuntimeLibcallImpl<OGT_F32>;
-def __gtdf2 : RuntimeLibcallImpl<OGT_F64>;
-def __gttf2 : RuntimeLibcallImpl<OGT_F128>;
-def __gcc_qgt : RuntimeLibcallImpl<OGT_PPCF128>;
+// Comparison. These return a three-way -1/0/1 result (FCMP3_PRED_*_F*), not a
+// boolean.
+def __eqsf2 : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F32>;
+def __eqdf2 : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F64>;
+def __eqtf2 : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F128>;
+def __gcc_qeq : RuntimeLibcallImpl<FCMP3_PRED_OEQ_PPCF128>;
+def __nesf2 : RuntimeLibcallImpl<FCMP3_PRED_UNE_F32>;
+def __nedf2 : RuntimeLibcallImpl<FCMP3_PRED_UNE_F64>;
+def __netf2 : RuntimeLibcallImpl<FCMP3_PRED_UNE_F128>;
+def __gcc_qne : RuntimeLibcallImpl<FCMP3_PRED_UNE_PPCF128>;
+def __gesf2 : RuntimeLibcallImpl<FCMP3_PRED_OGE_F32>;
+def __gedf2 : RuntimeLibcallImpl<FCMP3_PRED_OGE_F64>;
+def __getf2 : RuntimeLibcallImpl<FCMP3_PRED_OGE_F128>;
+def __gcc_qge : RuntimeLibcallImpl<FCMP3_PRED_OGE_PPCF128>;
+def __ltsf2 : RuntimeLibcallImpl<FCMP3_PRED_OLT_F32>;
+def __ltdf2 : RuntimeLibcallImpl<FCMP3_PRED_OLT_F64>;
+def __lttf2 : RuntimeLibcallImpl<FCMP3_PRED_OLT_F128>;
+def __gcc_qlt : RuntimeLibcallImpl<FCMP3_PRED_OLT_PPCF128>;
+def __lesf2 : RuntimeLibcallImpl<FCMP3_PRED_OLE_F32>;
+def __ledf2 : RuntimeLibcallImpl<FCMP3_PRED_OLE_F64>;
+def __letf2 : RuntimeLibcallImpl<FCMP3_PRED_OLE_F128>;
+def __gcc_qle : RuntimeLibcallImpl<FCMP3_PRED_OLE_PPCF128>;
+def __gtsf2 : RuntimeLibcallImpl<FCMP3_PRED_OGT_F32>;
+def __gtdf2 : RuntimeLibcallImpl<FCMP3_PRED_OGT_F64>;
+def __gttf2 : RuntimeLibcallImpl<FCMP3_PRED_OGT_F128>;
+def __gcc_qgt : RuntimeLibcallImpl<FCMP3_PRED_OGT_PPCF128>;
def __unordsf2 : RuntimeLibcallImpl<UO_F32>;
def __unorddf2 : RuntimeLibcallImpl<UO_F64>;
def __unordtf2 : RuntimeLibcallImpl<UO_F128>;
@@ -2782,8 +2794,8 @@ def __mips16_adddf3 : RuntimeLibcallImpl<ADD_F64>;
def __mips16_addsf3 : RuntimeLibcallImpl<ADD_F32>;
def __mips16_divdf3 : RuntimeLibcallImpl<DIV_F64>;
def __mips16_divsf3 : RuntimeLibcallImpl<DIV_F32>;
-def __mips16_eqdf2 : RuntimeLibcallImpl<OEQ_F64>;
-def __mips16_eqsf2 : RuntimeLibcallImpl<OEQ_F32>;
+def __mips16_eqdf2 : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F64>;
+def __mips16_eqsf2 : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F32>;
def __mips16_extendsfdf2 : RuntimeLibcallImpl<FPEXT_F32_F64>;
def __mips16_fix_truncdfsi : RuntimeLibcallImpl<FPTOSINT_F64_I32>;
def __mips16_fix_truncsfsi : RuntimeLibcallImpl<FPTOSINT_F32_I32>;
@@ -2791,18 +2803,18 @@ def __mips16_floatsidf : RuntimeLibcallImpl<SINTTOFP_I32_F64>;
def __mips16_floatsisf : RuntimeLibcallImpl<SINTTOFP_I32_F32>;
def __mips16_floatunsidf : RuntimeLibcallImpl<UINTTOFP_I32_F64>;
def __mips16_floatunsisf : RuntimeLibcallImpl<UINTTOFP_I32_F32>;
-def __mips16_gedf2 : RuntimeLibcallImpl<OGE_F64>;
-def __mips16_gesf2 : RuntimeLibcallImpl<OGE_F32>;
-def __mips16_gtdf2 : RuntimeLibcallImpl<OGT_F64>;
-def __mips16_gtsf2 : RuntimeLibcallImpl<OGT_F32>;
-def __mips16_ledf2 : RuntimeLibcallImpl<OLE_F64>;
-def __mips16_lesf2 : RuntimeLibcallImpl<OLE_F32>;
-def __mips16_ltdf2 : RuntimeLibcallImpl<OLT_F64>;
-def __mips16_ltsf2 : RuntimeLibcallImpl<OLT_F32>;
+def __mips16_gedf2 : RuntimeLibcallImpl<FCMP3_PRED_OGE_F64>;
+def __mips16_gesf2 : RuntimeLibcallImpl<FCMP3_PRED_OGE_F32>;
+def __mips16_gtdf2 : RuntimeLibcallImpl<FCMP3_PRED_OGT_F64>;
+def __mips16_gtsf2 : RuntimeLibcallImpl<FCMP3_PRED_OGT_F32>;
+def __mips16_ledf2 : RuntimeLibcallImpl<FCMP3_PRED_OLE_F64>;
+def __mips16_lesf2 : RuntimeLibcallImpl<FCMP3_PRED_OLE_F32>;
+def __mips16_ltdf2 : RuntimeLibcallImpl<FCMP3_PRED_OLT_F64>;
+def __mips16_ltsf2 : RuntimeLibcallImpl<FCMP3_PRED_OLT_F32>;
def __mips16_muldf3 : RuntimeLibcallImpl<MUL_F64>;
def __mips16_mulsf3 : RuntimeLibcallImpl<MUL_F32>;
-def __mips16_nedf2 : RuntimeLibcallImpl<UNE_F64>;
-def __mips16_nesf2 : RuntimeLibcallImpl<UNE_F32>;
+def __mips16_nedf2 : RuntimeLibcallImpl<FCMP3_PRED_UNE_F64>;
+def __mips16_nesf2 : RuntimeLibcallImpl<FCMP3_PRED_UNE_F32>;
def __mips16_ret_dc : RuntimeLibcallImpl<MIPS16_RET_DC>;
def __mips16_ret_df : RuntimeLibcallImpl<MIPS16_RET_DF>;
def __mips16_ret_sc : RuntimeLibcallImpl<MIPS16_RET_SC>;
@@ -2872,18 +2884,18 @@ def __mspabi_fltulf : RuntimeLibcallImpl<UINTTOFP_I32_F32>;
def __mspabi_fltullf : RuntimeLibcallImpl<UINTTOFP_I64_F32>;
// Floating point comparisons - EABI Table 7
-def __mspabi_cmpd__oeq : RuntimeLibcallImpl<OEQ_F64, "__mspabi_cmpd">;
-def __mspabi_cmpd__une : RuntimeLibcallImpl<UNE_F64, "__mspabi_cmpd">;
-def __mspabi_cmpd__oge : RuntimeLibcallImpl<OGE_F64, "__mspabi_cmpd">;
-def __mspabi_cmpd__olt : RuntimeLibcallImpl<OLT_F64, "__mspabi_cmpd">;
-def __mspabi_cmpd__ole : RuntimeLibcallImpl<OLE_F64, "__mspabi_cmpd">;
-def __mspabi_cmpd__ogt : RuntimeLibcallImpl<OGT_F64, "__mspabi_cmpd">;
-def __mspabi_cmpf__oeq : RuntimeLibcallImpl<OEQ_F32, "__mspabi_cmpf">;
-def __mspabi_cmpf__une : RuntimeLibcallImpl<UNE_F32, "__mspabi_cmpf">;
-def __mspabi_cmpf__oge : RuntimeLibcallImpl<OGE_F32, "__mspabi_cmpf">;
-def __mspabi_cmpf__olt : RuntimeLibcallImpl<OLT_F32, "__mspabi_cmpf">;
-def __mspabi_cmpf__ole : RuntimeLibcallImpl<OLE_F32, "__mspabi_cmpf">;
-def __mspabi_cmpf__ogt : RuntimeLibcallImpl<OGT_F32, "__mspabi_cmpf">;
+def __mspabi_cmpd__oeq : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F64, "__mspabi_cmpd">;
+def __mspabi_cmpd__une : RuntimeLibcallImpl<FCMP3_PRED_UNE_F64, "__mspabi_cmpd">;
+def __mspabi_cmpd__oge : RuntimeLibcallImpl<FCMP3_PRED_OGE_F64, "__mspabi_cmpd">;
+def __mspabi_cmpd__olt : RuntimeLibcallImpl<FCMP3_PRED_OLT_F64, "__mspabi_cmpd">;
+def __mspabi_cmpd__ole : RuntimeLibcallImpl<FCMP3_PRED_OLE_F64, "__mspabi_cmpd">;
+def __mspabi_cmpd__ogt : RuntimeLibcallImpl<FCMP3_PRED_OGT_F64, "__mspabi_cmpd">;
+def __mspabi_cmpf__oeq : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F32, "__mspabi_cmpf">;
+def __mspabi_cmpf__une : RuntimeLibcallImpl<FCMP3_PRED_UNE_F32, "__mspabi_cmpf">;
+def __mspabi_cmpf__oge : RuntimeLibcallImpl<FCMP3_PRED_OGE_F32, "__mspabi_cmpf">;
+def __mspabi_cmpf__olt : RuntimeLibcallImpl<FCMP3_PRED_OLT_F32, "__mspabi_cmpf">;
+def __mspabi_cmpf__ole : RuntimeLibcallImpl<FCMP3_PRED_OLE_F32, "__mspabi_cmpf">;
+def __mspabi_cmpf__ogt : RuntimeLibcallImpl<FCMP3_PRED_OGT_F32, "__mspabi_cmpf">;
// Floating point arithmetic - EABI Table 8
def __mspabi_addd : RuntimeLibcallImpl<ADD_F64>;
@@ -3104,12 +3116,12 @@ defset list<RuntimeLibcallImpl> PPCRuntimeLibcalls = {
def __floatunsikf : RuntimeLibcallImpl<UINTTOFP_I32_F128>;
def __floatundikf : RuntimeLibcallImpl<UINTTOFP_I64_F128>;
def __floatuntikf : RuntimeLibcallImpl<UINTTOFP_I128_F128>;
- def __eqkf2 : RuntimeLibcallImpl<OEQ_F128>;
- def __nekf2 : RuntimeLibcallImpl<UNE_F128>;
- def __gekf2 : RuntimeLibcallImpl<OGE_F128>;
- def __ltkf2 : RuntimeLibcallImpl<OLT_F128>;
- def __lekf2 : RuntimeLibcallImpl<OLE_F128>;
- def __gtkf2 : RuntimeLibcallImpl<OGT_F128>;
+ def __eqkf2 : RuntimeLibcallImpl<FCMP3_PRED_OEQ_F128>;
+ def __nekf2 : RuntimeLibcallImpl<FCMP3_PRED_UNE_F128>;
+ def __gekf2 : RuntimeLibcallImpl<FCMP3_PRED_OGE_F128>;
+ def __ltkf2 : RuntimeLibcallImpl<FCMP3_PRED_OLT_F128>;
+ def __lekf2 : RuntimeLibcallImpl<FCMP3_PRED_OLE_F128>;
+ def __gtkf2 : RuntimeLibcallImpl<FCMP3_PRED_OGT_F128>;
def __unordkf2 : RuntimeLibcallImpl<UO_F128>;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 87a3ea5bdea59..11d3c04e8de3d 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -1136,19 +1136,21 @@ getFCMPLibcallDesc(const CmpInst::Predicate Pred, unsigned Size) {
} \
} while (0)
+ // These use the three-way (-1/0/1) compare libcalls, whose result is tested
+ // against 0 with a signed integer predicate. Unordered (UO) is a boolean.
switch (Pred) {
case CmpInst::FCMP_OEQ:
- RTLIBCASE_CMP(OEQ_F, CmpInst::ICMP_EQ);
+ RTLIBCASE_CMP(FCMP3_PRED_OEQ_F, CmpInst::ICMP_EQ);
case CmpInst::FCMP_UNE:
- RTLIBCASE_CMP(UNE_F, CmpInst::ICMP_NE);
+ RTLIBCASE_CMP(FCMP3_PRED_UNE_F, CmpInst::ICMP_NE);
case CmpInst::FCMP_OGE:
- RTLIBCASE_CMP(OGE_F, CmpInst::ICMP_SGE);
+ RTLIBCASE_CMP(FCMP3_PRED_OGE_F, CmpInst::ICMP_SGE);
case CmpInst::FCMP_OLT:
- RTLIBCASE_CMP(OLT_F, CmpInst::ICMP_SLT);
+ RTLIBCASE_CMP(FCMP3_PRED_OLT_F, CmpInst::ICMP_SLT);
case CmpInst::FCMP_OLE:
- RTLIBCASE_CMP(OLE_F, CmpInst::ICMP_SLE);
+ RTLIBCASE_CMP(FCMP3_PRED_OLE_F, CmpInst::ICMP_SLE);
case CmpInst::FCMP_OGT:
- RTLIBCASE_CMP(OGT_F, CmpInst::ICMP_SGT);
+ RTLIBCASE_CMP(FCMP3_PRED_OGT_F, CmpInst::ICMP_SGT);
case CmpInst::FCMP_UNO:
RTLIBCASE_CMP(UO_F, CmpInst::ICMP_NE);
default:
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 6f47bf1b81c57..86c0a2adb35b9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -322,6 +322,18 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
OldRHS, Chain);
}
+/// Select the libcall and the condition code to test its result against 0 for
+/// an ordered floating-point compare. \p BoolLC is the boolean helper (result
+/// is 0/1); \p TriStateLC is the three-way helper (result is -1/0/1, tested
+/// against 0 with \p TriStateCC). The boolean form is preferred when available.
+static std::pair<RTLIB::Libcall, ISD::CondCode>
+selectFPCmpLibcall(const LibcallLoweringInfo &Libcalls, RTLIB::Libcall BoolLC,
+ RTLIB::Libcall TriStateLC, ISD::CondCode TriStateCC) {
+ if (Libcalls.getLibcallImpl(BoolLC) != RTLIB::Unsupported)
+ return {BoolLC, ISD::SETNE};
+ return {TriStateLC, TriStateCC};
+}
+
void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
SDValue &NewLHS, SDValue &NewRHS,
ISD::CondCode &CCCode,
@@ -338,101 +350,111 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
// Expand into one or more soft-fp libcall(s).
RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL;
+ ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID;
bool ShouldInvertCC = false;
+
+ // Expand a compare libcall family name (e.g. OEQ, FCMP3_PRED_OEQ) to the
+ // RTLIB::Libcall for VT.
+#define FP_CMP_LIBCALL(BASE) \
+ RTLIB::getFPLibCall(VT, RTLIB::BASE##_F32, RTLIB::BASE##_F64, \
+ RTLIB::UNKNOWN_LIBCALL, RTLIB::BASE##_F128, \
+ RTLIB::BASE##_PPCF128)
+
switch (CCCode) {
case ISD::SETEQ:
case ISD::SETOEQ:
- LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 :
- (VT == MVT::f64) ? RTLIB::OEQ_F64 :
- (VT == MVT::f128) ? RTLIB::OEQ_F128 : RTLIB::OEQ_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OEQ),
+ FP_CMP_LIBCALL(FCMP3_PRED_OEQ), ISD::SETEQ);
break;
case ISD::SETNE:
case ISD::SETUNE:
- LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 :
- (VT == MVT::f64) ? RTLIB::UNE_F64 :
- (VT == MVT::f128) ? RTLIB::UNE_F128 : RTLIB::UNE_PPCF128;
- // Some ABIs (e.g. AEABI) only provide an ordered-equal compare; obtain
- // not-equal (UNE = !OEQ) by inverting the result of that call.
- if (getLibcallImpl(LC1) == RTLIB::Unsupported) {
- LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32
- : (VT == MVT::f64) ? RTLIB::OEQ_F64
- : (VT == MVT::f128) ? RTLIB::OEQ_F128
- : RTLIB::OEQ_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(UNE),
+ FP_CMP_LIBCALL(FCMP3_PRED_UNE), ISD::SETNE);
+ // Some ABIs (e.g. AEABI) provide neither a not-equal nor a three-way
+ // compare; obtain not-equal (UNE = !OEQ) by inverting ordered-equal.
+ if (DAG.getLibcalls().getLibcallImpl(LC1) == RTLIB::Unsupported) {
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OEQ),
+ FP_CMP_LIBCALL(FCMP3_PRED_OEQ), ISD::SETEQ);
ShouldInvertCC = true;
}
break;
case ISD::SETGE:
case ISD::SETOGE:
- LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 :
- (VT == MVT::f64) ? RTLIB::OGE_F64 :
- (VT == MVT::f128) ? RTLIB::OGE_F128 : RTLIB::OGE_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OGE),
+ FP_CMP_LIBCALL(FCMP3_PRED_OGE), ISD::SETGE);
break;
case ISD::SETLT:
case ISD::SETOLT:
- LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 :
- (VT == MVT::f64) ? RTLIB::OLT_F64 :
- (VT == MVT::f128) ? RTLIB::OLT_F128 : RTLIB::OLT_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OLT),
+ FP_CMP_LIBCALL(FCMP3_PRED_OLT), ISD::SETLT);
break;
case ISD::SETLE:
case ISD::SETOLE:
- LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 :
- (VT == MVT::f64) ? RTLIB::OLE_F64 :
- (VT == MVT::f128) ? RTLIB::OLE_F128 : RTLIB::OLE_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OLE),
+ FP_CMP_LIBCALL(FCMP3_PRED_OLE), ISD::SETLE);
break;
case ISD::SETGT:
case ISD::SETOGT:
- LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 :
- (VT == MVT::f64) ? RTLIB::OGT_F64 :
- (VT == MVT::f128) ? RTLIB::OGT_F128 : RTLIB::OGT_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OGT),
+ FP_CMP_LIBCALL(FCMP3_PRED_OGT), ISD::SETGT);
break;
case ISD::SETO:
ShouldInvertCC = true;
[[fallthrough]];
case ISD::SETUO:
- LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 :
- (VT == MVT::f64) ? RTLIB::UO_F64 :
- (VT == MVT::f128) ? RTLIB::UO_F128 : RTLIB::UO_PPCF128;
+ // Unordered is a boolean everywhere (__unordXf2 returns 0/1).
+ LC1 = FP_CMP_LIBCALL(UO);
+ CC1 = ISD::SETNE;
break;
case ISD::SETONE:
// SETONE = O && UNE
ShouldInvertCC = true;
[[fallthrough]];
case ISD::SETUEQ:
- LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 :
- (VT == MVT::f64) ? RTLIB::UO_F64 :
- (VT == MVT::f128) ? RTLIB::UO_F128 : RTLIB::UO_PPCF128;
- LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 :
- (VT == MVT::f64) ? RTLIB::OEQ_F64 :
- (VT == MVT::f128) ? RTLIB::OEQ_F128 : RTLIB::OEQ_PPCF128;
+ LC1 = FP_CMP_LIBCALL(UO);
+ CC1 = ISD::SETNE;
+ std::tie(LC2, CC2) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OEQ),
+ FP_CMP_LIBCALL(FCMP3_PRED_OEQ), ISD::SETEQ);
break;
default:
- // Invert CC for unordered comparisons
+ // Invert CC for unordered comparisons, handled by the ordered inverse.
ShouldInvertCC = true;
switch (CCCode) {
case ISD::SETULT:
- LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 :
- (VT == MVT::f64) ? RTLIB::OGE_F64 :
- (VT == MVT::f128) ? RTLIB::OGE_F128 : RTLIB::OGE_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OGE),
+ FP_CMP_LIBCALL(FCMP3_PRED_OGE), ISD::SETGE);
break;
case ISD::SETULE:
- LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 :
- (VT == MVT::f64) ? RTLIB::OGT_F64 :
- (VT == MVT::f128) ? RTLIB::OGT_F128 : RTLIB::OGT_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OGT),
+ FP_CMP_LIBCALL(FCMP3_PRED_OGT), ISD::SETGT);
break;
case ISD::SETUGT:
- LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 :
- (VT == MVT::f64) ? RTLIB::OLE_F64 :
- (VT == MVT::f128) ? RTLIB::OLE_F128 : RTLIB::OLE_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OLE),
+ FP_CMP_LIBCALL(FCMP3_PRED_OLE), ISD::SETLE);
break;
case ISD::SETUGE:
- LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 :
- (VT == MVT::f64) ? RTLIB::OLT_F64 :
- (VT == MVT::f128) ? RTLIB::OLT_F128 : RTLIB::OLT_PPCF128;
+ std::tie(LC1, CC1) =
+ selectFPCmpLibcall(DAG.getLibcalls(), FP_CMP_LIBCALL(OLT),
+ FP_CMP_LIBCALL(FCMP3_PRED_OLT), ISD::SETLT);
break;
- default: llvm_unreachable("Do not know how to soften this setcc!");
+ default:
+ llvm_unreachable("Do not know how to soften this setcc!");
}
}
+#undef FP_CMP_LIBCALL
+
// Use the target specific return value for comparison lib calls.
EVT RetVT = getCmpLibcallReturnType();
SDValue Ops[2] = {NewLHS, NewRHS};
@@ -444,13 +466,12 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
NewLHS = Call.first;
NewRHS = DAG.getConstant(0, dl, RetVT);
- RTLIB::LibcallImpl LC1Impl = getLibcallImpl(LC1);
- if (LC1Impl == RTLIB::Unsupported) {
+ if (DAG.getLibcalls().getLibcallImpl(LC1) == RTLIB::Unsupported) {
reportFatalUsageError(
"no libcall available to soften floating-point compare");
}
- CCCode = getSoftFloatCmpLibcallPredicate(LC1Impl);
+ CCCode = CC1;
if (ShouldInvertCC) {
assert(RetVT.isInteger());
CCCode = getSetCCInverse(CCCode, RetVT);
@@ -460,8 +481,7 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
// Update Chain.
Chain = Call.second;
} else {
- RTLIB::LibcallImpl LC2Impl = getLibcallImpl(LC2);
- if (LC2Impl == RTLIB::Unsupported) {
+ if (DAG.getLibcalls().getLibcallImpl(LC2) == RTLIB::Unsupported) {
reportFatalUsageError(
"no libcall available to soften floating-point compare");
}
@@ -478,7 +498,7 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
SDValue Tmp = DAG.getSetCC(dl, SetCCVT, NewLHS, NewRHS, CCCode);
auto Call2 = makeLibCall(DAG, LC2, RetVT, Ops, CallOptions, dl, Chain);
- CCCode = getSoftFloatCmpLibcallPredicate(LC2Impl);
+ CCCode = CC2;
if (ShouldInvertCC)
CCCode = getSetCCInverse(CCCode, RetVT);
NewLHS = DAG.getSetCC(dl, SetCCVT, Call2.first, NewRHS, CCCode);
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index e5f2f3fc0e80e..051ba4670be40 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -939,75 +939,6 @@ RTLIB::Libcall RTLIB::getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize) {
}
}
-ISD::CondCode TargetLoweringBase::getSoftFloatCmpLibcallPredicate(
- RTLIB::LibcallImpl Impl) const {
- switch (Impl) {
- case RTLIB::impl___aeabi_dcmpeq:
- case RTLIB::impl___aeabi_dcmplt:
- case RTLIB::impl___aeabi_dcmple:
- case RTLIB::impl___aeabi_dcmpge:
- case RTLIB::impl___aeabi_dcmpgt:
- case RTLIB::impl___aeabi_dcmpun:
- case RTLIB::impl___aeabi_fcmpeq:
- case RTLIB::impl___aeabi_fcmplt:
- case RTLIB::impl___aeabi_fcmple:
- case RTLIB::impl___aeabi_fcmpge:
- case RTLIB::impl___aeabi_fcmpgt:
- /// The AEABI versions return a typical boolean value, so we can compare
- /// against the integer result as simply != 0.
- return ISD::SETNE;
- default:
- break;
- }
-
- // Assume libgcc/compiler-rt behavior. Most of the cases are really aliases of
- // each other, and return a 3-way comparison style result of -1, 0, or 1
- // depending on lt/eq/gt.
- //
- // FIXME: It would be cleaner to directly express this as a 3-way comparison
- // soft FP libcall instead of individual compares.
- RTLIB::Libcall LC = RTLIB::RuntimeLibcallsInfo::getLibcallFromImpl(Impl);
- switch (LC) {
- case RTLIB::OEQ_F32:
- case RTLIB::OEQ_F64:
- case RTLIB::OEQ_F128:
- case RTLIB::OEQ_PPCF128:
- return ISD::SETEQ;
- case RTLIB::UNE_F32:
- case RTLIB::UNE_F64:
- case RTLIB::UNE_F128:
- case RTLIB::UNE_PPCF128:
- return ISD::SETNE;
- case RTLIB::OGE_F32:
- case RTLIB::OGE_F64:
- case RTLIB::OGE_F128:
- case RTLIB::OGE_PPCF128:
- return ISD::SETGE;
- case RTLIB::OLT_F32:
- case RTLIB::OLT_F64:
- case RTLIB::OLT_F128:
- case RTLIB::OLT_PPCF128:
- return ISD::SETLT;
- case RTLIB::OLE_F32:
- case RTLIB::OLE_F64:
- case RTLIB::OLE_F128:
- case RTLIB::OLE_PPCF128:
- return ISD::SETLE;
- case RTLIB::OGT_F32:
- case RTLIB::OGT_F64:
- case RTLIB::OGT_F128:
- case RTLIB::OGT_PPCF128:
- return ISD::SETGT;
- case RTLIB::UO_F32:
- case RTLIB::UO_F64:
- case RTLIB::UO_F128:
- case RTLIB::UO_PPCF128:
- return ISD::SETNE;
- default:
- llvm_unreachable("not a compare libcall");
- }
-}
-
/// NOTE: The TargetMachine owns TLOF.
TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm,
const TargetSubtargetInfo &STI)
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index ae9299123ee37..7ec64935b40df 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -293,40 +293,64 @@ void ARMLegalizerInfo::setFCmpLibcallsGNU() {
// FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
// default-initialized.
FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
- FCmp32Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ}};
- FCmp32Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F32, CmpInst::ICMP_SGE}};
- FCmp32Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT}};
- FCmp32Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F32, CmpInst::ICMP_SLE}};
- FCmp32Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
+ FCmp32Libcalls[CmpInst::FCMP_OEQ] = {
+ {RTLIB::FCMP3_PRED_OEQ_F32, CmpInst::ICMP_EQ}};
+ FCmp32Libcalls[CmpInst::FCMP_OGE] = {
+ {RTLIB::FCMP3_PRED_OGE_F32, CmpInst::ICMP_SGE}};
+ FCmp32Libcalls[CmpInst::FCMP_OGT] = {
+ {RTLIB::FCMP3_PRED_OGT_F32, CmpInst::ICMP_SGT}};
+ FCmp32Libcalls[CmpInst::FCMP_OLE] = {
+ {RTLIB::FCMP3_PRED_OLE_F32, CmpInst::ICMP_SLE}};
+ FCmp32Libcalls[CmpInst::FCMP_OLT] = {
+ {RTLIB::FCMP3_PRED_OLT_F32, CmpInst::ICMP_SLT}};
FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::UO_F32, CmpInst::ICMP_EQ}};
- FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_SGE}};
- FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_SGT}};
- FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SLE}};
- FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_SLT}};
- FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_NE}};
+ FCmp32Libcalls[CmpInst::FCMP_UGE] = {
+ {RTLIB::FCMP3_PRED_OLT_F32, CmpInst::ICMP_SGE}};
+ FCmp32Libcalls[CmpInst::FCMP_UGT] = {
+ {RTLIB::FCMP3_PRED_OLE_F32, CmpInst::ICMP_SGT}};
+ FCmp32Libcalls[CmpInst::FCMP_ULE] = {
+ {RTLIB::FCMP3_PRED_OGT_F32, CmpInst::ICMP_SLE}};
+ FCmp32Libcalls[CmpInst::FCMP_ULT] = {
+ {RTLIB::FCMP3_PRED_OGE_F32, CmpInst::ICMP_SLT}};
+ FCmp32Libcalls[CmpInst::FCMP_UNE] = {
+ {RTLIB::FCMP3_PRED_UNE_F32, CmpInst::ICMP_NE}};
FCmp32Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F32, CmpInst::ICMP_NE}};
- FCmp32Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT},
- {RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
- FCmp32Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ},
- {RTLIB::UO_F32, CmpInst::ICMP_NE}};
+ FCmp32Libcalls[CmpInst::FCMP_ONE] = {
+ {RTLIB::FCMP3_PRED_OGT_F32, CmpInst::ICMP_SGT},
+ {RTLIB::FCMP3_PRED_OLT_F32, CmpInst::ICMP_SLT}};
+ FCmp32Libcalls[CmpInst::FCMP_UEQ] = {
+ {RTLIB::FCMP3_PRED_OEQ_F32, CmpInst::ICMP_EQ},
+ {RTLIB::UO_F32, CmpInst::ICMP_NE}};
FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
- FCmp64Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ}};
- FCmp64Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F64, CmpInst::ICMP_SGE}};
- FCmp64Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT}};
- FCmp64Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F64, CmpInst::ICMP_SLE}};
- FCmp64Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
+ FCmp64Libcalls[CmpInst::FCMP_OEQ] = {
+ {RTLIB::FCMP3_PRED_OEQ_F64, CmpInst::ICMP_EQ}};
+ FCmp64Libcalls[CmpInst::FCMP_OGE] = {
+ {RTLIB::FCMP3_PRED_OGE_F64, CmpInst::ICMP_SGE}};
+ FCmp64Libcalls[CmpInst::FCMP_OGT] = {
+ {RTLIB::FCMP3_PRED_OGT_F64, CmpInst::ICMP_SGT}};
+ FCmp64Libcalls[CmpInst::FCMP_OLE] = {
+ {RTLIB::FCMP3_PRED_OLE_F64, CmpInst::ICMP_SLE}};
+ FCmp64Libcalls[CmpInst::FCMP_OLT] = {
+ {RTLIB::FCMP3_PRED_OLT_F64, CmpInst::ICMP_SLT}};
FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::UO_F64, CmpInst::ICMP_EQ}};
- FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_SGE}};
- FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_SGT}};
- FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SLE}};
- FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_SLT}};
- FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_NE}};
+ FCmp64Libcalls[CmpInst::FCMP_UGE] = {
+ {RTLIB::FCMP3_PRED_OLT_F64, CmpInst::ICMP_SGE}};
+ FCmp64Libcalls[CmpInst::FCMP_UGT] = {
+ {RTLIB::FCMP3_PRED_OLE_F64, CmpInst::ICMP_SGT}};
+ FCmp64Libcalls[CmpInst::FCMP_ULE] = {
+ {RTLIB::FCMP3_PRED_OGT_F64, CmpInst::ICMP_SLE}};
+ FCmp64Libcalls[CmpInst::FCMP_ULT] = {
+ {RTLIB::FCMP3_PRED_OGE_F64, CmpInst::ICMP_SLT}};
+ FCmp64Libcalls[CmpInst::FCMP_UNE] = {
+ {RTLIB::FCMP3_PRED_UNE_F64, CmpInst::ICMP_NE}};
FCmp64Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F64, CmpInst::ICMP_NE}};
- FCmp64Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT},
- {RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
- FCmp64Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ},
- {RTLIB::UO_F64, CmpInst::ICMP_NE}};
+ FCmp64Libcalls[CmpInst::FCMP_ONE] = {
+ {RTLIB::FCMP3_PRED_OGT_F64, CmpInst::ICMP_SGT},
+ {RTLIB::FCMP3_PRED_OLT_F64, CmpInst::ICMP_SLT}};
+ FCmp64Libcalls[CmpInst::FCMP_UEQ] = {
+ {RTLIB::FCMP3_PRED_OEQ_F64, CmpInst::ICMP_EQ},
+ {RTLIB::UO_F64, CmpInst::ICMP_NE}};
}
ARMLegalizerInfo::FCmpLibcallsList
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index f3db0d0ef2d08..dc2e0622174d9 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -262,13 +262,18 @@ void ARMSubtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {
}
// AEABI provides an ordered-equal compare (__aeabi_{f,d}cmpeq) but no
- // not-equal compare. Clear the unordered-not-equal libcall so UNE will lower
- // as !OEQ using the AEABI compare, rather than emitting the now-available
- // generic __nesf2/__nedf2.
- if (RTLCI.isAvailable(RTLIB::impl___aeabi_fcmpeq))
+ // not-equal compare. Clear the not-equal libcalls so UNE will lower as !OEQ
+ // using the AEABI compare, rather than emitting the generic not-equal helper
+ // which would otherwise be preferred.
+ if (RTLCI.isAvailable(RTLIB::impl___aeabi_fcmpeq)) {
Info.setLibcallImpl(RTLIB::UNE_F32, RTLIB::Unsupported);
- if (RTLCI.isAvailable(RTLIB::impl___aeabi_dcmpeq))
+ Info.setLibcallImpl(RTLIB::FCMP3_PRED_UNE_F32, RTLIB::Unsupported);
+ }
+
+ if (RTLCI.isAvailable(RTLIB::impl___aeabi_dcmpeq)) {
Info.setLibcallImpl(RTLIB::UNE_F64, RTLIB::Unsupported);
+ Info.setLibcallImpl(RTLIB::FCMP3_PRED_UNE_F64, RTLIB::Unsupported);
+ }
}
bool ARMSubtarget::isXRaySupported() const {
diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
index 7e575864f4027..dbe0489be356b 100644
--- a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
+++ b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp
@@ -158,18 +158,20 @@ void MSP430Subtarget::initLibcallLoweringInfo(LibcallLoweringInfo &Info) const {
{RTLIB::SINTTOFP_I64_F32, RTLIB::impl___mspabi_fltllif},
{RTLIB::UINTTOFP_I32_F32, RTLIB::impl___mspabi_fltulf},
{RTLIB::UINTTOFP_I64_F32, RTLIB::impl___mspabi_fltullf},
- // Floating point comparisons - EABI Table 7.
- {RTLIB::OEQ_F64, RTLIB::impl___mspabi_cmpd__oeq},
- {RTLIB::OGE_F64, RTLIB::impl___mspabi_cmpd__oge},
- {RTLIB::OLT_F64, RTLIB::impl___mspabi_cmpd__olt},
- {RTLIB::OLE_F64, RTLIB::impl___mspabi_cmpd__ole},
- {RTLIB::OGT_F64, RTLIB::impl___mspabi_cmpd__ogt},
- {RTLIB::OEQ_F32, RTLIB::impl___mspabi_cmpf__oeq},
- {RTLIB::UNE_F32, RTLIB::impl___mspabi_cmpf__une},
- {RTLIB::OGE_F32, RTLIB::impl___mspabi_cmpf__oge},
- {RTLIB::OLT_F32, RTLIB::impl___mspabi_cmpf__olt},
- {RTLIB::OLE_F32, RTLIB::impl___mspabi_cmpf__ole},
- {RTLIB::OGT_F32, RTLIB::impl___mspabi_cmpf__ogt},
+ // Floating point comparisons - EABI Table 7. These are three-way
+ // compares returning -1/0/1, so they implement the FCMP3_PRED_* libcalls.
+ {RTLIB::FCMP3_PRED_OEQ_F64, RTLIB::impl___mspabi_cmpd__oeq},
+ {RTLIB::FCMP3_PRED_UNE_F64, RTLIB::impl___mspabi_cmpd__une},
+ {RTLIB::FCMP3_PRED_OGE_F64, RTLIB::impl___mspabi_cmpd__oge},
+ {RTLIB::FCMP3_PRED_OLT_F64, RTLIB::impl___mspabi_cmpd__olt},
+ {RTLIB::FCMP3_PRED_OLE_F64, RTLIB::impl___mspabi_cmpd__ole},
+ {RTLIB::FCMP3_PRED_OGT_F64, RTLIB::impl___mspabi_cmpd__ogt},
+ {RTLIB::FCMP3_PRED_OEQ_F32, RTLIB::impl___mspabi_cmpf__oeq},
+ {RTLIB::FCMP3_PRED_UNE_F32, RTLIB::impl___mspabi_cmpf__une},
+ {RTLIB::FCMP3_PRED_OGE_F32, RTLIB::impl___mspabi_cmpf__oge},
+ {RTLIB::FCMP3_PRED_OLT_F32, RTLIB::impl___mspabi_cmpf__olt},
+ {RTLIB::FCMP3_PRED_OLE_F32, RTLIB::impl___mspabi_cmpf__ole},
+ {RTLIB::FCMP3_PRED_OGT_F32, RTLIB::impl___mspabi_cmpf__ogt},
// Floating point arithmetic - EABI Table 8.
{RTLIB::ADD_F64, RTLIB::impl___mspabi_addd},
{RTLIB::SUB_F64, RTLIB::impl___mspabi_subd},
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
index cda6f6ec88be0..698b8084909ce 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
@@ -363,6 +363,24 @@ struct RuntimeLibcallSignatureTable {
Table[RTLIB::UO_F32] = i32_func_f32_f32;
Table[RTLIB::UO_F64] = i32_func_f64_f64;
Table[RTLIB::UO_F128] = i32_func_i64_i64_i64_i64;
+ Table[RTLIB::FCMP3_PRED_OEQ_F32] = i32_func_f32_f32;
+ Table[RTLIB::FCMP3_PRED_OEQ_F64] = i32_func_f64_f64;
+ Table[RTLIB::FCMP3_PRED_OEQ_F128] = i32_func_i64_i64_i64_i64;
+ Table[RTLIB::FCMP3_PRED_UNE_F32] = i32_func_f32_f32;
+ Table[RTLIB::FCMP3_PRED_UNE_F64] = i32_func_f64_f64;
+ Table[RTLIB::FCMP3_PRED_UNE_F128] = i32_func_i64_i64_i64_i64;
+ Table[RTLIB::FCMP3_PRED_OGE_F32] = i32_func_f32_f32;
+ Table[RTLIB::FCMP3_PRED_OGE_F64] = i32_func_f64_f64;
+ Table[RTLIB::FCMP3_PRED_OGE_F128] = i32_func_i64_i64_i64_i64;
+ Table[RTLIB::FCMP3_PRED_OLT_F32] = i32_func_f32_f32;
+ Table[RTLIB::FCMP3_PRED_OLT_F64] = i32_func_f64_f64;
+ Table[RTLIB::FCMP3_PRED_OLT_F128] = i32_func_i64_i64_i64_i64;
+ Table[RTLIB::FCMP3_PRED_OLE_F32] = i32_func_f32_f32;
+ Table[RTLIB::FCMP3_PRED_OLE_F64] = i32_func_f64_f64;
+ Table[RTLIB::FCMP3_PRED_OLE_F128] = i32_func_i64_i64_i64_i64;
+ Table[RTLIB::FCMP3_PRED_OGT_F32] = i32_func_f32_f32;
+ Table[RTLIB::FCMP3_PRED_OGT_F64] = i32_func_f64_f64;
+ Table[RTLIB::FCMP3_PRED_OGT_F128] = i32_func_i64_i64_i64_i64;
// Memory
Table[RTLIB::MEMCPY] = iPTR_func_iPTR_iPTR_iPTR;
More information about the llvm-commits
mailing list