[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