From 13c19eac02209a623bfe4008256bc39ad0846c4e Mon Sep 17 00:00:00 2001 From: Benjamin Maxwell Date: Mon, 10 Mar 2025 10:47:31 +0000 Subject: [PATCH] [SDAG] Pass pointer type to libcall expansion for SoftenFloatRes stack slots Solution for: https://github.com/llvm/llvm-project/pull/129264#issuecomment-2710079843 --- llvm/include/llvm/CodeGen/TargetLowering.h | 9 +++++++++ llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 11 +++++++++-- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 5 ++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 2089d47e9cbc8..051848b4acc3a 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4749,6 +4749,8 @@ class TargetLowering : public TargetLoweringBase { // shouldExtendTypeInLibCall can get the original type before soften. ArrayRef OpsVTBeforeSoften; EVT RetVTBeforeSoften; + ArrayRef OpsTypeOverrides; + bool IsSigned : 1; bool DoesNotReturn : 1; bool IsReturnValueUsed : 1; @@ -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 OpsTypes) { + OpsTypeOverrides = OpsTypes; + return *this; + } }; /// This function lowers an abstract call to a function into an actual call. diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index c2107a73301bc..894d717bbbbd5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -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()); @@ -811,6 +814,8 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults( SmallVector OpsVT = {VT}; std::array StackSlots; + SmallVector CallOpsTypeOverrides = {nullptr}; + auto PointerTy = PointerType::getUnqual(*DAG.getContext()); for (unsigned ResNum = 0; ResNum < N->getNumValues(); ++ResNum) { if (ResNum == CallRetResNo) continue; @@ -818,12 +823,14 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults( 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()); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index bd72718c49031..f1649a3903fac 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -157,10 +157,13 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, Args.reserve(Ops.size()); TargetLowering::ArgListEntry Entry; + ArrayRef 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;