|
25 | 25 | #include "llvm/ADT/Twine.h"
|
26 | 26 | #include "llvm/Analysis/AliasAnalysis.h"
|
27 | 27 | #include "llvm/Analysis/MemoryLocation.h"
|
| 28 | +#include "llvm/Analysis/TargetLibraryInfo.h" |
28 | 29 | #include "llvm/Analysis/ValueTracking.h"
|
29 | 30 | #include "llvm/Analysis/VectorUtils.h"
|
30 | 31 | #include "llvm/BinaryFormat/Dwarf.h"
|
@@ -2483,6 +2484,103 @@ SDValue SelectionDAG::getPartialReduceAdd(SDLoc DL, EVT ReducedTy, SDValue Op1,
|
2483 | 2484 | return Subvectors[0];
|
2484 | 2485 | }
|
2485 | 2486 |
|
| 2487 | +bool SelectionDAG::expandFSINCOS(SDNode *Node, |
| 2488 | + SmallVectorImpl<SDValue> &Results) { |
| 2489 | + EVT VT = Node->getValueType(0); |
| 2490 | + LLVMContext *Ctx = getContext(); |
| 2491 | + Type *Ty = VT.getTypeForEVT(*Ctx); |
| 2492 | + RTLIB::Libcall LC = |
| 2493 | + RTLIB::getFSINCOS(VT.isVector() ? VT.getVectorElementType() : VT); |
| 2494 | + |
| 2495 | + const char *LCName = TLI->getLibcallName(LC); |
| 2496 | + if (!LC || !LCName) |
| 2497 | + return false; |
| 2498 | + |
| 2499 | + auto getVecDesc = [&]() -> VecDesc const * { |
| 2500 | + for (bool Masked : {false, true}) { |
| 2501 | + if (VecDesc const *VD = getLibInfo().getVectorMappingInfo( |
| 2502 | + LCName, VT.getVectorElementCount(), Masked)) { |
| 2503 | + return VD; |
| 2504 | + } |
| 2505 | + } |
| 2506 | + return nullptr; |
| 2507 | + }; |
| 2508 | + |
| 2509 | + VecDesc const *VD = nullptr; |
| 2510 | + if (VT.isVector() && !(VD = getVecDesc())) |
| 2511 | + return false; |
| 2512 | + |
| 2513 | + // Find users of the node that store the results (and share input chains). The |
| 2514 | + // destination pointers can be used instead of creating stack allocations. |
| 2515 | + SDValue StoresInChain{}; |
| 2516 | + std::array<StoreSDNode *, 2> ResultStores = {nullptr}; |
| 2517 | + for (SDNode *User : Node->uses()) { |
| 2518 | + if (!ISD::isNormalStore(User)) |
| 2519 | + continue; |
| 2520 | + auto *ST = cast<StoreSDNode>(User); |
| 2521 | + if (!ST->isSimple() || ST->getAddressSpace() != 0 || |
| 2522 | + ST->getAlign() < getDataLayout().getABITypeAlign(Ty->getScalarType()) || |
| 2523 | + (StoresInChain && ST->getChain() != StoresInChain) || |
| 2524 | + Node->isPredecessorOf(ST->getChain().getNode())) |
| 2525 | + continue; |
| 2526 | + ResultStores[ST->getValue().getResNo()] = ST; |
| 2527 | + StoresInChain = ST->getChain(); |
| 2528 | + } |
| 2529 | + |
| 2530 | + TargetLowering::ArgListTy Args; |
| 2531 | + TargetLowering::ArgListEntry Entry{}; |
| 2532 | + |
| 2533 | + // Pass the argument. |
| 2534 | + Entry.Node = Node->getOperand(0); |
| 2535 | + Entry.Ty = Ty; |
| 2536 | + Args.push_back(Entry); |
| 2537 | + |
| 2538 | + // Pass the output pointers for sin and cos. |
| 2539 | + SmallVector<SDValue, 2> ResultPtrs{}; |
| 2540 | + for (StoreSDNode *ST : ResultStores) { |
| 2541 | + SDValue ResultPtr = ST ? ST->getBasePtr() : CreateStackTemporary(VT); |
| 2542 | + Entry.Node = ResultPtr; |
| 2543 | + Entry.Ty = PointerType::getUnqual(Ty->getContext()); |
| 2544 | + Args.push_back(Entry); |
| 2545 | + ResultPtrs.push_back(ResultPtr); |
| 2546 | + } |
| 2547 | + |
| 2548 | + SDLoc DL(Node); |
| 2549 | + |
| 2550 | + if (VD && VD->isMasked()) { |
| 2551 | + EVT MaskVT = TLI->getSetCCResultType(getDataLayout(), *Ctx, VT); |
| 2552 | + Entry.Node = getBoolConstant(true, DL, MaskVT, VT); |
| 2553 | + Entry.Ty = MaskVT.getTypeForEVT(*Ctx); |
| 2554 | + Args.push_back(Entry); |
| 2555 | + } |
| 2556 | + |
| 2557 | + SDValue InChain = StoresInChain ? StoresInChain : getEntryNode(); |
| 2558 | + SDValue Callee = getExternalSymbol(VD ? VD->getVectorFnName().data() : LCName, |
| 2559 | + TLI->getPointerTy(getDataLayout())); |
| 2560 | + TargetLowering::CallLoweringInfo CLI(*this); |
| 2561 | + CLI.setDebugLoc(DL).setChain(InChain).setLibCallee( |
| 2562 | + TLI->getLibcallCallingConv(LC), Type::getVoidTy(*Ctx), Callee, |
| 2563 | + std::move(Args)); |
| 2564 | + |
| 2565 | + auto [Call, OutChain] = TLI->LowerCallTo(CLI); |
| 2566 | + |
| 2567 | + for (auto [ResNo, ResultPtr] : llvm::enumerate(ResultPtrs)) { |
| 2568 | + MachinePointerInfo PtrInfo; |
| 2569 | + if (StoreSDNode *ST = ResultStores[ResNo]) { |
| 2570 | + // Replace store with the library call. |
| 2571 | + ReplaceAllUsesOfValueWith(SDValue(ST, 0), OutChain); |
| 2572 | + PtrInfo = ST->getPointerInfo(); |
| 2573 | + } else { |
| 2574 | + PtrInfo = MachinePointerInfo::getFixedStack( |
| 2575 | + getMachineFunction(), cast<FrameIndexSDNode>(ResultPtr)->getIndex()); |
| 2576 | + } |
| 2577 | + SDValue LoadResult = getLoad(VT, DL, OutChain, ResultPtr, PtrInfo); |
| 2578 | + Results.push_back(LoadResult); |
| 2579 | + } |
| 2580 | + |
| 2581 | + return true; |
| 2582 | +} |
| 2583 | + |
2486 | 2584 | SDValue SelectionDAG::expandVAArg(SDNode *Node) {
|
2487 | 2585 | SDLoc dl(Node);
|
2488 | 2586 | const TargetLowering &TLI = getTargetLoweringInfo();
|
|
0 commit comments