Skip to content
Open
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
11 changes: 10 additions & 1 deletion llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -4116,12 +4116,21 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
}

/// Returns a pair of (return value, chain).
/// It is an error to pass RTLIB::Unsupported as \p LibcallImpl
std::pair<SDValue, SDValue>
makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT,
ArrayRef<SDValue> Ops, MakeLibCallOptions CallOptions,
const SDLoc &dl, SDValue Chain = SDValue()) const;

/// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC.
std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC,
EVT RetVT, ArrayRef<SDValue> Ops,
MakeLibCallOptions CallOptions,
const SDLoc &dl,
SDValue Chain = SDValue()) const;
SDValue Chain = SDValue()) const {
return makeLibCall(DAG, getLibcallImpl(LC), RetVT, Ops, CallOptions, dl,
Chain);
}

/// Check whether parameters to a call that are passed in callee saved
/// registers are the same as from the calling function. This needs to be
Expand Down
8 changes: 5 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,8 @@ bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
assert(VT == N->getValueType(1) &&
"expected both return values to have the same type");

if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported)
RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
if (LCImpl == RTLIB::Unsupported)
return false;

EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
Expand Down Expand Up @@ -831,8 +832,9 @@ bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
CallOptions.setTypeListBeforeSoften({OpsVT}, VT)
.setOpsTypeOverrides(CallOpsTypeOverrides);

auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, DL,
/*Chain=*/SDValue());
auto [ReturnVal, Chain] =
TLI.makeLibCall(DAG, LCImpl, NVT, Ops, CallOptions, DL,
/*Chain=*/SDValue());

auto CreateStackLoad = [&, Chain = Chain](SDValue StackSlot) {
int FrameIdx = cast<FrameIndexSDNode>(StackSlot)->getIndex();
Expand Down
37 changes: 23 additions & 14 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2692,7 +2692,8 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) {
RTLIB::Libcall LC = IsPowI ? RTLIB::getPOWI(N->getValueType(0))
: RTLIB::getLDEXP(N->getValueType(0));

if (TLI.getLibcallImpl(LC) == RTLIB::Unsupported) {
RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
if (LCImpl == RTLIB::Unsupported) {
// Scalarize vector FPOWI instead of promoting the type. This allows the
// scalar FPOWIs to be visited and converted to libcalls before promoting
// the type.
Expand All @@ -2719,7 +2720,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ExpOp(SDNode *N) {
CallOptions.setIsSigned(true);
SDValue Ops[2] = {N->getOperand(0 + OpOffset), N->getOperand(1 + OpOffset)};
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
DAG, LC, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain);
DAG, LCImpl, N->getValueType(0), Ops, CallOptions, SDLoc(N), Chain);
ReplaceValueWith(SDValue(N, 0), Tmp.first);
if (IsStrict)
ReplaceValueWith(SDValue(N, 1), Tmp.second);
Expand Down Expand Up @@ -3187,16 +3188,19 @@ std::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) {
EVT RetVT = Node->getValueType(0);
TargetLowering::MakeLibCallOptions CallOptions;
SmallVector<SDValue, 4> Ops;
if (TLI.getLibcallName(LC)) {

RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
if (LCImpl != RTLIB::Unsupported) {
Ops.append(Node->op_begin() + 2, Node->op_end());
Ops.push_back(Node->getOperand(1));
} else {
LC = RTLIB::getSYNC(Opc, VT);
assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected atomic op or value type!");
Ops.append(Node->op_begin() + 1, Node->op_end());
LCImpl = TLI.getLibcallImpl(LC);
}
return TLI.makeLibCall(DAG, LC, RetVT, Ops, CallOptions, SDLoc(Node),
return TLI.makeLibCall(DAG, LCImpl, RetVT, Ops, CallOptions, SDLoc(Node),
Node->getOperand(0));
}

Expand Down Expand Up @@ -4403,8 +4407,8 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,

// If nothing else, we can make a libcall.
RTLIB::Libcall LC = RTLIB::getMUL(VT);

if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC)) {
RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);
if (LCImpl == RTLIB::Unsupported) {
// Perform a wide multiplication where the wide type is the original VT and
// the 4 parts are the split arguments.
TLI.forceExpandMultiply(DAG, dl, /*Signed=*/false, Lo, Hi, LL, RL, LH, RH);
Expand All @@ -4416,8 +4420,8 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
TargetLowering::MakeLibCallOptions CallOptions;
CallOptions.setIsSigned(true);
SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first,
Lo, Hi);
SplitInteger(TLI.makeLibCall(DAG, LCImpl, VT, Ops, CallOptions, dl).first, Lo,
Hi);
}

void DAGTypeLegalizer::ExpandIntRes_READCOUNTER(SDNode *N, SDValue &Lo,
Expand Down Expand Up @@ -4991,14 +4995,16 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
LC = RTLIB::getSRA(VT);
}

if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
if (RTLIB::LibcallImpl LibcallImpl = TLI.getLibcallImpl(LC)) {
EVT ShAmtTy =
EVT::getIntegerVT(*DAG.getContext(), DAG.getLibInfo().getIntSize());
SDValue ShAmt = DAG.getZExtOrTrunc(N->getOperand(1), dl, ShAmtTy);
SDValue Ops[2] = {N->getOperand(0), ShAmt};
TargetLowering::MakeLibCallOptions CallOptions;
CallOptions.setIsSigned(isSigned);
SplitInteger(TLI.makeLibCall(DAG, LC, VT, Ops, CallOptions, dl).first, Lo, Hi);
SplitInteger(
TLI.makeLibCall(DAG, LibcallImpl, VT, Ops, CallOptions, dl).first, Lo,
Hi);
return;
}

Expand Down Expand Up @@ -5158,11 +5164,12 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,

// Replace this with a libcall that will check overflow.
RTLIB::Libcall LC = RTLIB::getMULO(VT);
RTLIB::LibcallImpl LCImpl = TLI.getLibcallImpl(LC);

// If we don't have the libcall or if the function we are compiling is the
// implementation of the expected libcall (avoid inf-loop), expand inline.
if (LC == RTLIB::UNKNOWN_LIBCALL || !TLI.getLibcallName(LC) ||
TLI.getLibcallName(LC) == DAG.getMachineFunction().getName()) {
if (LCImpl == RTLIB::Unsupported ||
TLI.getLibcallImplName(LCImpl) == DAG.getMachineFunction().getName()) {
// FIXME: This is not an optimal expansion, but better than crashing.
SDValue MulLo, MulHi;
TLI.forceExpandWideMUL(DAG, dl, /*Signed=*/true, N->getOperand(0),
Expand Down Expand Up @@ -5200,12 +5207,14 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
Entry.IsZExt = false;
Args.push_back(Entry);

SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT);
SDValue Func =
DAG.getExternalSymbol(TLI.getLibcallImplName(LCImpl).data(), PtrVT);

TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(dl)
.setChain(Chain)
.setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Func, std::move(Args))
.setLibCallee(TLI.getLibcallImplCallingConv(LCImpl), RetTy, Func,
std::move(Args))
.setSExtResult();

std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
Expand Down
14 changes: 6 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,13 @@ void TargetLoweringBase::ArgListEntry::setAttributes(const CallBase *Call,
/// Generate a libcall taking the given operands as arguments and returning a
/// result of type RetVT.
std::pair<SDValue, SDValue>
TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
ArrayRef<SDValue> Ops,
MakeLibCallOptions CallOptions,
const SDLoc &dl,
TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl,
EVT RetVT, ArrayRef<SDValue> Ops,
MakeLibCallOptions CallOptions, const SDLoc &dl,
SDValue InChain) const {
if (LibcallImpl == RTLIB::Unsupported)
reportFatalInternalError("unsupported library call operation");

if (!InChain)
InChain = DAG.getEntryNode();

Expand Down Expand Up @@ -185,10 +187,6 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
Args.push_back(Entry);
}

RTLIB::LibcallImpl LibcallImpl = getLibcallImpl(LC);
if (LibcallImpl == RTLIB::Unsupported)
reportFatalInternalError("unsupported library call operation");

SDValue Callee = DAG.getExternalSymbol(getLibcallImplName(LibcallImpl).data(),
getPointerTy(DAG.getDataLayout()));

Expand Down
Loading