Skip to content

RuntimeLibcalls: Remove table of soft float compare cond codes #146082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ LLVM_ABI Libcall getMEMMOVE_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
/// UNKNOW_LIBCALL if there is none.
LLVM_ABI Libcall getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);

/// Initialize the default condition code on the libcalls.
LLVM_ABI void initCmpLibcallCCs(ISD::CondCode *CmpLibcallCCs);

} // namespace RTLIB
} // namespace llvm

Expand Down
17 changes: 4 additions & 13 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -3571,19 +3571,10 @@ class LLVM_ABI TargetLoweringBase {

const char *getMemcpyName() const { return Libcalls.getMemcpyName(); }

/// Override the default CondCode to be used to test the result of the
/// comparison libcall against zero.
/// FIXME: This should be removed
void setCmpLibcallCC(RTLIB::Libcall Call, CmpInst::Predicate Pred) {
Libcalls.setSoftFloatCmpLibcallPredicate(Call, Pred);
}

/// Get the CondCode that's to be used to test the result of the comparison
/// libcall against zero.
CmpInst::Predicate
getSoftFloatCmpLibcallPredicate(RTLIB::Libcall Call) const {
return Libcalls.getSoftFloatCmpLibcallPredicate(Call);
}
/// 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;

/// Set the CallingConv that should be used for the specified libcall.
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
Expand Down
33 changes: 5 additions & 28 deletions llvm/include/llvm/IR/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ struct RuntimeLibcallsInfo {
ExceptionHandling ExceptionModel = ExceptionHandling::None,
FloatABI::ABIType FloatABI = FloatABI::Default,
EABI EABIVersion = EABI::Default, StringRef ABIName = "") {
initSoftFloatCmpLibcallPredicates();

// FIXME: The ExceptionModel parameter is to handle the field in
// TargetOptions. This interface fails to distinguish the forced disable
// case for targets which support exceptions by default. This should
Expand Down Expand Up @@ -114,22 +112,6 @@ struct RuntimeLibcallsInfo {
return ArrayRef(LibcallImpls).drop_back();
}

/// 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.
// FIXME: This should be a function of RTLIB::LibcallImpl
CmpInst::Predicate
getSoftFloatCmpLibcallPredicate(RTLIB::Libcall Call) const {
return SoftFloatCompareLibcallPredicates[Call];
}

// FIXME: This should be removed. This should be private constant.
// FIXME: This should be a function of RTLIB::LibcallImpl
void setSoftFloatCmpLibcallPredicate(RTLIB::Libcall Call,
CmpInst::Predicate Pred) {
SoftFloatCompareLibcallPredicates[Call] = Pred;
}

/// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
/// unsupported.
const char *getMemcpyName() const {
Expand All @@ -140,6 +122,11 @@ struct RuntimeLibcallsInfo {
return getLibcallName(RTLIB::MEMMOVE);
}

/// Return the libcall provided by \p Impl
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
return ImplToLibcall[Impl];
}

private:
static const RTLIB::LibcallImpl
DefaultLibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1];
Expand All @@ -155,14 +142,6 @@ struct RuntimeLibcallsInfo {
/// implementation.;
CallingConv::ID LibcallImplCallingConvs[RTLIB::NumLibcallImpls] = {};

/// The condition type that should be used to test the result of each of the
/// soft floating-point comparison libcall against integer zero.
///
// FIXME: This is only relevant for the handful of floating-point comparison
// runtime calls; it's excessive to have a table entry for every single
// opcode.
CmpInst::Predicate SoftFloatCompareLibcallPredicates[RTLIB::UNKNOWN_LIBCALL];

/// Names of concrete implementations of runtime calls. e.g. __ashlsi3 for
/// SHL_I32
LLVM_ABI static const char *const LibCallImplNames[RTLIB::NumLibcallImpls];
Expand Down Expand Up @@ -200,8 +179,6 @@ struct RuntimeLibcallsInfo {
/// Generated by tablegen.
void setTargetRuntimeLibcallSets(const Triple &TT);

LLVM_ABI void initSoftFloatCmpLibcallPredicates();

/// Set default libcall names. If a target wants to opt-out of a libcall it
/// should be placed here.
LLVM_ABI void initLibcalls(const Triple &TT, ExceptionHandling ExceptionModel,
Expand Down
8 changes: 4 additions & 4 deletions llvm/include/llvm/IR/RuntimeLibcalls.td
Original file line number Diff line number Diff line change
Expand Up @@ -1176,8 +1176,8 @@ def __aeabi_dsub : RuntimeLibcallImpl<SUB_F64>; // CallingConv::ARM_AAPCS

// Double-precision floating-point comparison helper functions
// RTABI chapter 4.1.2, Table 3
def __aeabi_dcmpeq__ne : RuntimeLibcallImpl<OEQ_F64, "__aeabi_dcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_dcmpeq__eq : RuntimeLibcallImpl<UNE_F64, "__aeabi_dcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ
def __aeabi_dcmpeq__oeq : RuntimeLibcallImpl<OEQ_F64, "__aeabi_dcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_dcmpeq__une : RuntimeLibcallImpl<UNE_F64, "__aeabi_dcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ
def __aeabi_dcmplt : RuntimeLibcallImpl<OLT_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_dcmple : RuntimeLibcallImpl<OLE_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_dcmpge : RuntimeLibcallImpl<OGE_F64>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
Expand All @@ -1193,8 +1193,8 @@ def __aeabi_fsub : RuntimeLibcallImpl<SUB_F32>; // CallingConv::ARM_AAPCS

// Single-precision floating-point comparison helper functions
// RTABI chapter 4.1.2, Table 5
def __aeabi_fcmpeq__ne : RuntimeLibcallImpl<OEQ_F32, "__aeabi_fcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_fcmpeq__eq : RuntimeLibcallImpl<UNE_F32, "__aeabi_fcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ
def __aeabi_fcmpeq__oeq : RuntimeLibcallImpl<OEQ_F32, "__aeabi_fcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_fcmpeq__une : RuntimeLibcallImpl<UNE_F32, "__aeabi_fcmpeq">; // CallingConv::ARM_AAPCS, CmpInst::ICMP_EQ
def __aeabi_fcmplt : RuntimeLibcallImpl<OLT_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_fcmple : RuntimeLibcallImpl<OLE_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
def __aeabi_fcmpge : RuntimeLibcallImpl<OGE_F32>; // CallingConv::ARM_AAPCS, CmpInst::ICMP_NE
Expand Down
16 changes: 14 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,13 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
NewLHS = Call.first;
NewRHS = DAG.getConstant(0, dl, RetVT);

CCCode = getICmpCondCode(getSoftFloatCmpLibcallPredicate(LC1));
RTLIB::LibcallImpl LC1Impl = getLibcallImpl(LC1);
if (LC1Impl == RTLIB::Unsupported) {
reportFatalUsageError(
"no libcall available to soften floating-point compare");
}

CCCode = getSoftFloatCmpLibcallPredicate(LC1Impl);
if (ShouldInvertCC) {
assert(RetVT.isInteger());
CCCode = getSetCCInverse(CCCode, RetVT);
Expand All @@ -434,6 +440,12 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
// Update Chain.
Chain = Call.second;
} else {
RTLIB::LibcallImpl LC2Impl = getLibcallImpl(LC2);
if (LC2Impl == RTLIB::Unsupported) {
reportFatalUsageError(
"no libcall available to soften floating-point compare");
}

assert(CCCode == (ShouldInvertCC ? ISD::SETEQ : ISD::SETNE) &&
"unordered call should be simple boolean");

Expand All @@ -446,7 +458,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 = getICmpCondCode(getSoftFloatCmpLibcallPredicate(LC2));
CCCode = getSoftFloatCmpLibcallPredicate(LC2Impl);
if (ShouldInvertCC)
CCCode = getSetCCInverse(CCCode, RetVT);
NewLHS = DAG.getSetCC(dl, SetCCVT, Call2.first, NewRHS, CCCode);
Expand Down
106 changes: 73 additions & 33 deletions llvm/lib/CodeGen/TargetLoweringBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,37 +609,79 @@ RTLIB::Libcall RTLIB::getMEMSET_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize) {
}
}

void RTLIB::initCmpLibcallCCs(ISD::CondCode *CmpLibcallCCs) {
std::fill(CmpLibcallCCs, CmpLibcallCCs + RTLIB::UNKNOWN_LIBCALL,
ISD::SETCC_INVALID);
CmpLibcallCCs[RTLIB::OEQ_F32] = ISD::SETEQ;
CmpLibcallCCs[RTLIB::OEQ_F64] = ISD::SETEQ;
CmpLibcallCCs[RTLIB::OEQ_F128] = ISD::SETEQ;
CmpLibcallCCs[RTLIB::OEQ_PPCF128] = ISD::SETEQ;
CmpLibcallCCs[RTLIB::UNE_F32] = ISD::SETNE;
CmpLibcallCCs[RTLIB::UNE_F64] = ISD::SETNE;
CmpLibcallCCs[RTLIB::UNE_F128] = ISD::SETNE;
CmpLibcallCCs[RTLIB::UNE_PPCF128] = ISD::SETNE;
CmpLibcallCCs[RTLIB::OGE_F32] = ISD::SETGE;
CmpLibcallCCs[RTLIB::OGE_F64] = ISD::SETGE;
CmpLibcallCCs[RTLIB::OGE_F128] = ISD::SETGE;
CmpLibcallCCs[RTLIB::OGE_PPCF128] = ISD::SETGE;
CmpLibcallCCs[RTLIB::OLT_F32] = ISD::SETLT;
CmpLibcallCCs[RTLIB::OLT_F64] = ISD::SETLT;
CmpLibcallCCs[RTLIB::OLT_F128] = ISD::SETLT;
CmpLibcallCCs[RTLIB::OLT_PPCF128] = ISD::SETLT;
CmpLibcallCCs[RTLIB::OLE_F32] = ISD::SETLE;
CmpLibcallCCs[RTLIB::OLE_F64] = ISD::SETLE;
CmpLibcallCCs[RTLIB::OLE_F128] = ISD::SETLE;
CmpLibcallCCs[RTLIB::OLE_PPCF128] = ISD::SETLE;
CmpLibcallCCs[RTLIB::OGT_F32] = ISD::SETGT;
CmpLibcallCCs[RTLIB::OGT_F64] = ISD::SETGT;
CmpLibcallCCs[RTLIB::OGT_F128] = ISD::SETGT;
CmpLibcallCCs[RTLIB::OGT_PPCF128] = ISD::SETGT;
CmpLibcallCCs[RTLIB::UO_F32] = ISD::SETNE;
CmpLibcallCCs[RTLIB::UO_F64] = ISD::SETNE;
CmpLibcallCCs[RTLIB::UO_F128] = ISD::SETNE;
CmpLibcallCCs[RTLIB::UO_PPCF128] = ISD::SETNE;
ISD::CondCode TargetLoweringBase::getSoftFloatCmpLibcallPredicate(
RTLIB::LibcallImpl Impl) const {
switch (Impl) {
case RTLIB::__aeabi_dcmpeq__une:
case RTLIB::__aeabi_fcmpeq__une:
// Usage in the eq case, so we have to invert the comparison.
return ISD::SETEQ;
case RTLIB::__aeabi_dcmpeq__oeq:
case RTLIB::__aeabi_fcmpeq__oeq:
// Normal comparison to boolean value.
return ISD::SETNE;
case RTLIB::__aeabi_dcmplt:
case RTLIB::__aeabi_dcmple:
case RTLIB::__aeabi_dcmpge:
case RTLIB::__aeabi_dcmpgt:
case RTLIB::__aeabi_dcmpun:
case RTLIB::__aeabi_fcmplt:
case RTLIB::__aeabi_fcmple:
case RTLIB::__aeabi_fcmpge:
case RTLIB::__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.
Expand Down Expand Up @@ -678,8 +720,6 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm)

MinCmpXchgSizeInBits = 0;
SupportsUnalignedAtomics = false;

RTLIB::initCmpLibcallCCs(CmpLibcallCCs);
}

// Define the virtual destructor out-of-line to act as a key method to anchor
Expand Down
31 changes: 0 additions & 31 deletions llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,37 +100,6 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT,
}
}

void RuntimeLibcallsInfo::initSoftFloatCmpLibcallPredicates() {
SoftFloatCompareLibcallPredicates[RTLIB::OEQ_F32] = CmpInst::ICMP_EQ;
SoftFloatCompareLibcallPredicates[RTLIB::OEQ_F64] = CmpInst::ICMP_EQ;
SoftFloatCompareLibcallPredicates[RTLIB::OEQ_F128] = CmpInst::ICMP_EQ;
SoftFloatCompareLibcallPredicates[RTLIB::OEQ_PPCF128] = CmpInst::ICMP_EQ;
SoftFloatCompareLibcallPredicates[RTLIB::UNE_F32] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::UNE_F64] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::UNE_F128] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::UNE_PPCF128] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::OGE_F32] = CmpInst::ICMP_SGE;
SoftFloatCompareLibcallPredicates[RTLIB::OGE_F64] = CmpInst::ICMP_SGE;
SoftFloatCompareLibcallPredicates[RTLIB::OGE_F128] = CmpInst::ICMP_SGE;
SoftFloatCompareLibcallPredicates[RTLIB::OGE_PPCF128] = CmpInst::ICMP_SGE;
SoftFloatCompareLibcallPredicates[RTLIB::OLT_F32] = CmpInst::ICMP_SLT;
SoftFloatCompareLibcallPredicates[RTLIB::OLT_F64] = CmpInst::ICMP_SLT;
SoftFloatCompareLibcallPredicates[RTLIB::OLT_F128] = CmpInst::ICMP_SLT;
SoftFloatCompareLibcallPredicates[RTLIB::OLT_PPCF128] = CmpInst::ICMP_SLT;
SoftFloatCompareLibcallPredicates[RTLIB::OLE_F32] = CmpInst::ICMP_SLE;
SoftFloatCompareLibcallPredicates[RTLIB::OLE_F64] = CmpInst::ICMP_SLE;
SoftFloatCompareLibcallPredicates[RTLIB::OLE_F128] = CmpInst::ICMP_SLE;
SoftFloatCompareLibcallPredicates[RTLIB::OLE_PPCF128] = CmpInst::ICMP_SLE;
SoftFloatCompareLibcallPredicates[RTLIB::OGT_F32] = CmpInst::ICMP_SGT;
SoftFloatCompareLibcallPredicates[RTLIB::OGT_F64] = CmpInst::ICMP_SGT;
SoftFloatCompareLibcallPredicates[RTLIB::OGT_F128] = CmpInst::ICMP_SGT;
SoftFloatCompareLibcallPredicates[RTLIB::OGT_PPCF128] = CmpInst::ICMP_SGT;
SoftFloatCompareLibcallPredicates[RTLIB::UO_F32] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::UO_F64] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::UO_F128] = CmpInst::ICMP_NE;
SoftFloatCompareLibcallPredicates[RTLIB::UO_PPCF128] = CmpInst::ICMP_NE;
}

static void setLongDoubleIsF128Libm(RuntimeLibcallsInfo &Info,
bool FiniteOnlyFuncs = false) {
Info.setLibcallImpl(RTLIB::REM_F128, RTLIB::fmodf128);
Expand Down
Loading
Loading