Skip to content

[SDAG] Pass pointer type to libcall expansion for SoftenFloatRes stack slots #130647

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
merged 1 commit into from
Mar 13, 2025
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
9 changes: 9 additions & 0 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -4749,6 +4749,8 @@ class TargetLowering : public TargetLoweringBase {
// shouldExtendTypeInLibCall can get the original type before soften.
ArrayRef<EVT> OpsVTBeforeSoften;
EVT RetVTBeforeSoften;
ArrayRef<Type *> OpsTypeOverrides;

bool IsSigned : 1;
bool DoesNotReturn : 1;
bool IsReturnValueUsed : 1;
Expand Down Expand Up @@ -4786,6 +4788,13 @@ class TargetLowering : public TargetLoweringBase {
IsSoften = Value;
return *this;
}

/// Override the argument type for an operand. Leave the type as null to use
/// the type from the operand's node.
MakeLibCallOptions &setOpsTypeOverrides(ArrayRef<Type *> OpsTypes) {
OpsTypeOverrides = OpsTypes;
return *this;
}
};

/// This function lowers an abstract call to a function into an actual call.
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,13 +772,16 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {

SDLoc DL(N);

auto PointerTy = PointerType::getUnqual(*DAG.getContext());
TargetLowering::MakeLibCallOptions CallOptions;
SDValue Ops[2] = {GetSoftenedFloat(N->getOperand(0)), StackSlot};
EVT OpsVT[2] = {VT0, StackSlot.getValueType()};
Type *CallOpsTypeOverrides[2] = {nullptr, PointerTy};

// TODO: setTypeListBeforeSoften can't properly express multiple return types,
// but we only really need to handle the 0th one for softening anyway.
CallOptions.setTypeListBeforeSoften({OpsVT}, VT0, true);
CallOptions.setTypeListBeforeSoften({OpsVT}, VT0, true)
.setOpsTypeOverrides(CallOpsTypeOverrides);

auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT0, Ops, CallOptions, DL,
/*Chain=*/SDValue());
Expand Down Expand Up @@ -811,19 +814,23 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
SmallVector<EVT, 3> OpsVT = {VT};

std::array<SDValue, 2> StackSlots;
SmallVector<Type *, 3> CallOpsTypeOverrides = {nullptr};
auto PointerTy = PointerType::getUnqual(*DAG.getContext());
for (unsigned ResNum = 0; ResNum < N->getNumValues(); ++ResNum) {
if (ResNum == CallRetResNo)
continue;
SDValue StackSlot = DAG.CreateStackTemporary(NVT);
Ops.push_back(StackSlot);
OpsVT.push_back(StackSlot.getValueType());
StackSlots[ResNum] = StackSlot;
CallOpsTypeOverrides.push_back(PointerTy);
}

TargetLowering::MakeLibCallOptions CallOptions;
// TODO: setTypeListBeforeSoften can't properly express multiple return types,
// but since both returns have the same type it should be okay.
CallOptions.setTypeListBeforeSoften({OpsVT}, VT, true);
CallOptions.setTypeListBeforeSoften({OpsVT}, VT, true)
.setOpsTypeOverrides(CallOpsTypeOverrides);

auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, DL,
/*Chain=*/SDValue());
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,13 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
Args.reserve(Ops.size());

TargetLowering::ArgListEntry Entry;
ArrayRef<Type *> OpsTypeOverrides = CallOptions.OpsTypeOverrides;
for (unsigned i = 0; i < Ops.size(); ++i) {
SDValue NewOp = Ops[i];
Entry.Node = NewOp;
Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext());
Entry.Ty = i < OpsTypeOverrides.size() && OpsTypeOverrides[i]
? OpsTypeOverrides[i]
: Entry.Node.getValueType().getTypeForEVT(*DAG.getContext());
Entry.IsSExt =
shouldSignExtendTypeInLibCall(Entry.Ty, CallOptions.IsSigned);
Entry.IsZExt = !Entry.IsSExt;
Expand Down