[llvm] [SDAG] Avoid creating redundant stack slots when lowering FSINCOS (PR #108401)
Benjamin Maxwell via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 12 07:48:57 PDT 2024
================
@@ -2355,68 +2347,73 @@ static bool useSinCos(SDNode *Node) {
}
/// Issue libcalls to sincos to compute sin / cos pairs.
-void
-SelectionDAGLegalize::ExpandSinCosLibCall(SDNode *Node,
- SmallVectorImpl<SDValue> &Results) {
- RTLIB::Libcall LC;
- switch (Node->getSimpleValueType(0).SimpleTy) {
- default: llvm_unreachable("Unexpected request for libcall!");
- case MVT::f32: LC = RTLIB::SINCOS_F32; break;
- case MVT::f64: LC = RTLIB::SINCOS_F64; break;
- case MVT::f80: LC = RTLIB::SINCOS_F80; break;
- case MVT::f128: LC = RTLIB::SINCOS_F128; break;
- case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128; break;
- }
-
- // The input chain to this libcall is the entry node of the function.
- // Legalizing the call will automatically add the previous call to the
- // dependence.
- SDValue InChain = DAG.getEntryNode();
-
+void SelectionDAGLegalize::ExpandSinCosLibCall(
+ SDNode *Node, SmallVectorImpl<SDValue> &Results) {
EVT RetVT = Node->getValueType(0);
Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
TargetLowering::ArgListTy Args;
- TargetLowering::ArgListEntry Entry;
+ TargetLowering::ArgListEntry Entry{};
+
+ // Find users of the node that store the results. The destination pointers
+ // can be used instead of creating stack allocations.
+ StoreSDNode *SinST = nullptr;
+ StoreSDNode *CosST = nullptr;
+ for (SDNode::use_iterator UI = Node->use_begin(), UE = Node->use_end();
+ UI != UE; ++UI) {
+ SDUse &Use = UI.getUse();
+ SDNode *User = Use.getUser();
+ if (!ISD::isNormalStore(User))
+ continue;
+ auto *ST = cast<StoreSDNode>(User);
+ if (Use.getResNo() == 0)
+ SinST = ST;
+ if (Use.getResNo() == 1)
+ CosST = ST;
+ }
// Pass the argument.
Entry.Node = Node->getOperand(0);
Entry.Ty = RetTy;
- Entry.IsSExt = false;
- Entry.IsZExt = false;
Args.push_back(Entry);
+ auto GetOrCreateOutPointer = [&](StoreSDNode *MaybeStore) {
+ if (MaybeStore)
+ return std::make_pair(MaybeStore->getBasePtr(),
+ MaybeStore->getPointerInfo());
+ SDValue StackSlot = DAG.CreateStackTemporary(RetVT);
+ auto PtrInfo = MachinePointerInfo::getFixedStack(
+ DAG.getMachineFunction(),
+ cast<FrameIndexSDNode>(StackSlot)->getIndex());
+ return std::make_pair(StackSlot, PtrInfo);
+ };
+
// Pass the return address of sin.
- SDValue SinPtr = DAG.CreateStackTemporary(RetVT);
- Entry.Node = SinPtr;
+ auto SinPtr = GetOrCreateOutPointer(SinST);
+ Entry.Node = SinPtr.first;
Entry.Ty = PointerType::getUnqual(RetTy->getContext());
- Entry.IsSExt = false;
- Entry.IsZExt = false;
Args.push_back(Entry);
// Also pass the return address of the cos.
- SDValue CosPtr = DAG.CreateStackTemporary(RetVT);
- Entry.Node = CosPtr;
+ auto CosPtr = GetOrCreateOutPointer(CosST);
+ Entry.Node = CosPtr.first;
Entry.Ty = PointerType::getUnqual(RetTy->getContext());
- Entry.IsSExt = false;
- Entry.IsZExt = false;
Args.push_back(Entry);
- SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
- TLI.getPointerTy(DAG.getDataLayout()));
-
- SDLoc dl(Node);
- TargetLowering::CallLoweringInfo CLI(DAG);
- CLI.setDebugLoc(dl).setChain(InChain).setLibCallee(
- TLI.getLibcallCallingConv(LC), Type::getVoidTy(*DAG.getContext()), Callee,
- std::move(Args));
+ RTLIB::Libcall LC = RTLIB::getFSINCOS(RetVT);
+ auto [Call, Chain] = ExpandLibCall(LC, Node, std::move(Args), false);
- std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
+ // Replace explict stores with the library call.
+ for (StoreSDNode *ST : {SinST, CosST}) {
+ if (ST)
+ DAG.ReplaceAllUsesOfValueWith(SDValue(ST, 0), Chain);
+ }
----------------
MacDue wrote:
Question: Is a safe way to replace a `StoreSDNode`? Does the input chain for the `StoreSDNode` also need to be considered?
https://github.com/llvm/llvm-project/pull/108401
More information about the llvm-commits
mailing list