@@ -2326,15 +2326,7 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
2326
2326
2327
2327
// / Return true if sincos libcall is available.
2328
2328
static bool isSinCosLibcallAvailable (SDNode *Node, const TargetLowering &TLI) {
2329
- RTLIB::Libcall LC;
2330
- switch (Node->getSimpleValueType (0 ).SimpleTy ) {
2331
- default : llvm_unreachable (" Unexpected request for libcall!" );
2332
- case MVT::f32: LC = RTLIB::SINCOS_F32; break ;
2333
- case MVT::f64: LC = RTLIB::SINCOS_F64; break ;
2334
- case MVT::f80: LC = RTLIB::SINCOS_F80; break ;
2335
- case MVT::f128: LC = RTLIB::SINCOS_F128; break ;
2336
- case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128; break ;
2337
- }
2329
+ RTLIB::Libcall LC = RTLIB::getFSINCOS (Node->getSimpleValueType (0 ).SimpleTy );
2338
2330
return TLI.getLibcallName (LC) != nullptr ;
2339
2331
}
2340
2332
@@ -2355,68 +2347,72 @@ static bool useSinCos(SDNode *Node) {
2355
2347
}
2356
2348
2357
2349
// / Issue libcalls to sincos to compute sin / cos pairs.
2358
- void
2359
- SelectionDAGLegalize::ExpandSinCosLibCall (SDNode *Node,
2360
- SmallVectorImpl<SDValue> &Results) {
2361
- RTLIB::Libcall LC;
2362
- switch (Node->getSimpleValueType (0 ).SimpleTy ) {
2363
- default : llvm_unreachable (" Unexpected request for libcall!" );
2364
- case MVT::f32: LC = RTLIB::SINCOS_F32; break ;
2365
- case MVT::f64: LC = RTLIB::SINCOS_F64; break ;
2366
- case MVT::f80: LC = RTLIB::SINCOS_F80; break ;
2367
- case MVT::f128: LC = RTLIB::SINCOS_F128; break ;
2368
- case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128; break ;
2350
+ void SelectionDAGLegalize::ExpandSinCosLibCall (
2351
+ SDNode *Node, SmallVectorImpl<SDValue> &Results) {
2352
+ EVT VT = Node->getValueType (0 );
2353
+ Type *Ty = VT.getTypeForEVT (*DAG.getContext ());
2354
+ RTLIB::Libcall LC = RTLIB::getFSINCOS (VT);
2355
+
2356
+ // Find users of the node that store the results (and share input chains). The
2357
+ // destination pointers can be used instead of creating stack allocations.
2358
+ SDValue StoresInChain{};
2359
+ std::array<StoreSDNode *, 2 > ResultStores = {nullptr };
2360
+ for (SDNode *User : Node->uses ()) {
2361
+ if (!ISD::isNormalStore (User))
2362
+ continue ;
2363
+ auto *ST = cast<StoreSDNode>(User);
2364
+ if (!ST->isSimple () || ST->getAddressSpace () != 0 ||
2365
+ ST->getAlign () < DAG.getDataLayout ().getABITypeAlign (Ty) ||
2366
+ (StoresInChain && ST->getChain () != StoresInChain) ||
2367
+ Node->isPredecessorOf (ST->getChain ().getNode ()))
2368
+ continue ;
2369
+ ResultStores[ST->getValue ().getResNo ()] = ST;
2370
+ StoresInChain = ST->getChain ();
2369
2371
}
2370
2372
2371
- // The input chain to this libcall is the entry node of the function.
2372
- // Legalizing the call will automatically add the previous call to the
2373
- // dependence.
2374
- SDValue InChain = DAG.getEntryNode ();
2375
-
2376
- EVT RetVT = Node->getValueType (0 );
2377
- Type *RetTy = RetVT.getTypeForEVT (*DAG.getContext ());
2378
-
2379
2373
TargetLowering::ArgListTy Args;
2380
- TargetLowering::ArgListEntry Entry;
2374
+ TargetLowering::ArgListEntry Entry{} ;
2381
2375
2382
2376
// Pass the argument.
2383
2377
Entry.Node = Node->getOperand (0 );
2384
- Entry.Ty = RetTy;
2385
- Entry.IsSExt = false ;
2386
- Entry.IsZExt = false ;
2387
- Args.push_back (Entry);
2388
-
2389
- // Pass the return address of sin.
2390
- SDValue SinPtr = DAG.CreateStackTemporary (RetVT);
2391
- Entry.Node = SinPtr;
2392
- Entry.Ty = PointerType::getUnqual (RetTy->getContext ());
2393
- Entry.IsSExt = false ;
2394
- Entry.IsZExt = false ;
2378
+ Entry.Ty = Ty;
2395
2379
Args.push_back (Entry);
2396
2380
2397
- // Also pass the return address of the cos.
2398
- SDValue CosPtr = DAG.CreateStackTemporary (RetVT);
2399
- Entry.Node = CosPtr;
2400
- Entry.Ty = PointerType::getUnqual (RetTy->getContext ());
2401
- Entry.IsSExt = false ;
2402
- Entry.IsZExt = false ;
2403
- Args.push_back (Entry);
2381
+ // Pass the output pointers for sin and cos.
2382
+ SmallVector<SDValue, 2 > ResultPtrs{};
2383
+ for (StoreSDNode *ST : ResultStores) {
2384
+ SDValue ResultPtr = ST ? ST->getBasePtr () : DAG.CreateStackTemporary (VT);
2385
+ Entry.Node = ResultPtr;
2386
+ Entry.Ty = PointerType::getUnqual (Ty->getContext ());
2387
+ Args.push_back (Entry);
2388
+ ResultPtrs.push_back (ResultPtr);
2389
+ }
2404
2390
2391
+ SDLoc DL (Node);
2392
+ SDValue InChain = StoresInChain ? StoresInChain : DAG.getEntryNode ();
2405
2393
SDValue Callee = DAG.getExternalSymbol (TLI.getLibcallName (LC),
2406
2394
TLI.getPointerTy (DAG.getDataLayout ()));
2407
-
2408
- SDLoc dl (Node);
2409
2395
TargetLowering::CallLoweringInfo CLI (DAG);
2410
- CLI.setDebugLoc (dl ).setChain (InChain).setLibCallee (
2396
+ CLI.setDebugLoc (DL ).setChain (InChain).setLibCallee (
2411
2397
TLI.getLibcallCallingConv (LC), Type::getVoidTy (*DAG.getContext ()), Callee,
2412
2398
std::move (Args));
2413
2399
2414
- std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo (CLI);
2400
+ auto [Call, OutChain] = TLI.LowerCallTo (CLI);
2415
2401
2416
- Results.push_back (
2417
- DAG.getLoad (RetVT, dl, CallInfo.second , SinPtr, MachinePointerInfo ()));
2418
- Results.push_back (
2419
- DAG.getLoad (RetVT, dl, CallInfo.second , CosPtr, MachinePointerInfo ()));
2402
+ for (auto [ResNo, ResultPtr] : llvm::enumerate (ResultPtrs)) {
2403
+ MachinePointerInfo PtrInfo;
2404
+ if (StoreSDNode *ST = ResultStores[ResNo]) {
2405
+ // Replace store with the library call.
2406
+ DAG.ReplaceAllUsesOfValueWith (SDValue (ST, 0 ), OutChain);
2407
+ PtrInfo = ST->getPointerInfo ();
2408
+ } else {
2409
+ PtrInfo = MachinePointerInfo::getFixedStack (
2410
+ DAG.getMachineFunction (),
2411
+ cast<FrameIndexSDNode>(ResultPtr)->getIndex ());
2412
+ }
2413
+ SDValue LoadResult = DAG.getLoad (VT, DL, OutChain, ResultPtr, PtrInfo);
2414
+ Results.push_back (LoadResult);
2415
+ }
2420
2416
}
2421
2417
2422
2418
SDValue SelectionDAGLegalize::expandLdexp (SDNode *Node) const {
0 commit comments