10b57cec5SDimitry Andric //===- llvm/Analysis/IVDescriptors.cpp - IndVar Descriptors -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file "describes" induction and recurrence variables. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Analysis/IVDescriptors.h" 145ffd83dbSDimitry Andric #include "llvm/Analysis/DemandedBits.h" 150b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 160b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h" 170b57cec5SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h" 180b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h" 190b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 200b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 210b57cec5SDimitry Andric #include "llvm/IR/Module.h" 220b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h" 230b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 240b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 250b57cec5SDimitry Andric #include "llvm/Support/KnownBits.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric using namespace llvm::PatternMatch; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric #define DEBUG_TYPE "iv-descriptors" 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric bool RecurrenceDescriptor::areAllUsesIn(Instruction *I, 330b57cec5SDimitry Andric SmallPtrSetImpl<Instruction *> &Set) { 34349cc55cSDimitry Andric for (const Use &Use : I->operands()) 35349cc55cSDimitry Andric if (!Set.count(dyn_cast<Instruction>(Use))) 360b57cec5SDimitry Andric return false; 370b57cec5SDimitry Andric return true; 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric 40e8d8bef9SDimitry Andric bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) { 410b57cec5SDimitry Andric switch (Kind) { 420b57cec5SDimitry Andric default: 430b57cec5SDimitry Andric break; 44e8d8bef9SDimitry Andric case RecurKind::Add: 45e8d8bef9SDimitry Andric case RecurKind::Mul: 46e8d8bef9SDimitry Andric case RecurKind::Or: 47e8d8bef9SDimitry Andric case RecurKind::And: 48e8d8bef9SDimitry Andric case RecurKind::Xor: 49e8d8bef9SDimitry Andric case RecurKind::SMax: 50e8d8bef9SDimitry Andric case RecurKind::SMin: 51e8d8bef9SDimitry Andric case RecurKind::UMax: 52e8d8bef9SDimitry Andric case RecurKind::UMin: 535f757f3fSDimitry Andric case RecurKind::IAnyOf: 545f757f3fSDimitry Andric case RecurKind::FAnyOf: 550b57cec5SDimitry Andric return true; 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric return false; 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 60e8d8bef9SDimitry Andric bool RecurrenceDescriptor::isFloatingPointRecurrenceKind(RecurKind Kind) { 61e8d8bef9SDimitry Andric return (Kind != RecurKind::None) && !isIntegerRecurrenceKind(Kind); 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric /// Determines if Phi may have been type-promoted. If Phi has a single user 650b57cec5SDimitry Andric /// that ANDs the Phi with a type mask, return the user. RT is updated to 660b57cec5SDimitry Andric /// account for the narrower bit width represented by the mask, and the AND 670b57cec5SDimitry Andric /// instruction is added to CI. 680b57cec5SDimitry Andric static Instruction *lookThroughAnd(PHINode *Phi, Type *&RT, 690b57cec5SDimitry Andric SmallPtrSetImpl<Instruction *> &Visited, 700b57cec5SDimitry Andric SmallPtrSetImpl<Instruction *> &CI) { 710b57cec5SDimitry Andric if (!Phi->hasOneUse()) 720b57cec5SDimitry Andric return Phi; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric const APInt *M = nullptr; 750b57cec5SDimitry Andric Instruction *I, *J = cast<Instruction>(Phi->use_begin()->getUser()); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // Matches either I & 2^x-1 or 2^x-1 & I. If we find a match, we update RT 780b57cec5SDimitry Andric // with a new integer type of the corresponding bit width. 79*0fca6ea1SDimitry Andric if (match(J, m_And(m_Instruction(I), m_APInt(M)))) { 800b57cec5SDimitry Andric int32_t Bits = (*M + 1).exactLogBase2(); 810b57cec5SDimitry Andric if (Bits > 0) { 820b57cec5SDimitry Andric RT = IntegerType::get(Phi->getContext(), Bits); 830b57cec5SDimitry Andric Visited.insert(Phi); 840b57cec5SDimitry Andric CI.insert(J); 850b57cec5SDimitry Andric return J; 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric return Phi; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Compute the minimal bit width needed to represent a reduction whose exit 920b57cec5SDimitry Andric /// instruction is given by Exit. 930b57cec5SDimitry Andric static std::pair<Type *, bool> computeRecurrenceType(Instruction *Exit, 940b57cec5SDimitry Andric DemandedBits *DB, 950b57cec5SDimitry Andric AssumptionCache *AC, 960b57cec5SDimitry Andric DominatorTree *DT) { 970b57cec5SDimitry Andric bool IsSigned = false; 98*0fca6ea1SDimitry Andric const DataLayout &DL = Exit->getDataLayout(); 990b57cec5SDimitry Andric uint64_t MaxBitWidth = DL.getTypeSizeInBits(Exit->getType()); 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric if (DB) { 1020b57cec5SDimitry Andric // Use the demanded bits analysis to determine the bits that are live out 1030b57cec5SDimitry Andric // of the exit instruction, rounding up to the nearest power of two. If the 1040b57cec5SDimitry Andric // use of demanded bits results in a smaller bit width, we know the value 1050b57cec5SDimitry Andric // must be positive (i.e., IsSigned = false), because if this were not the 1060b57cec5SDimitry Andric // case, the sign bit would have been demanded. 1070b57cec5SDimitry Andric auto Mask = DB->getDemandedBits(Exit); 10806c3fb27SDimitry Andric MaxBitWidth = Mask.getBitWidth() - Mask.countl_zero(); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric if (MaxBitWidth == DL.getTypeSizeInBits(Exit->getType()) && AC && DT) { 1120b57cec5SDimitry Andric // If demanded bits wasn't able to limit the bit width, we can try to use 1130b57cec5SDimitry Andric // value tracking instead. This can be the case, for example, if the value 1140b57cec5SDimitry Andric // may be negative. 1150b57cec5SDimitry Andric auto NumSignBits = ComputeNumSignBits(Exit, DL, 0, AC, nullptr, DT); 1160b57cec5SDimitry Andric auto NumTypeBits = DL.getTypeSizeInBits(Exit->getType()); 1170b57cec5SDimitry Andric MaxBitWidth = NumTypeBits - NumSignBits; 1180b57cec5SDimitry Andric KnownBits Bits = computeKnownBits(Exit, DL); 1190b57cec5SDimitry Andric if (!Bits.isNonNegative()) { 1200b57cec5SDimitry Andric // If the value is not known to be non-negative, we set IsSigned to true, 1210b57cec5SDimitry Andric // meaning that we will use sext instructions instead of zext 1220b57cec5SDimitry Andric // instructions to restore the original type. 1230b57cec5SDimitry Andric IsSigned = true; 1245f757f3fSDimitry Andric // Make sure at least one sign bit is included in the result, so it 125349cc55cSDimitry Andric // will get properly sign-extended. 1260b57cec5SDimitry Andric ++MaxBitWidth; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric } 12906c3fb27SDimitry Andric MaxBitWidth = llvm::bit_ceil(MaxBitWidth); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric return std::make_pair(Type::getIntNTy(Exit->getContext(), MaxBitWidth), 1320b57cec5SDimitry Andric IsSigned); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /// Collect cast instructions that can be ignored in the vectorizer's cost 1360b57cec5SDimitry Andric /// model, given a reduction exit value and the minimal type in which the 13704eeddc0SDimitry Andric // reduction can be represented. Also search casts to the recurrence type 13804eeddc0SDimitry Andric // to find the minimum width used by the recurrence. 13904eeddc0SDimitry Andric static void collectCastInstrs(Loop *TheLoop, Instruction *Exit, 1400b57cec5SDimitry Andric Type *RecurrenceType, 14104eeddc0SDimitry Andric SmallPtrSetImpl<Instruction *> &Casts, 14204eeddc0SDimitry Andric unsigned &MinWidthCastToRecurTy) { 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric SmallVector<Instruction *, 8> Worklist; 1450b57cec5SDimitry Andric SmallPtrSet<Instruction *, 8> Visited; 1460b57cec5SDimitry Andric Worklist.push_back(Exit); 14704eeddc0SDimitry Andric MinWidthCastToRecurTy = -1U; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric while (!Worklist.empty()) { 1500b57cec5SDimitry Andric Instruction *Val = Worklist.pop_back_val(); 1510b57cec5SDimitry Andric Visited.insert(Val); 15204eeddc0SDimitry Andric if (auto *Cast = dyn_cast<CastInst>(Val)) { 1530b57cec5SDimitry Andric if (Cast->getSrcTy() == RecurrenceType) { 1540b57cec5SDimitry Andric // If the source type of a cast instruction is equal to the recurrence 1550b57cec5SDimitry Andric // type, it will be eliminated, and should be ignored in the vectorizer 1560b57cec5SDimitry Andric // cost model. 1570b57cec5SDimitry Andric Casts.insert(Cast); 1580b57cec5SDimitry Andric continue; 1590b57cec5SDimitry Andric } 16004eeddc0SDimitry Andric if (Cast->getDestTy() == RecurrenceType) { 16104eeddc0SDimitry Andric // The minimum width used by the recurrence is found by checking for 16204eeddc0SDimitry Andric // casts on its operands. The minimum width is used by the vectorizer 16304eeddc0SDimitry Andric // when finding the widest type for in-loop reductions without any 16404eeddc0SDimitry Andric // loads/stores. 16504eeddc0SDimitry Andric MinWidthCastToRecurTy = std::min<unsigned>( 16604eeddc0SDimitry Andric MinWidthCastToRecurTy, Cast->getSrcTy()->getScalarSizeInBits()); 16704eeddc0SDimitry Andric continue; 16804eeddc0SDimitry Andric } 16904eeddc0SDimitry Andric } 1700b57cec5SDimitry Andric // Add all operands to the work list if they are loop-varying values that 1710b57cec5SDimitry Andric // we haven't yet visited. 1720b57cec5SDimitry Andric for (Value *O : cast<User>(Val)->operands()) 1730b57cec5SDimitry Andric if (auto *I = dyn_cast<Instruction>(O)) 1740b57cec5SDimitry Andric if (TheLoop->contains(I) && !Visited.count(I)) 1750b57cec5SDimitry Andric Worklist.push_back(I); 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 179fe6060f1SDimitry Andric // Check if a given Phi node can be recognized as an ordered reduction for 180fe6060f1SDimitry Andric // vectorizing floating point operations without unsafe math. 181fe6060f1SDimitry Andric static bool checkOrderedReduction(RecurKind Kind, Instruction *ExactFPMathInst, 182fe6060f1SDimitry Andric Instruction *Exit, PHINode *Phi) { 1834824e7fdSDimitry Andric // Currently only FAdd and FMulAdd are supported. 1844824e7fdSDimitry Andric if (Kind != RecurKind::FAdd && Kind != RecurKind::FMulAdd) 185fe6060f1SDimitry Andric return false; 186fe6060f1SDimitry Andric 1874824e7fdSDimitry Andric if (Kind == RecurKind::FAdd && Exit->getOpcode() != Instruction::FAdd) 1884824e7fdSDimitry Andric return false; 1894824e7fdSDimitry Andric 1904824e7fdSDimitry Andric if (Kind == RecurKind::FMulAdd && 1914824e7fdSDimitry Andric !RecurrenceDescriptor::isFMulAddIntrinsic(Exit)) 1924824e7fdSDimitry Andric return false; 1934824e7fdSDimitry Andric 1944824e7fdSDimitry Andric // Ensure the exit instruction has only one user other than the reduction PHI 1954824e7fdSDimitry Andric if (Exit != ExactFPMathInst || Exit->hasNUsesOrMore(3)) 196fe6060f1SDimitry Andric return false; 197fe6060f1SDimitry Andric 198fe6060f1SDimitry Andric // The only pattern accepted is the one in which the reduction PHI 199fe6060f1SDimitry Andric // is used as one of the operands of the exit instruction 2004824e7fdSDimitry Andric auto *Op0 = Exit->getOperand(0); 2014824e7fdSDimitry Andric auto *Op1 = Exit->getOperand(1); 2024824e7fdSDimitry Andric if (Kind == RecurKind::FAdd && Op0 != Phi && Op1 != Phi) 2034824e7fdSDimitry Andric return false; 2044824e7fdSDimitry Andric if (Kind == RecurKind::FMulAdd && Exit->getOperand(2) != Phi) 205fe6060f1SDimitry Andric return false; 206fe6060f1SDimitry Andric 207fe6060f1SDimitry Andric LLVM_DEBUG(dbgs() << "LV: Found an ordered reduction: Phi: " << *Phi 208fe6060f1SDimitry Andric << ", ExitInst: " << *Exit << "\n"); 209fe6060f1SDimitry Andric 210fe6060f1SDimitry Andric return true; 211fe6060f1SDimitry Andric } 212fe6060f1SDimitry Andric 21381ad6265SDimitry Andric bool RecurrenceDescriptor::AddReductionVar( 21481ad6265SDimitry Andric PHINode *Phi, RecurKind Kind, Loop *TheLoop, FastMathFlags FuncFMF, 21581ad6265SDimitry Andric RecurrenceDescriptor &RedDes, DemandedBits *DB, AssumptionCache *AC, 21681ad6265SDimitry Andric DominatorTree *DT, ScalarEvolution *SE) { 2170b57cec5SDimitry Andric if (Phi->getNumIncomingValues() != 2) 2180b57cec5SDimitry Andric return false; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric // Reduction variables are only found in the loop header block. 2210b57cec5SDimitry Andric if (Phi->getParent() != TheLoop->getHeader()) 2220b57cec5SDimitry Andric return false; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric // Obtain the reduction start value from the value that comes from the loop 2250b57cec5SDimitry Andric // preheader. 2260b57cec5SDimitry Andric Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader()); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric // ExitInstruction is the single value which is used outside the loop. 2290b57cec5SDimitry Andric // We only allow for a single reduction value to be used outside the loop. 2300b57cec5SDimitry Andric // This includes users of the reduction, variables (which form a cycle 2310b57cec5SDimitry Andric // which ends in the phi node). 2320b57cec5SDimitry Andric Instruction *ExitInstruction = nullptr; 23381ad6265SDimitry Andric 23481ad6265SDimitry Andric // Variable to keep last visited store instruction. By the end of the 23581ad6265SDimitry Andric // algorithm this variable will be either empty or having intermediate 23681ad6265SDimitry Andric // reduction value stored in invariant address. 23781ad6265SDimitry Andric StoreInst *IntermediateStore = nullptr; 23881ad6265SDimitry Andric 2390b57cec5SDimitry Andric // Indicates that we found a reduction operation in our scan. 2400b57cec5SDimitry Andric bool FoundReduxOp = false; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric // We start with the PHI node and scan for all of the users of this 2430b57cec5SDimitry Andric // instruction. All users must be instructions that can be used as reduction 2440b57cec5SDimitry Andric // variables (such as ADD). We must have a single out-of-block user. The cycle 2450b57cec5SDimitry Andric // must include the original PHI. 2460b57cec5SDimitry Andric bool FoundStartPHI = false; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // To recognize min/max patterns formed by a icmp select sequence, we store 2490b57cec5SDimitry Andric // the number of instruction we saw from the recognized min/max pattern, 2500b57cec5SDimitry Andric // to make sure we only see exactly the two instructions. 2510b57cec5SDimitry Andric unsigned NumCmpSelectPatternInst = 0; 2520b57cec5SDimitry Andric InstDesc ReduxDesc(false, nullptr); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric // Data used for determining if the recurrence has been type-promoted. 2550b57cec5SDimitry Andric Type *RecurrenceType = Phi->getType(); 2560b57cec5SDimitry Andric SmallPtrSet<Instruction *, 4> CastInsts; 25704eeddc0SDimitry Andric unsigned MinWidthCastToRecurrenceType; 2580b57cec5SDimitry Andric Instruction *Start = Phi; 2590b57cec5SDimitry Andric bool IsSigned = false; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric SmallPtrSet<Instruction *, 8> VisitedInsts; 2620b57cec5SDimitry Andric SmallVector<Instruction *, 8> Worklist; 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Return early if the recurrence kind does not match the type of Phi. If the 2650b57cec5SDimitry Andric // recurrence kind is arithmetic, we attempt to look through AND operations 2660b57cec5SDimitry Andric // resulting from the type promotion performed by InstCombine. Vector 2670b57cec5SDimitry Andric // operations are not limited to the legal integer widths, so we may be able 2680b57cec5SDimitry Andric // to evaluate the reduction in the narrower width. 2690b57cec5SDimitry Andric if (RecurrenceType->isFloatingPointTy()) { 2700b57cec5SDimitry Andric if (!isFloatingPointRecurrenceKind(Kind)) 2710b57cec5SDimitry Andric return false; 272d409305fSDimitry Andric } else if (RecurrenceType->isIntegerTy()) { 2730b57cec5SDimitry Andric if (!isIntegerRecurrenceKind(Kind)) 2740b57cec5SDimitry Andric return false; 275349cc55cSDimitry Andric if (!isMinMaxRecurrenceKind(Kind)) 2760b57cec5SDimitry Andric Start = lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts); 277d409305fSDimitry Andric } else { 278d409305fSDimitry Andric // Pointer min/max may exist, but it is not supported as a reduction op. 279d409305fSDimitry Andric return false; 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric Worklist.push_back(Start); 2830b57cec5SDimitry Andric VisitedInsts.insert(Start); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // Start with all flags set because we will intersect this with the reduction 2860b57cec5SDimitry Andric // flags from all the reduction operations. 2870b57cec5SDimitry Andric FastMathFlags FMF = FastMathFlags::getFast(); 2880b57cec5SDimitry Andric 28904eeddc0SDimitry Andric // The first instruction in the use-def chain of the Phi node that requires 29004eeddc0SDimitry Andric // exact floating point operations. 29104eeddc0SDimitry Andric Instruction *ExactFPMathInst = nullptr; 29204eeddc0SDimitry Andric 2930b57cec5SDimitry Andric // A value in the reduction can be used: 2940b57cec5SDimitry Andric // - By the reduction: 2950b57cec5SDimitry Andric // - Reduction operation: 2960b57cec5SDimitry Andric // - One use of reduction value (safe). 2970b57cec5SDimitry Andric // - Multiple use of reduction value (not safe). 2980b57cec5SDimitry Andric // - PHI: 2990b57cec5SDimitry Andric // - All uses of the PHI must be the reduction (safe). 3000b57cec5SDimitry Andric // - Otherwise, not safe. 3010b57cec5SDimitry Andric // - By instructions outside of the loop (safe). 3020b57cec5SDimitry Andric // * One value may have several outside users, but all outside 3030b57cec5SDimitry Andric // uses must be of the same value. 30481ad6265SDimitry Andric // - By store instructions with a loop invariant address (safe with 30581ad6265SDimitry Andric // the following restrictions): 30681ad6265SDimitry Andric // * If there are several stores, all must have the same address. 30781ad6265SDimitry Andric // * Final value should be stored in that loop invariant address. 3080b57cec5SDimitry Andric // - By an instruction that is not part of the reduction (not safe). 3090b57cec5SDimitry Andric // This is either: 3100b57cec5SDimitry Andric // * An instruction type other than PHI or the reduction operation. 3110b57cec5SDimitry Andric // * A PHI in the header other than the initial PHI. 3120b57cec5SDimitry Andric while (!Worklist.empty()) { 313e8d8bef9SDimitry Andric Instruction *Cur = Worklist.pop_back_val(); 3140b57cec5SDimitry Andric 31581ad6265SDimitry Andric // Store instructions are allowed iff it is the store of the reduction 31681ad6265SDimitry Andric // value to the same loop invariant memory location. 31781ad6265SDimitry Andric if (auto *SI = dyn_cast<StoreInst>(Cur)) { 31881ad6265SDimitry Andric if (!SE) { 31981ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Store instructions are not processed without " 32081ad6265SDimitry Andric << "Scalar Evolution Analysis\n"); 32181ad6265SDimitry Andric return false; 32281ad6265SDimitry Andric } 32381ad6265SDimitry Andric 32481ad6265SDimitry Andric const SCEV *PtrScev = SE->getSCEV(SI->getPointerOperand()); 32581ad6265SDimitry Andric // Check it is the same address as previous stores 32681ad6265SDimitry Andric if (IntermediateStore) { 32781ad6265SDimitry Andric const SCEV *OtherScev = 32881ad6265SDimitry Andric SE->getSCEV(IntermediateStore->getPointerOperand()); 32981ad6265SDimitry Andric 33081ad6265SDimitry Andric if (OtherScev != PtrScev) { 33181ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Storing reduction value to different addresses " 33281ad6265SDimitry Andric << "inside the loop: " << *SI->getPointerOperand() 33381ad6265SDimitry Andric << " and " 33481ad6265SDimitry Andric << *IntermediateStore->getPointerOperand() << '\n'); 33581ad6265SDimitry Andric return false; 33681ad6265SDimitry Andric } 33781ad6265SDimitry Andric } 33881ad6265SDimitry Andric 33981ad6265SDimitry Andric // Check the pointer is loop invariant 34081ad6265SDimitry Andric if (!SE->isLoopInvariant(PtrScev, TheLoop)) { 34181ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Storing reduction value to non-uniform address " 34281ad6265SDimitry Andric << "inside the loop: " << *SI->getPointerOperand() 34381ad6265SDimitry Andric << '\n'); 34481ad6265SDimitry Andric return false; 34581ad6265SDimitry Andric } 34681ad6265SDimitry Andric 34781ad6265SDimitry Andric // IntermediateStore is always the last store in the loop. 34881ad6265SDimitry Andric IntermediateStore = SI; 34981ad6265SDimitry Andric continue; 35081ad6265SDimitry Andric } 35181ad6265SDimitry Andric 3520b57cec5SDimitry Andric // No Users. 3530b57cec5SDimitry Andric // If the instruction has no users then this is a broken chain and can't be 3540b57cec5SDimitry Andric // a reduction variable. 3550b57cec5SDimitry Andric if (Cur->use_empty()) 3560b57cec5SDimitry Andric return false; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric bool IsAPhi = isa<PHINode>(Cur); 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric // A header PHI use other than the original PHI. 3610b57cec5SDimitry Andric if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent()) 3620b57cec5SDimitry Andric return false; 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric // Reductions of instructions such as Div, and Sub is only possible if the 3650b57cec5SDimitry Andric // LHS is the reduction variable. 3660b57cec5SDimitry Andric if (!Cur->isCommutative() && !IsAPhi && !isa<SelectInst>(Cur) && 3670b57cec5SDimitry Andric !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) && 3680b57cec5SDimitry Andric !VisitedInsts.count(dyn_cast<Instruction>(Cur->getOperand(0)))) 3690b57cec5SDimitry Andric return false; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric // Any reduction instruction must be of one of the allowed kinds. We ignore 3720b57cec5SDimitry Andric // the starting value (the Phi or an AND instruction if the Phi has been 3730b57cec5SDimitry Andric // type-promoted). 3740b57cec5SDimitry Andric if (Cur != Start) { 375349cc55cSDimitry Andric ReduxDesc = 376349cc55cSDimitry Andric isRecurrenceInstr(TheLoop, Phi, Cur, Kind, ReduxDesc, FuncFMF); 37704eeddc0SDimitry Andric ExactFPMathInst = ExactFPMathInst == nullptr 37804eeddc0SDimitry Andric ? ReduxDesc.getExactFPMathInst() 37904eeddc0SDimitry Andric : ExactFPMathInst; 3800b57cec5SDimitry Andric if (!ReduxDesc.isRecurrence()) 3810b57cec5SDimitry Andric return false; 3828bcb0991SDimitry Andric // FIXME: FMF is allowed on phi, but propagation is not handled correctly. 383fe6060f1SDimitry Andric if (isa<FPMathOperator>(ReduxDesc.getPatternInst()) && !IsAPhi) { 384fe6060f1SDimitry Andric FastMathFlags CurFMF = ReduxDesc.getPatternInst()->getFastMathFlags(); 385fe6060f1SDimitry Andric if (auto *Sel = dyn_cast<SelectInst>(ReduxDesc.getPatternInst())) { 386fe6060f1SDimitry Andric // Accept FMF on either fcmp or select of a min/max idiom. 387fe6060f1SDimitry Andric // TODO: This is a hack to work-around the fact that FMF may not be 388fe6060f1SDimitry Andric // assigned/propagated correctly. If that problem is fixed or we 389fe6060f1SDimitry Andric // standardize on fmin/fmax via intrinsics, this can be removed. 390fe6060f1SDimitry Andric if (auto *FCmp = dyn_cast<FCmpInst>(Sel->getCondition())) 391fe6060f1SDimitry Andric CurFMF |= FCmp->getFastMathFlags(); 392fe6060f1SDimitry Andric } 393fe6060f1SDimitry Andric FMF &= CurFMF; 394fe6060f1SDimitry Andric } 395e8d8bef9SDimitry Andric // Update this reduction kind if we matched a new instruction. 396e8d8bef9SDimitry Andric // TODO: Can we eliminate the need for a 2nd InstDesc by keeping 'Kind' 397e8d8bef9SDimitry Andric // state accurate while processing the worklist? 398e8d8bef9SDimitry Andric if (ReduxDesc.getRecKind() != RecurKind::None) 399e8d8bef9SDimitry Andric Kind = ReduxDesc.getRecKind(); 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric bool IsASelect = isa<SelectInst>(Cur); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // A conditional reduction operation must only have 2 or less uses in 4050b57cec5SDimitry Andric // VisitedInsts. 406e8d8bef9SDimitry Andric if (IsASelect && (Kind == RecurKind::FAdd || Kind == RecurKind::FMul) && 4070b57cec5SDimitry Andric hasMultipleUsesOf(Cur, VisitedInsts, 2)) 4080b57cec5SDimitry Andric return false; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric // A reduction operation must only have one use of the reduction value. 411e8d8bef9SDimitry Andric if (!IsAPhi && !IsASelect && !isMinMaxRecurrenceKind(Kind) && 4125f757f3fSDimitry Andric !isAnyOfRecurrenceKind(Kind) && hasMultipleUsesOf(Cur, VisitedInsts, 1)) 4130b57cec5SDimitry Andric return false; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric // All inputs to a PHI node must be a reduction value. 4160b57cec5SDimitry Andric if (IsAPhi && Cur != Phi && !areAllUsesIn(Cur, VisitedInsts)) 4170b57cec5SDimitry Andric return false; 4180b57cec5SDimitry Andric 4195f757f3fSDimitry Andric if ((isIntMinMaxRecurrenceKind(Kind) || Kind == RecurKind::IAnyOf) && 4200b57cec5SDimitry Andric (isa<ICmpInst>(Cur) || isa<SelectInst>(Cur))) 4210b57cec5SDimitry Andric ++NumCmpSelectPatternInst; 4225f757f3fSDimitry Andric if ((isFPMinMaxRecurrenceKind(Kind) || Kind == RecurKind::FAnyOf) && 423e8d8bef9SDimitry Andric (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur))) 4240b57cec5SDimitry Andric ++NumCmpSelectPatternInst; 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric // Check whether we found a reduction operator. 4270b57cec5SDimitry Andric FoundReduxOp |= !IsAPhi && Cur != Start; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric // Process users of current instruction. Push non-PHI nodes after PHI nodes 4300b57cec5SDimitry Andric // onto the stack. This way we are going to have seen all inputs to PHI 4310b57cec5SDimitry Andric // nodes once we get to them. 4320b57cec5SDimitry Andric SmallVector<Instruction *, 8> NonPHIs; 4330b57cec5SDimitry Andric SmallVector<Instruction *, 8> PHIs; 4340b57cec5SDimitry Andric for (User *U : Cur->users()) { 4350b57cec5SDimitry Andric Instruction *UI = cast<Instruction>(U); 4360b57cec5SDimitry Andric 4374824e7fdSDimitry Andric // If the user is a call to llvm.fmuladd then the instruction can only be 4384824e7fdSDimitry Andric // the final operand. 4394824e7fdSDimitry Andric if (isFMulAddIntrinsic(UI)) 4404824e7fdSDimitry Andric if (Cur == UI->getOperand(0) || Cur == UI->getOperand(1)) 4414824e7fdSDimitry Andric return false; 4424824e7fdSDimitry Andric 4430b57cec5SDimitry Andric // Check if we found the exit user. 4440b57cec5SDimitry Andric BasicBlock *Parent = UI->getParent(); 4450b57cec5SDimitry Andric if (!TheLoop->contains(Parent)) { 4460b57cec5SDimitry Andric // If we already know this instruction is used externally, move on to 4470b57cec5SDimitry Andric // the next user. 4480b57cec5SDimitry Andric if (ExitInstruction == Cur) 4490b57cec5SDimitry Andric continue; 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric // Exit if you find multiple values used outside or if the header phi 4520b57cec5SDimitry Andric // node is being used. In this case the user uses the value of the 4530b57cec5SDimitry Andric // previous iteration, in which case we would loose "VF-1" iterations of 4540b57cec5SDimitry Andric // the reduction operation if we vectorize. 4550b57cec5SDimitry Andric if (ExitInstruction != nullptr || Cur == Phi) 4560b57cec5SDimitry Andric return false; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric // The instruction used by an outside user must be the last instruction 4590b57cec5SDimitry Andric // before we feed back to the reduction phi. Otherwise, we loose VF-1 4600b57cec5SDimitry Andric // operations on the value. 4610b57cec5SDimitry Andric if (!is_contained(Phi->operands(), Cur)) 4620b57cec5SDimitry Andric return false; 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric ExitInstruction = Cur; 4650b57cec5SDimitry Andric continue; 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric // Process instructions only once (termination). Each reduction cycle 4690b57cec5SDimitry Andric // value must only be used once, except by phi nodes and min/max 4700b57cec5SDimitry Andric // reductions which are represented as a cmp followed by a select. 4710b57cec5SDimitry Andric InstDesc IgnoredVal(false, nullptr); 4720b57cec5SDimitry Andric if (VisitedInsts.insert(UI).second) { 47381ad6265SDimitry Andric if (isa<PHINode>(UI)) { 4740b57cec5SDimitry Andric PHIs.push_back(UI); 47581ad6265SDimitry Andric } else { 47681ad6265SDimitry Andric StoreInst *SI = dyn_cast<StoreInst>(UI); 47781ad6265SDimitry Andric if (SI && SI->getPointerOperand() == Cur) { 47881ad6265SDimitry Andric // Reduction variable chain can only be stored somewhere but it 47981ad6265SDimitry Andric // can't be used as an address. 48081ad6265SDimitry Andric return false; 48181ad6265SDimitry Andric } 4820b57cec5SDimitry Andric NonPHIs.push_back(UI); 48381ad6265SDimitry Andric } 4840b57cec5SDimitry Andric } else if (!isa<PHINode>(UI) && 4850b57cec5SDimitry Andric ((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) && 4860b57cec5SDimitry Andric !isa<SelectInst>(UI)) || 4870b57cec5SDimitry Andric (!isConditionalRdxPattern(Kind, UI).isRecurrence() && 4885f757f3fSDimitry Andric !isAnyOfPattern(TheLoop, Phi, UI, IgnoredVal) 489349cc55cSDimitry Andric .isRecurrence() && 490349cc55cSDimitry Andric !isMinMaxPattern(UI, Kind, IgnoredVal).isRecurrence()))) 4910b57cec5SDimitry Andric return false; 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric // Remember that we completed the cycle. 4940b57cec5SDimitry Andric if (UI == Phi) 4950b57cec5SDimitry Andric FoundStartPHI = true; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric Worklist.append(PHIs.begin(), PHIs.end()); 4980b57cec5SDimitry Andric Worklist.append(NonPHIs.begin(), NonPHIs.end()); 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // This means we have seen one but not the other instruction of the 502349cc55cSDimitry Andric // pattern or more than just a select and cmp. Zero implies that we saw a 50381ad6265SDimitry Andric // llvm.min/max intrinsic, which is always OK. 504349cc55cSDimitry Andric if (isMinMaxRecurrenceKind(Kind) && NumCmpSelectPatternInst != 2 && 505349cc55cSDimitry Andric NumCmpSelectPatternInst != 0) 506349cc55cSDimitry Andric return false; 507349cc55cSDimitry Andric 5085f757f3fSDimitry Andric if (isAnyOfRecurrenceKind(Kind) && NumCmpSelectPatternInst != 1) 5090b57cec5SDimitry Andric return false; 5100b57cec5SDimitry Andric 51181ad6265SDimitry Andric if (IntermediateStore) { 51281ad6265SDimitry Andric // Check that stored value goes to the phi node again. This way we make sure 51381ad6265SDimitry Andric // that the value stored in IntermediateStore is indeed the final reduction 51481ad6265SDimitry Andric // value. 51581ad6265SDimitry Andric if (!is_contained(Phi->operands(), IntermediateStore->getValueOperand())) { 51681ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Not a final reduction value stored: " 51781ad6265SDimitry Andric << *IntermediateStore << '\n'); 51881ad6265SDimitry Andric return false; 51981ad6265SDimitry Andric } 52081ad6265SDimitry Andric 52181ad6265SDimitry Andric // If there is an exit instruction it's value should be stored in 52281ad6265SDimitry Andric // IntermediateStore 52381ad6265SDimitry Andric if (ExitInstruction && 52481ad6265SDimitry Andric IntermediateStore->getValueOperand() != ExitInstruction) { 52581ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Last store Instruction of reduction value does not " 52681ad6265SDimitry Andric "store last calculated value of the reduction: " 52781ad6265SDimitry Andric << *IntermediateStore << '\n'); 52881ad6265SDimitry Andric return false; 52981ad6265SDimitry Andric } 53081ad6265SDimitry Andric 53181ad6265SDimitry Andric // If all uses are inside the loop (intermediate stores), then the 53281ad6265SDimitry Andric // reduction value after the loop will be the one used in the last store. 53381ad6265SDimitry Andric if (!ExitInstruction) 53481ad6265SDimitry Andric ExitInstruction = cast<Instruction>(IntermediateStore->getValueOperand()); 53581ad6265SDimitry Andric } 53681ad6265SDimitry Andric 5370b57cec5SDimitry Andric if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction) 5380b57cec5SDimitry Andric return false; 5390b57cec5SDimitry Andric 54004eeddc0SDimitry Andric const bool IsOrdered = 54104eeddc0SDimitry Andric checkOrderedReduction(Kind, ExactFPMathInst, ExitInstruction, Phi); 542fe6060f1SDimitry Andric 5430b57cec5SDimitry Andric if (Start != Phi) { 5440b57cec5SDimitry Andric // If the starting value is not the same as the phi node, we speculatively 5450b57cec5SDimitry Andric // looked through an 'and' instruction when evaluating a potential 5460b57cec5SDimitry Andric // arithmetic reduction to determine if it may have been type-promoted. 5470b57cec5SDimitry Andric // 5480b57cec5SDimitry Andric // We now compute the minimal bit width that is required to represent the 5490b57cec5SDimitry Andric // reduction. If this is the same width that was indicated by the 'and', we 5500b57cec5SDimitry Andric // can represent the reduction in the smaller type. The 'and' instruction 5510b57cec5SDimitry Andric // will be eliminated since it will essentially be a cast instruction that 5520b57cec5SDimitry Andric // can be ignore in the cost model. If we compute a different type than we 5530b57cec5SDimitry Andric // did when evaluating the 'and', the 'and' will not be eliminated, and we 5540b57cec5SDimitry Andric // will end up with different kinds of operations in the recurrence 555e8d8bef9SDimitry Andric // expression (e.g., IntegerAND, IntegerADD). We give up if this is 5560b57cec5SDimitry Andric // the case. 5570b57cec5SDimitry Andric // 5580b57cec5SDimitry Andric // The vectorizer relies on InstCombine to perform the actual 5590b57cec5SDimitry Andric // type-shrinking. It does this by inserting instructions to truncate the 5600b57cec5SDimitry Andric // exit value of the reduction to the width indicated by RecurrenceType and 5610b57cec5SDimitry Andric // then extend this value back to the original width. If IsSigned is false, 5620b57cec5SDimitry Andric // a 'zext' instruction will be generated; otherwise, a 'sext' will be 5630b57cec5SDimitry Andric // used. 5640b57cec5SDimitry Andric // 5650b57cec5SDimitry Andric // TODO: We should not rely on InstCombine to rewrite the reduction in the 5660b57cec5SDimitry Andric // smaller type. We should just generate a correctly typed expression 5670b57cec5SDimitry Andric // to begin with. 5680b57cec5SDimitry Andric Type *ComputedType; 5690b57cec5SDimitry Andric std::tie(ComputedType, IsSigned) = 5700b57cec5SDimitry Andric computeRecurrenceType(ExitInstruction, DB, AC, DT); 5710b57cec5SDimitry Andric if (ComputedType != RecurrenceType) 5720b57cec5SDimitry Andric return false; 57304eeddc0SDimitry Andric } 5740b57cec5SDimitry Andric 57504eeddc0SDimitry Andric // Collect cast instructions and the minimum width used by the recurrence. 57604eeddc0SDimitry Andric // If the starting value is not the same as the phi node and the computed 57704eeddc0SDimitry Andric // recurrence type is equal to the recurrence type, the recurrence expression 57804eeddc0SDimitry Andric // will be represented in a narrower or wider type. If there are any cast 57904eeddc0SDimitry Andric // instructions that will be unnecessary, collect them in CastsFromRecurTy. 58004eeddc0SDimitry Andric // Note that the 'and' instruction was already included in this list. 5810b57cec5SDimitry Andric // 5820b57cec5SDimitry Andric // TODO: A better way to represent this may be to tag in some way all the 5830b57cec5SDimitry Andric // instructions that are a part of the reduction. The vectorizer cost 5840b57cec5SDimitry Andric // model could then apply the recurrence type to these instructions, 5850b57cec5SDimitry Andric // without needing a white list of instructions to ignore. 586e8d8bef9SDimitry Andric // This may also be useful for the inloop reductions, if it can be 587e8d8bef9SDimitry Andric // kept simple enough. 58804eeddc0SDimitry Andric collectCastInstrs(TheLoop, ExitInstruction, RecurrenceType, CastInsts, 58904eeddc0SDimitry Andric MinWidthCastToRecurrenceType); 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric // We found a reduction var if we have reached the original phi node and we 5920b57cec5SDimitry Andric // only have a single instruction with out-of-loop users. 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric // The ExitInstruction(Instruction which is allowed to have out-of-loop users) 5950b57cec5SDimitry Andric // is saved as part of the RecurrenceDescriptor. 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric // Save the description of this reduction variable. 59881ad6265SDimitry Andric RecurrenceDescriptor RD(RdxStart, ExitInstruction, IntermediateStore, Kind, 59981ad6265SDimitry Andric FMF, ExactFPMathInst, RecurrenceType, IsSigned, 60081ad6265SDimitry Andric IsOrdered, CastInsts, MinWidthCastToRecurrenceType); 6010b57cec5SDimitry Andric RedDes = RD; 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric return true; 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 606349cc55cSDimitry Andric // We are looking for loops that do something like this: 607349cc55cSDimitry Andric // int r = 0; 608349cc55cSDimitry Andric // for (int i = 0; i < n; i++) { 609349cc55cSDimitry Andric // if (src[i] > 3) 610349cc55cSDimitry Andric // r = 3; 611349cc55cSDimitry Andric // } 612349cc55cSDimitry Andric // where the reduction value (r) only has two states, in this example 0 or 3. 613349cc55cSDimitry Andric // The generated LLVM IR for this type of loop will be like this: 614349cc55cSDimitry Andric // for.body: 615349cc55cSDimitry Andric // %r = phi i32 [ %spec.select, %for.body ], [ 0, %entry ] 616349cc55cSDimitry Andric // ... 617349cc55cSDimitry Andric // %cmp = icmp sgt i32 %5, 3 618349cc55cSDimitry Andric // %spec.select = select i1 %cmp, i32 3, i32 %r 619349cc55cSDimitry Andric // ... 620349cc55cSDimitry Andric // In general we can support vectorization of loops where 'r' flips between 621349cc55cSDimitry Andric // any two non-constants, provided they are loop invariant. The only thing 622349cc55cSDimitry Andric // we actually care about at the end of the loop is whether or not any lane 623349cc55cSDimitry Andric // in the selected vector is different from the start value. The final 624349cc55cSDimitry Andric // across-vector reduction after the loop simply involves choosing the start 625349cc55cSDimitry Andric // value if nothing changed (0 in the example above) or the other selected 626349cc55cSDimitry Andric // value (3 in the example above). 6270b57cec5SDimitry Andric RecurrenceDescriptor::InstDesc 6285f757f3fSDimitry Andric RecurrenceDescriptor::isAnyOfPattern(Loop *Loop, PHINode *OrigPhi, 629349cc55cSDimitry Andric Instruction *I, InstDesc &Prev) { 630349cc55cSDimitry Andric // We must handle the select(cmp(),x,y) as a single instruction. Advance to 631349cc55cSDimitry Andric // the select. 632e8d8bef9SDimitry Andric CmpInst::Predicate Pred; 633e8d8bef9SDimitry Andric if (match(I, m_OneUse(m_Cmp(Pred, m_Value(), m_Value())))) { 634e8d8bef9SDimitry Andric if (auto *Select = dyn_cast<SelectInst>(*I->user_begin())) 635e8d8bef9SDimitry Andric return InstDesc(Select, Prev.getRecKind()); 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric 638*0fca6ea1SDimitry Andric if (!match(I, 639*0fca6ea1SDimitry Andric m_Select(m_Cmp(Pred, m_Value(), m_Value()), m_Value(), m_Value()))) 6400b57cec5SDimitry Andric return InstDesc(false, I); 6410b57cec5SDimitry Andric 642349cc55cSDimitry Andric SelectInst *SI = cast<SelectInst>(I); 643349cc55cSDimitry Andric Value *NonPhi = nullptr; 644349cc55cSDimitry Andric 645349cc55cSDimitry Andric if (OrigPhi == dyn_cast<PHINode>(SI->getTrueValue())) 646349cc55cSDimitry Andric NonPhi = SI->getFalseValue(); 647349cc55cSDimitry Andric else if (OrigPhi == dyn_cast<PHINode>(SI->getFalseValue())) 648349cc55cSDimitry Andric NonPhi = SI->getTrueValue(); 649349cc55cSDimitry Andric else 650349cc55cSDimitry Andric return InstDesc(false, I); 651349cc55cSDimitry Andric 652349cc55cSDimitry Andric // We are looking for selects of the form: 653349cc55cSDimitry Andric // select(cmp(), phi, loop_invariant) or 654349cc55cSDimitry Andric // select(cmp(), loop_invariant, phi) 655349cc55cSDimitry Andric if (!Loop->isLoopInvariant(NonPhi)) 656349cc55cSDimitry Andric return InstDesc(false, I); 657349cc55cSDimitry Andric 6585f757f3fSDimitry Andric return InstDesc(I, isa<ICmpInst>(I->getOperand(0)) ? RecurKind::IAnyOf 6595f757f3fSDimitry Andric : RecurKind::FAnyOf); 660349cc55cSDimitry Andric } 661349cc55cSDimitry Andric 662349cc55cSDimitry Andric RecurrenceDescriptor::InstDesc 663349cc55cSDimitry Andric RecurrenceDescriptor::isMinMaxPattern(Instruction *I, RecurKind Kind, 664349cc55cSDimitry Andric const InstDesc &Prev) { 665349cc55cSDimitry Andric assert((isa<CmpInst>(I) || isa<SelectInst>(I) || isa<CallInst>(I)) && 666349cc55cSDimitry Andric "Expected a cmp or select or call instruction"); 667349cc55cSDimitry Andric if (!isMinMaxRecurrenceKind(Kind)) 668349cc55cSDimitry Andric return InstDesc(false, I); 669349cc55cSDimitry Andric 670349cc55cSDimitry Andric // We must handle the select(cmp()) as a single instruction. Advance to the 671349cc55cSDimitry Andric // select. 672349cc55cSDimitry Andric CmpInst::Predicate Pred; 673349cc55cSDimitry Andric if (match(I, m_OneUse(m_Cmp(Pred, m_Value(), m_Value())))) { 674349cc55cSDimitry Andric if (auto *Select = dyn_cast<SelectInst>(*I->user_begin())) 675349cc55cSDimitry Andric return InstDesc(Select, Prev.getRecKind()); 676349cc55cSDimitry Andric } 677349cc55cSDimitry Andric 678349cc55cSDimitry Andric // Only match select with single use cmp condition, or a min/max intrinsic. 679349cc55cSDimitry Andric if (!isa<IntrinsicInst>(I) && 680349cc55cSDimitry Andric !match(I, m_Select(m_OneUse(m_Cmp(Pred, m_Value(), m_Value())), m_Value(), 681349cc55cSDimitry Andric m_Value()))) 682349cc55cSDimitry Andric return InstDesc(false, I); 683349cc55cSDimitry Andric 6840b57cec5SDimitry Andric // Look for a min/max pattern. 685e8d8bef9SDimitry Andric if (match(I, m_UMin(m_Value(), m_Value()))) 686349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::UMin, I); 687e8d8bef9SDimitry Andric if (match(I, m_UMax(m_Value(), m_Value()))) 688349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::UMax, I); 689e8d8bef9SDimitry Andric if (match(I, m_SMax(m_Value(), m_Value()))) 690349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::SMax, I); 691e8d8bef9SDimitry Andric if (match(I, m_SMin(m_Value(), m_Value()))) 692349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::SMin, I); 693e8d8bef9SDimitry Andric if (match(I, m_OrdFMin(m_Value(), m_Value()))) 694349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::FMin, I); 695e8d8bef9SDimitry Andric if (match(I, m_OrdFMax(m_Value(), m_Value()))) 696349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::FMax, I); 697e8d8bef9SDimitry Andric if (match(I, m_UnordFMin(m_Value(), m_Value()))) 698349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::FMin, I); 699e8d8bef9SDimitry Andric if (match(I, m_UnordFMax(m_Value(), m_Value()))) 700349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::FMax, I); 701349cc55cSDimitry Andric if (match(I, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_Value()))) 702349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::FMin, I); 703349cc55cSDimitry Andric if (match(I, m_Intrinsic<Intrinsic::maxnum>(m_Value(), m_Value()))) 704349cc55cSDimitry Andric return InstDesc(Kind == RecurKind::FMax, I); 70506c3fb27SDimitry Andric if (match(I, m_Intrinsic<Intrinsic::minimum>(m_Value(), m_Value()))) 70606c3fb27SDimitry Andric return InstDesc(Kind == RecurKind::FMinimum, I); 70706c3fb27SDimitry Andric if (match(I, m_Intrinsic<Intrinsic::maximum>(m_Value(), m_Value()))) 70806c3fb27SDimitry Andric return InstDesc(Kind == RecurKind::FMaximum, I); 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric return InstDesc(false, I); 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric /// Returns true if the select instruction has users in the compare-and-add 7140b57cec5SDimitry Andric /// reduction pattern below. The select instruction argument is the last one 7150b57cec5SDimitry Andric /// in the sequence. 7160b57cec5SDimitry Andric /// 7170b57cec5SDimitry Andric /// %sum.1 = phi ... 7180b57cec5SDimitry Andric /// ... 7190b57cec5SDimitry Andric /// %cmp = fcmp pred %0, %CFP 7200b57cec5SDimitry Andric /// %add = fadd %0, %sum.1 7210b57cec5SDimitry Andric /// %sum.2 = select %cmp, %add, %sum.1 7220b57cec5SDimitry Andric RecurrenceDescriptor::InstDesc 723e8d8bef9SDimitry Andric RecurrenceDescriptor::isConditionalRdxPattern(RecurKind Kind, Instruction *I) { 7240b57cec5SDimitry Andric SelectInst *SI = dyn_cast<SelectInst>(I); 7250b57cec5SDimitry Andric if (!SI) 7260b57cec5SDimitry Andric return InstDesc(false, I); 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric CmpInst *CI = dyn_cast<CmpInst>(SI->getCondition()); 7290b57cec5SDimitry Andric // Only handle single use cases for now. 7300b57cec5SDimitry Andric if (!CI || !CI->hasOneUse()) 7310b57cec5SDimitry Andric return InstDesc(false, I); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric Value *TrueVal = SI->getTrueValue(); 7340b57cec5SDimitry Andric Value *FalseVal = SI->getFalseValue(); 7350b57cec5SDimitry Andric // Handle only when either of operands of select instruction is a PHI 7360b57cec5SDimitry Andric // node for now. 7370b57cec5SDimitry Andric if ((isa<PHINode>(*TrueVal) && isa<PHINode>(*FalseVal)) || 7380b57cec5SDimitry Andric (!isa<PHINode>(*TrueVal) && !isa<PHINode>(*FalseVal))) 7390b57cec5SDimitry Andric return InstDesc(false, I); 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric Instruction *I1 = 7420b57cec5SDimitry Andric isa<PHINode>(*TrueVal) ? dyn_cast<Instruction>(FalseVal) 7430b57cec5SDimitry Andric : dyn_cast<Instruction>(TrueVal); 7440b57cec5SDimitry Andric if (!I1 || !I1->isBinaryOp()) 7450b57cec5SDimitry Andric return InstDesc(false, I); 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andric Value *Op1, *Op2; 74806c3fb27SDimitry Andric if (!(((m_FAdd(m_Value(Op1), m_Value(Op2)).match(I1) || 7490b57cec5SDimitry Andric m_FSub(m_Value(Op1), m_Value(Op2)).match(I1)) && 75006c3fb27SDimitry Andric I1->isFast()) || 75106c3fb27SDimitry Andric (m_FMul(m_Value(Op1), m_Value(Op2)).match(I1) && (I1->isFast())) || 75206c3fb27SDimitry Andric ((m_Add(m_Value(Op1), m_Value(Op2)).match(I1) || 75306c3fb27SDimitry Andric m_Sub(m_Value(Op1), m_Value(Op2)).match(I1))) || 75406c3fb27SDimitry Andric (m_Mul(m_Value(Op1), m_Value(Op2)).match(I1)))) 7550b57cec5SDimitry Andric return InstDesc(false, I); 75606c3fb27SDimitry Andric 75706c3fb27SDimitry Andric Instruction *IPhi = isa<PHINode>(*Op1) ? dyn_cast<Instruction>(Op1) 75806c3fb27SDimitry Andric : dyn_cast<Instruction>(Op2); 75906c3fb27SDimitry Andric if (!IPhi || IPhi != FalseVal) 76006c3fb27SDimitry Andric return InstDesc(false, I); 76106c3fb27SDimitry Andric 76206c3fb27SDimitry Andric return InstDesc(true, SI); 7630b57cec5SDimitry Andric } 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric RecurrenceDescriptor::InstDesc 766349cc55cSDimitry Andric RecurrenceDescriptor::isRecurrenceInstr(Loop *L, PHINode *OrigPhi, 767349cc55cSDimitry Andric Instruction *I, RecurKind Kind, 768349cc55cSDimitry Andric InstDesc &Prev, FastMathFlags FuncFMF) { 769349cc55cSDimitry Andric assert(Prev.getRecKind() == RecurKind::None || Prev.getRecKind() == Kind); 7700b57cec5SDimitry Andric switch (I->getOpcode()) { 7710b57cec5SDimitry Andric default: 7720b57cec5SDimitry Andric return InstDesc(false, I); 7730b57cec5SDimitry Andric case Instruction::PHI: 774fe6060f1SDimitry Andric return InstDesc(I, Prev.getRecKind(), Prev.getExactFPMathInst()); 7750b57cec5SDimitry Andric case Instruction::Sub: 7760b57cec5SDimitry Andric case Instruction::Add: 777e8d8bef9SDimitry Andric return InstDesc(Kind == RecurKind::Add, I); 7780b57cec5SDimitry Andric case Instruction::Mul: 779e8d8bef9SDimitry Andric return InstDesc(Kind == RecurKind::Mul, I); 7800b57cec5SDimitry Andric case Instruction::And: 781e8d8bef9SDimitry Andric return InstDesc(Kind == RecurKind::And, I); 7820b57cec5SDimitry Andric case Instruction::Or: 783e8d8bef9SDimitry Andric return InstDesc(Kind == RecurKind::Or, I); 7840b57cec5SDimitry Andric case Instruction::Xor: 785e8d8bef9SDimitry Andric return InstDesc(Kind == RecurKind::Xor, I); 786e8d8bef9SDimitry Andric case Instruction::FDiv: 7870b57cec5SDimitry Andric case Instruction::FMul: 788fe6060f1SDimitry Andric return InstDesc(Kind == RecurKind::FMul, I, 789fe6060f1SDimitry Andric I->hasAllowReassoc() ? nullptr : I); 7900b57cec5SDimitry Andric case Instruction::FSub: 7910b57cec5SDimitry Andric case Instruction::FAdd: 792fe6060f1SDimitry Andric return InstDesc(Kind == RecurKind::FAdd, I, 793fe6060f1SDimitry Andric I->hasAllowReassoc() ? nullptr : I); 7940b57cec5SDimitry Andric case Instruction::Select: 79506c3fb27SDimitry Andric if (Kind == RecurKind::FAdd || Kind == RecurKind::FMul || 79606c3fb27SDimitry Andric Kind == RecurKind::Add || Kind == RecurKind::Mul) 7970b57cec5SDimitry Andric return isConditionalRdxPattern(Kind, I); 798bdd1243dSDimitry Andric [[fallthrough]]; 7990b57cec5SDimitry Andric case Instruction::FCmp: 8000b57cec5SDimitry Andric case Instruction::ICmp: 801349cc55cSDimitry Andric case Instruction::Call: 8025f757f3fSDimitry Andric if (isAnyOfRecurrenceKind(Kind)) 8035f757f3fSDimitry Andric return isAnyOfPattern(L, OrigPhi, I, Prev); 80406c3fb27SDimitry Andric auto HasRequiredFMF = [&]() { 80506c3fb27SDimitry Andric if (FuncFMF.noNaNs() && FuncFMF.noSignedZeros()) 80606c3fb27SDimitry Andric return true; 80706c3fb27SDimitry Andric if (isa<FPMathOperator>(I) && I->hasNoNaNs() && I->hasNoSignedZeros()) 80806c3fb27SDimitry Andric return true; 80906c3fb27SDimitry Andric // minimum and maximum intrinsics do not require nsz and nnan flags since 81006c3fb27SDimitry Andric // NaN and signed zeroes are propagated in the intrinsic implementation. 81106c3fb27SDimitry Andric return match(I, m_Intrinsic<Intrinsic::minimum>(m_Value(), m_Value())) || 81206c3fb27SDimitry Andric match(I, m_Intrinsic<Intrinsic::maximum>(m_Value(), m_Value())); 81306c3fb27SDimitry Andric }; 814fe6060f1SDimitry Andric if (isIntMinMaxRecurrenceKind(Kind) || 81506c3fb27SDimitry Andric (HasRequiredFMF() && isFPMinMaxRecurrenceKind(Kind))) 816349cc55cSDimitry Andric return isMinMaxPattern(I, Kind, Prev); 8174824e7fdSDimitry Andric else if (isFMulAddIntrinsic(I)) 8184824e7fdSDimitry Andric return InstDesc(Kind == RecurKind::FMulAdd, I, 8194824e7fdSDimitry Andric I->hasAllowReassoc() ? nullptr : I); 820fe6060f1SDimitry Andric return InstDesc(false, I); 8210b57cec5SDimitry Andric } 8220b57cec5SDimitry Andric } 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric bool RecurrenceDescriptor::hasMultipleUsesOf( 8250b57cec5SDimitry Andric Instruction *I, SmallPtrSetImpl<Instruction *> &Insts, 8260b57cec5SDimitry Andric unsigned MaxNumUses) { 8270b57cec5SDimitry Andric unsigned NumUses = 0; 828fe6060f1SDimitry Andric for (const Use &U : I->operands()) { 829fe6060f1SDimitry Andric if (Insts.count(dyn_cast<Instruction>(U))) 8300b57cec5SDimitry Andric ++NumUses; 8310b57cec5SDimitry Andric if (NumUses > MaxNumUses) 8320b57cec5SDimitry Andric return true; 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric return false; 8360b57cec5SDimitry Andric } 837fe6060f1SDimitry Andric 8380b57cec5SDimitry Andric bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, 8390b57cec5SDimitry Andric RecurrenceDescriptor &RedDes, 8400b57cec5SDimitry Andric DemandedBits *DB, AssumptionCache *AC, 84181ad6265SDimitry Andric DominatorTree *DT, 84281ad6265SDimitry Andric ScalarEvolution *SE) { 8430b57cec5SDimitry Andric BasicBlock *Header = TheLoop->getHeader(); 8440b57cec5SDimitry Andric Function &F = *Header->getParent(); 845fe6060f1SDimitry Andric FastMathFlags FMF; 846fe6060f1SDimitry Andric FMF.setNoNaNs( 847fe6060f1SDimitry Andric F.getFnAttribute("no-nans-fp-math").getValueAsBool()); 848fe6060f1SDimitry Andric FMF.setNoSignedZeros( 849fe6060f1SDimitry Andric F.getFnAttribute("no-signed-zeros-fp-math").getValueAsBool()); 8500b57cec5SDimitry Andric 85181ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::Add, TheLoop, FMF, RedDes, DB, AC, DT, 85281ad6265SDimitry Andric SE)) { 8530b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n"); 8540b57cec5SDimitry Andric return true; 8550b57cec5SDimitry Andric } 85681ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::Mul, TheLoop, FMF, RedDes, DB, AC, DT, 85781ad6265SDimitry Andric SE)) { 8580b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n"); 8590b57cec5SDimitry Andric return true; 8600b57cec5SDimitry Andric } 86181ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::Or, TheLoop, FMF, RedDes, DB, AC, DT, 86281ad6265SDimitry Andric SE)) { 8630b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n"); 8640b57cec5SDimitry Andric return true; 8650b57cec5SDimitry Andric } 86681ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::And, TheLoop, FMF, RedDes, DB, AC, DT, 86781ad6265SDimitry Andric SE)) { 8680b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n"); 8690b57cec5SDimitry Andric return true; 8700b57cec5SDimitry Andric } 87181ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::Xor, TheLoop, FMF, RedDes, DB, AC, DT, 87281ad6265SDimitry Andric SE)) { 8730b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n"); 8740b57cec5SDimitry Andric return true; 8750b57cec5SDimitry Andric } 87681ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::SMax, TheLoop, FMF, RedDes, DB, AC, DT, 87781ad6265SDimitry Andric SE)) { 878e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Found a SMAX reduction PHI." << *Phi << "\n"); 8790b57cec5SDimitry Andric return true; 8800b57cec5SDimitry Andric } 88181ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::SMin, TheLoop, FMF, RedDes, DB, AC, DT, 88281ad6265SDimitry Andric SE)) { 883e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Found a SMIN reduction PHI." << *Phi << "\n"); 884e8d8bef9SDimitry Andric return true; 885e8d8bef9SDimitry Andric } 88681ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::UMax, TheLoop, FMF, RedDes, DB, AC, DT, 88781ad6265SDimitry Andric SE)) { 888e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Found a UMAX reduction PHI." << *Phi << "\n"); 889e8d8bef9SDimitry Andric return true; 890e8d8bef9SDimitry Andric } 89181ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::UMin, TheLoop, FMF, RedDes, DB, AC, DT, 89281ad6265SDimitry Andric SE)) { 893e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Found a UMIN reduction PHI." << *Phi << "\n"); 894e8d8bef9SDimitry Andric return true; 895e8d8bef9SDimitry Andric } 8965f757f3fSDimitry Andric if (AddReductionVar(Phi, RecurKind::IAnyOf, TheLoop, FMF, RedDes, DB, AC, DT, 8975f757f3fSDimitry Andric SE)) { 898349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Found an integer conditional select reduction PHI." 899349cc55cSDimitry Andric << *Phi << "\n"); 900349cc55cSDimitry Andric return true; 901349cc55cSDimitry Andric } 90281ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::FMul, TheLoop, FMF, RedDes, DB, AC, DT, 90381ad6265SDimitry Andric SE)) { 9040b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n"); 9050b57cec5SDimitry Andric return true; 9060b57cec5SDimitry Andric } 90781ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::FAdd, TheLoop, FMF, RedDes, DB, AC, DT, 90881ad6265SDimitry Andric SE)) { 9090b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n"); 9100b57cec5SDimitry Andric return true; 9110b57cec5SDimitry Andric } 91281ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::FMax, TheLoop, FMF, RedDes, DB, AC, DT, 91381ad6265SDimitry Andric SE)) { 914e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Found a float MAX reduction PHI." << *Phi << "\n"); 915e8d8bef9SDimitry Andric return true; 916e8d8bef9SDimitry Andric } 91781ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::FMin, TheLoop, FMF, RedDes, DB, AC, DT, 91881ad6265SDimitry Andric SE)) { 919e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Found a float MIN reduction PHI." << *Phi << "\n"); 9200b57cec5SDimitry Andric return true; 9210b57cec5SDimitry Andric } 9225f757f3fSDimitry Andric if (AddReductionVar(Phi, RecurKind::FAnyOf, TheLoop, FMF, RedDes, DB, AC, DT, 9235f757f3fSDimitry Andric SE)) { 924349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Found a float conditional select reduction PHI." 925349cc55cSDimitry Andric << " PHI." << *Phi << "\n"); 926349cc55cSDimitry Andric return true; 927349cc55cSDimitry Andric } 92881ad6265SDimitry Andric if (AddReductionVar(Phi, RecurKind::FMulAdd, TheLoop, FMF, RedDes, DB, AC, DT, 92981ad6265SDimitry Andric SE)) { 9304824e7fdSDimitry Andric LLVM_DEBUG(dbgs() << "Found an FMulAdd reduction PHI." << *Phi << "\n"); 9314824e7fdSDimitry Andric return true; 9324824e7fdSDimitry Andric } 93306c3fb27SDimitry Andric if (AddReductionVar(Phi, RecurKind::FMaximum, TheLoop, FMF, RedDes, DB, AC, DT, 93406c3fb27SDimitry Andric SE)) { 93506c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << "Found a float MAXIMUM reduction PHI." << *Phi << "\n"); 93606c3fb27SDimitry Andric return true; 93706c3fb27SDimitry Andric } 93806c3fb27SDimitry Andric if (AddReductionVar(Phi, RecurKind::FMinimum, TheLoop, FMF, RedDes, DB, AC, DT, 93906c3fb27SDimitry Andric SE)) { 94006c3fb27SDimitry Andric LLVM_DEBUG(dbgs() << "Found a float MINIMUM reduction PHI." << *Phi << "\n"); 94106c3fb27SDimitry Andric return true; 94206c3fb27SDimitry Andric } 9430b57cec5SDimitry Andric // Not a reduction of known type. 9440b57cec5SDimitry Andric return false; 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric 94706c3fb27SDimitry Andric bool RecurrenceDescriptor::isFixedOrderRecurrence(PHINode *Phi, Loop *TheLoop, 94806c3fb27SDimitry Andric DominatorTree *DT) { 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric // Ensure the phi node is in the loop header and has two incoming values. 9510b57cec5SDimitry Andric if (Phi->getParent() != TheLoop->getHeader() || 9520b57cec5SDimitry Andric Phi->getNumIncomingValues() != 2) 9530b57cec5SDimitry Andric return false; 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric // Ensure the loop has a preheader and a single latch block. The loop 9560b57cec5SDimitry Andric // vectorizer will need the latch to set up the next iteration of the loop. 9570b57cec5SDimitry Andric auto *Preheader = TheLoop->getLoopPreheader(); 9580b57cec5SDimitry Andric auto *Latch = TheLoop->getLoopLatch(); 9590b57cec5SDimitry Andric if (!Preheader || !Latch) 9600b57cec5SDimitry Andric return false; 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric // Ensure the phi node's incoming blocks are the loop preheader and latch. 9630b57cec5SDimitry Andric if (Phi->getBasicBlockIndex(Preheader) < 0 || 9640b57cec5SDimitry Andric Phi->getBasicBlockIndex(Latch) < 0) 9650b57cec5SDimitry Andric return false; 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric // Get the previous value. The previous value comes from the latch edge while 968bdd1243dSDimitry Andric // the initial value comes from the preheader edge. 9690b57cec5SDimitry Andric auto *Previous = dyn_cast<Instruction>(Phi->getIncomingValueForBlock(Latch)); 970bdd1243dSDimitry Andric 971bdd1243dSDimitry Andric // If Previous is a phi in the header, go through incoming values from the 972bdd1243dSDimitry Andric // latch until we find a non-phi value. Use this as the new Previous, all uses 973bdd1243dSDimitry Andric // in the header will be dominated by the original phi, but need to be moved 974bdd1243dSDimitry Andric // after the non-phi previous value. 975bdd1243dSDimitry Andric SmallPtrSet<PHINode *, 4> SeenPhis; 976bdd1243dSDimitry Andric while (auto *PrevPhi = dyn_cast_or_null<PHINode>(Previous)) { 977bdd1243dSDimitry Andric if (PrevPhi->getParent() != Phi->getParent()) 978bdd1243dSDimitry Andric return false; 979bdd1243dSDimitry Andric if (!SeenPhis.insert(PrevPhi).second) 980bdd1243dSDimitry Andric return false; 981bdd1243dSDimitry Andric Previous = dyn_cast<Instruction>(PrevPhi->getIncomingValueForBlock(Latch)); 982bdd1243dSDimitry Andric } 983bdd1243dSDimitry Andric 98406c3fb27SDimitry Andric if (!Previous || !TheLoop->contains(Previous) || isa<PHINode>(Previous)) 9850b57cec5SDimitry Andric return false; 9860b57cec5SDimitry Andric 987fe6060f1SDimitry Andric // Ensure every user of the phi node (recursively) is dominated by the 988fe6060f1SDimitry Andric // previous value. The dominance requirement ensures the loop vectorizer will 989fe6060f1SDimitry Andric // not need to vectorize the initial value prior to the first iteration of the 990fe6060f1SDimitry Andric // loop. 991fe6060f1SDimitry Andric // TODO: Consider extending this sinking to handle memory instructions. 992480093f4SDimitry Andric 99306c3fb27SDimitry Andric SmallPtrSet<Value *, 8> Seen; 994fe6060f1SDimitry Andric BasicBlock *PhiBB = Phi->getParent(); 995fe6060f1SDimitry Andric SmallVector<Instruction *, 8> WorkList; 996fe6060f1SDimitry Andric auto TryToPushSinkCandidate = [&](Instruction *SinkCandidate) { 997fe6060f1SDimitry Andric // Cyclic dependence. 998fe6060f1SDimitry Andric if (Previous == SinkCandidate) 999480093f4SDimitry Andric return false; 1000480093f4SDimitry Andric 100106c3fb27SDimitry Andric if (!Seen.insert(SinkCandidate).second) 100206c3fb27SDimitry Andric return true; 1003fe6060f1SDimitry Andric if (DT->dominates(Previous, 1004fe6060f1SDimitry Andric SinkCandidate)) // We already are good w/o sinking. 1005fe6060f1SDimitry Andric return true; 1006fe6060f1SDimitry Andric 1007fe6060f1SDimitry Andric if (SinkCandidate->getParent() != PhiBB || 1008fe6060f1SDimitry Andric SinkCandidate->mayHaveSideEffects() || 1009fe6060f1SDimitry Andric SinkCandidate->mayReadFromMemory() || SinkCandidate->isTerminator()) 1010480093f4SDimitry Andric return false; 1011480093f4SDimitry Andric 1012fe6060f1SDimitry Andric // If we reach a PHI node that is not dominated by Previous, we reached a 1013fe6060f1SDimitry Andric // header PHI. No need for sinking. 1014fe6060f1SDimitry Andric if (isa<PHINode>(SinkCandidate)) 1015480093f4SDimitry Andric return true; 1016480093f4SDimitry Andric 1017fe6060f1SDimitry Andric // Sink User tentatively and check its users 1018fe6060f1SDimitry Andric WorkList.push_back(SinkCandidate); 1019fe6060f1SDimitry Andric return true; 1020fe6060f1SDimitry Andric }; 1021fe6060f1SDimitry Andric 1022fe6060f1SDimitry Andric WorkList.push_back(Phi); 1023fe6060f1SDimitry Andric // Try to recursively sink instructions and their users after Previous. 1024fe6060f1SDimitry Andric while (!WorkList.empty()) { 1025fe6060f1SDimitry Andric Instruction *Current = WorkList.pop_back_val(); 1026fe6060f1SDimitry Andric for (User *User : Current->users()) { 1027fe6060f1SDimitry Andric if (!TryToPushSinkCandidate(cast<Instruction>(User))) 1028fe6060f1SDimitry Andric return false; 1029fe6060f1SDimitry Andric } 1030fe6060f1SDimitry Andric } 1031fe6060f1SDimitry Andric 10320b57cec5SDimitry Andric return true; 10330b57cec5SDimitry Andric } 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric /// This function returns the identity element (or neutral element) for 10360b57cec5SDimitry Andric /// the operation K. 1037349cc55cSDimitry Andric Value *RecurrenceDescriptor::getRecurrenceIdentity(RecurKind K, Type *Tp, 10380eae32dcSDimitry Andric FastMathFlags FMF) const { 10390b57cec5SDimitry Andric switch (K) { 1040e8d8bef9SDimitry Andric case RecurKind::Xor: 1041e8d8bef9SDimitry Andric case RecurKind::Add: 1042e8d8bef9SDimitry Andric case RecurKind::Or: 10430b57cec5SDimitry Andric // Adding, Xoring, Oring zero to a number does not change it. 10440b57cec5SDimitry Andric return ConstantInt::get(Tp, 0); 1045e8d8bef9SDimitry Andric case RecurKind::Mul: 10460b57cec5SDimitry Andric // Multiplying a number by 1 does not change it. 10470b57cec5SDimitry Andric return ConstantInt::get(Tp, 1); 1048e8d8bef9SDimitry Andric case RecurKind::And: 10490b57cec5SDimitry Andric // AND-ing a number with an all-1 value does not change it. 10500b57cec5SDimitry Andric return ConstantInt::get(Tp, -1, true); 1051e8d8bef9SDimitry Andric case RecurKind::FMul: 10520b57cec5SDimitry Andric // Multiplying a number by 1 does not change it. 10530b57cec5SDimitry Andric return ConstantFP::get(Tp, 1.0L); 10544824e7fdSDimitry Andric case RecurKind::FMulAdd: 1055e8d8bef9SDimitry Andric case RecurKind::FAdd: 10560b57cec5SDimitry Andric // Adding zero to a number does not change it. 1057fe6060f1SDimitry Andric // FIXME: Ideally we should not need to check FMF for FAdd and should always 1058fe6060f1SDimitry Andric // use -0.0. However, this will currently result in mixed vectors of 0.0/-0.0. 1059fe6060f1SDimitry Andric // Instead, we should ensure that 1) the FMF from FAdd are propagated to the PHI 1060fe6060f1SDimitry Andric // nodes where possible, and 2) PHIs with the nsz flag + -0.0 use 0.0. This would 1061fe6060f1SDimitry Andric // mean we can then remove the check for noSignedZeros() below (see D98963). 1062fe6060f1SDimitry Andric if (FMF.noSignedZeros()) 10630b57cec5SDimitry Andric return ConstantFP::get(Tp, 0.0L); 1064fe6060f1SDimitry Andric return ConstantFP::get(Tp, -0.0L); 1065e8d8bef9SDimitry Andric case RecurKind::UMin: 106606c3fb27SDimitry Andric return ConstantInt::get(Tp, -1, true); 1067e8d8bef9SDimitry Andric case RecurKind::UMax: 1068e8d8bef9SDimitry Andric return ConstantInt::get(Tp, 0); 1069e8d8bef9SDimitry Andric case RecurKind::SMin: 1070e8d8bef9SDimitry Andric return ConstantInt::get(Tp, 1071e8d8bef9SDimitry Andric APInt::getSignedMaxValue(Tp->getIntegerBitWidth())); 1072e8d8bef9SDimitry Andric case RecurKind::SMax: 1073e8d8bef9SDimitry Andric return ConstantInt::get(Tp, 1074e8d8bef9SDimitry Andric APInt::getSignedMinValue(Tp->getIntegerBitWidth())); 1075e8d8bef9SDimitry Andric case RecurKind::FMin: 1076bdd1243dSDimitry Andric assert((FMF.noNaNs() && FMF.noSignedZeros()) && 1077bdd1243dSDimitry Andric "nnan, nsz is expected to be set for FP min reduction."); 1078bdd1243dSDimitry Andric return ConstantFP::getInfinity(Tp, false /*Negative*/); 1079e8d8bef9SDimitry Andric case RecurKind::FMax: 1080bdd1243dSDimitry Andric assert((FMF.noNaNs() && FMF.noSignedZeros()) && 1081bdd1243dSDimitry Andric "nnan, nsz is expected to be set for FP max reduction."); 1082bdd1243dSDimitry Andric return ConstantFP::getInfinity(Tp, true /*Negative*/); 108306c3fb27SDimitry Andric case RecurKind::FMinimum: 108406c3fb27SDimitry Andric return ConstantFP::getInfinity(Tp, false /*Negative*/); 108506c3fb27SDimitry Andric case RecurKind::FMaximum: 108606c3fb27SDimitry Andric return ConstantFP::getInfinity(Tp, true /*Negative*/); 10875f757f3fSDimitry Andric case RecurKind::IAnyOf: 10885f757f3fSDimitry Andric case RecurKind::FAnyOf: 1089349cc55cSDimitry Andric return getRecurrenceStartValue(); 1090349cc55cSDimitry Andric break; 10910b57cec5SDimitry Andric default: 10920b57cec5SDimitry Andric llvm_unreachable("Unknown recurrence kind"); 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric 1096e8d8bef9SDimitry Andric unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) { 10970b57cec5SDimitry Andric switch (Kind) { 1098e8d8bef9SDimitry Andric case RecurKind::Add: 10990b57cec5SDimitry Andric return Instruction::Add; 1100e8d8bef9SDimitry Andric case RecurKind::Mul: 11010b57cec5SDimitry Andric return Instruction::Mul; 1102e8d8bef9SDimitry Andric case RecurKind::Or: 11030b57cec5SDimitry Andric return Instruction::Or; 1104e8d8bef9SDimitry Andric case RecurKind::And: 11050b57cec5SDimitry Andric return Instruction::And; 1106e8d8bef9SDimitry Andric case RecurKind::Xor: 11070b57cec5SDimitry Andric return Instruction::Xor; 1108e8d8bef9SDimitry Andric case RecurKind::FMul: 11090b57cec5SDimitry Andric return Instruction::FMul; 11104824e7fdSDimitry Andric case RecurKind::FMulAdd: 1111e8d8bef9SDimitry Andric case RecurKind::FAdd: 11120b57cec5SDimitry Andric return Instruction::FAdd; 1113e8d8bef9SDimitry Andric case RecurKind::SMax: 1114e8d8bef9SDimitry Andric case RecurKind::SMin: 1115e8d8bef9SDimitry Andric case RecurKind::UMax: 1116e8d8bef9SDimitry Andric case RecurKind::UMin: 11175f757f3fSDimitry Andric case RecurKind::IAnyOf: 11180b57cec5SDimitry Andric return Instruction::ICmp; 1119e8d8bef9SDimitry Andric case RecurKind::FMax: 1120e8d8bef9SDimitry Andric case RecurKind::FMin: 112106c3fb27SDimitry Andric case RecurKind::FMaximum: 112206c3fb27SDimitry Andric case RecurKind::FMinimum: 11235f757f3fSDimitry Andric case RecurKind::FAnyOf: 11240b57cec5SDimitry Andric return Instruction::FCmp; 11250b57cec5SDimitry Andric default: 11260b57cec5SDimitry Andric llvm_unreachable("Unknown recurrence operation"); 11270b57cec5SDimitry Andric } 11280b57cec5SDimitry Andric } 11290b57cec5SDimitry Andric 1130e8d8bef9SDimitry Andric SmallVector<Instruction *, 4> 1131e8d8bef9SDimitry Andric RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const { 1132e8d8bef9SDimitry Andric SmallVector<Instruction *, 4> ReductionOperations; 1133e8d8bef9SDimitry Andric unsigned RedOp = getOpcode(Kind); 1134e8d8bef9SDimitry Andric 1135e8d8bef9SDimitry Andric // Search down from the Phi to the LoopExitInstr, looking for instructions 1136e8d8bef9SDimitry Andric // with a single user of the correct type for the reduction. 1137e8d8bef9SDimitry Andric 1138e8d8bef9SDimitry Andric // Note that we check that the type of the operand is correct for each item in 1139e8d8bef9SDimitry Andric // the chain, including the last (the loop exit value). This can come up from 1140e8d8bef9SDimitry Andric // sub, which would otherwise be treated as an add reduction. MinMax also need 1141e8d8bef9SDimitry Andric // to check for a pair of icmp/select, for which we use getNextInstruction and 1142e8d8bef9SDimitry Andric // isCorrectOpcode functions to step the right number of instruction, and 1143e8d8bef9SDimitry Andric // check the icmp/select pair. 114481ad6265SDimitry Andric // FIXME: We also do not attempt to look through Select's yet, which might 1145e8d8bef9SDimitry Andric // be part of the reduction chain, or attempt to looks through And's to find a 1146e8d8bef9SDimitry Andric // smaller bitwidth. Subs are also currently not allowed (which are usually 1147e8d8bef9SDimitry Andric // treated as part of a add reduction) as they are expected to generally be 1148e8d8bef9SDimitry Andric // more expensive than out-of-loop reductions, and need to be costed more 1149e8d8bef9SDimitry Andric // carefully. 1150e8d8bef9SDimitry Andric unsigned ExpectedUses = 1; 1151e8d8bef9SDimitry Andric if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) 1152e8d8bef9SDimitry Andric ExpectedUses = 2; 1153e8d8bef9SDimitry Andric 115481ad6265SDimitry Andric auto getNextInstruction = [&](Instruction *Cur) -> Instruction * { 1155fcaf7f86SDimitry Andric for (auto *User : Cur->users()) { 115681ad6265SDimitry Andric Instruction *UI = cast<Instruction>(User); 115781ad6265SDimitry Andric if (isa<PHINode>(UI)) 115881ad6265SDimitry Andric continue; 1159e8d8bef9SDimitry Andric if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) { 1160e8d8bef9SDimitry Andric // We are expecting a icmp/select pair, which we go to the next select 1161e8d8bef9SDimitry Andric // instruction if we can. We already know that Cur has 2 uses. 116281ad6265SDimitry Andric if (isa<SelectInst>(UI)) 116381ad6265SDimitry Andric return UI; 116481ad6265SDimitry Andric continue; 1165e8d8bef9SDimitry Andric } 116681ad6265SDimitry Andric return UI; 116781ad6265SDimitry Andric } 116881ad6265SDimitry Andric return nullptr; 1169e8d8bef9SDimitry Andric }; 1170e8d8bef9SDimitry Andric auto isCorrectOpcode = [&](Instruction *Cur) { 1171e8d8bef9SDimitry Andric if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) { 1172e8d8bef9SDimitry Andric Value *LHS, *RHS; 1173e8d8bef9SDimitry Andric return SelectPatternResult::isMinOrMax( 1174e8d8bef9SDimitry Andric matchSelectPattern(Cur, LHS, RHS).Flavor); 1175e8d8bef9SDimitry Andric } 11764824e7fdSDimitry Andric // Recognize a call to the llvm.fmuladd intrinsic. 11774824e7fdSDimitry Andric if (isFMulAddIntrinsic(Cur)) 11784824e7fdSDimitry Andric return true; 11794824e7fdSDimitry Andric 1180e8d8bef9SDimitry Andric return Cur->getOpcode() == RedOp; 1181e8d8bef9SDimitry Andric }; 1182e8d8bef9SDimitry Andric 118381ad6265SDimitry Andric // Attempt to look through Phis which are part of the reduction chain 118481ad6265SDimitry Andric unsigned ExtraPhiUses = 0; 118581ad6265SDimitry Andric Instruction *RdxInstr = LoopExitInstr; 118681ad6265SDimitry Andric if (auto ExitPhi = dyn_cast<PHINode>(LoopExitInstr)) { 118781ad6265SDimitry Andric if (ExitPhi->getNumIncomingValues() != 2) 118881ad6265SDimitry Andric return {}; 118981ad6265SDimitry Andric 119081ad6265SDimitry Andric Instruction *Inc0 = dyn_cast<Instruction>(ExitPhi->getIncomingValue(0)); 119181ad6265SDimitry Andric Instruction *Inc1 = dyn_cast<Instruction>(ExitPhi->getIncomingValue(1)); 119281ad6265SDimitry Andric 119381ad6265SDimitry Andric Instruction *Chain = nullptr; 119481ad6265SDimitry Andric if (Inc0 == Phi) 119581ad6265SDimitry Andric Chain = Inc1; 119681ad6265SDimitry Andric else if (Inc1 == Phi) 119781ad6265SDimitry Andric Chain = Inc0; 119881ad6265SDimitry Andric else 119981ad6265SDimitry Andric return {}; 120081ad6265SDimitry Andric 120181ad6265SDimitry Andric RdxInstr = Chain; 120281ad6265SDimitry Andric ExtraPhiUses = 1; 120381ad6265SDimitry Andric } 120481ad6265SDimitry Andric 1205e8d8bef9SDimitry Andric // The loop exit instruction we check first (as a quick test) but add last. We 1206e8d8bef9SDimitry Andric // check the opcode is correct (and dont allow them to be Subs) and that they 1207e8d8bef9SDimitry Andric // have expected to have the expected number of uses. They will have one use 1208e8d8bef9SDimitry Andric // from the phi and one from a LCSSA value, no matter the type. 120981ad6265SDimitry Andric if (!isCorrectOpcode(RdxInstr) || !LoopExitInstr->hasNUses(2)) 1210e8d8bef9SDimitry Andric return {}; 1211e8d8bef9SDimitry Andric 121281ad6265SDimitry Andric // Check that the Phi has one (or two for min/max) uses, plus an extra use 121381ad6265SDimitry Andric // for conditional reductions. 121481ad6265SDimitry Andric if (!Phi->hasNUses(ExpectedUses + ExtraPhiUses)) 1215e8d8bef9SDimitry Andric return {}; 121681ad6265SDimitry Andric 1217e8d8bef9SDimitry Andric Instruction *Cur = getNextInstruction(Phi); 1218e8d8bef9SDimitry Andric 1219e8d8bef9SDimitry Andric // Each other instruction in the chain should have the expected number of uses 1220e8d8bef9SDimitry Andric // and be the correct opcode. 122181ad6265SDimitry Andric while (Cur != RdxInstr) { 122281ad6265SDimitry Andric if (!Cur || !isCorrectOpcode(Cur) || !Cur->hasNUses(ExpectedUses)) 1223e8d8bef9SDimitry Andric return {}; 1224e8d8bef9SDimitry Andric 1225e8d8bef9SDimitry Andric ReductionOperations.push_back(Cur); 1226e8d8bef9SDimitry Andric Cur = getNextInstruction(Cur); 1227e8d8bef9SDimitry Andric } 1228e8d8bef9SDimitry Andric 1229e8d8bef9SDimitry Andric ReductionOperations.push_back(Cur); 1230e8d8bef9SDimitry Andric return ReductionOperations; 1231e8d8bef9SDimitry Andric } 1232e8d8bef9SDimitry Andric 12330b57cec5SDimitry Andric InductionDescriptor::InductionDescriptor(Value *Start, InductionKind K, 12340b57cec5SDimitry Andric const SCEV *Step, BinaryOperator *BOp, 12350b57cec5SDimitry Andric SmallVectorImpl<Instruction *> *Casts) 123606c3fb27SDimitry Andric : StartValue(Start), IK(K), Step(Step), InductionBinOp(BOp) { 12370b57cec5SDimitry Andric assert(IK != IK_NoInduction && "Not an induction"); 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric // Start value type should match the induction kind and the value 12400b57cec5SDimitry Andric // itself should not be null. 12410b57cec5SDimitry Andric assert(StartValue && "StartValue is null"); 12420b57cec5SDimitry Andric assert((IK != IK_PtrInduction || StartValue->getType()->isPointerTy()) && 12430b57cec5SDimitry Andric "StartValue is not a pointer for pointer induction"); 12440b57cec5SDimitry Andric assert((IK != IK_IntInduction || StartValue->getType()->isIntegerTy()) && 12450b57cec5SDimitry Andric "StartValue is not an integer for integer induction"); 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric // Check the Step Value. It should be non-zero integer value. 12480b57cec5SDimitry Andric assert((!getConstIntStepValue() || !getConstIntStepValue()->isZero()) && 12490b57cec5SDimitry Andric "Step value is zero"); 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric assert((IK == IK_FpInduction || Step->getType()->isIntegerTy()) && 12520b57cec5SDimitry Andric "StepValue is not an integer"); 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric assert((IK != IK_FpInduction || Step->getType()->isFloatingPointTy()) && 12550b57cec5SDimitry Andric "StepValue is not FP for FpInduction"); 12560b57cec5SDimitry Andric assert((IK != IK_FpInduction || 12570b57cec5SDimitry Andric (InductionBinOp && 12580b57cec5SDimitry Andric (InductionBinOp->getOpcode() == Instruction::FAdd || 12590b57cec5SDimitry Andric InductionBinOp->getOpcode() == Instruction::FSub))) && 12600b57cec5SDimitry Andric "Binary opcode should be specified for FP induction"); 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric if (Casts) { 12630b57cec5SDimitry Andric for (auto &Inst : *Casts) { 12640b57cec5SDimitry Andric RedundantCasts.push_back(Inst); 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric } 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric 12690b57cec5SDimitry Andric ConstantInt *InductionDescriptor::getConstIntStepValue() const { 12700b57cec5SDimitry Andric if (isa<SCEVConstant>(Step)) 12710b57cec5SDimitry Andric return dyn_cast<ConstantInt>(cast<SCEVConstant>(Step)->getValue()); 12720b57cec5SDimitry Andric return nullptr; 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric bool InductionDescriptor::isFPInductionPHI(PHINode *Phi, const Loop *TheLoop, 12760b57cec5SDimitry Andric ScalarEvolution *SE, 12770b57cec5SDimitry Andric InductionDescriptor &D) { 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric // Here we only handle FP induction variables. 12800b57cec5SDimitry Andric assert(Phi->getType()->isFloatingPointTy() && "Unexpected Phi type"); 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric if (TheLoop->getHeader() != Phi->getParent()) 12830b57cec5SDimitry Andric return false; 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric // The loop may have multiple entrances or multiple exits; we can analyze 12860b57cec5SDimitry Andric // this phi if it has a unique entry value and a unique backedge value. 12870b57cec5SDimitry Andric if (Phi->getNumIncomingValues() != 2) 12880b57cec5SDimitry Andric return false; 12890b57cec5SDimitry Andric Value *BEValue = nullptr, *StartValue = nullptr; 12900b57cec5SDimitry Andric if (TheLoop->contains(Phi->getIncomingBlock(0))) { 12910b57cec5SDimitry Andric BEValue = Phi->getIncomingValue(0); 12920b57cec5SDimitry Andric StartValue = Phi->getIncomingValue(1); 12930b57cec5SDimitry Andric } else { 12940b57cec5SDimitry Andric assert(TheLoop->contains(Phi->getIncomingBlock(1)) && 12950b57cec5SDimitry Andric "Unexpected Phi node in the loop"); 12960b57cec5SDimitry Andric BEValue = Phi->getIncomingValue(1); 12970b57cec5SDimitry Andric StartValue = Phi->getIncomingValue(0); 12980b57cec5SDimitry Andric } 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andric BinaryOperator *BOp = dyn_cast<BinaryOperator>(BEValue); 13010b57cec5SDimitry Andric if (!BOp) 13020b57cec5SDimitry Andric return false; 13030b57cec5SDimitry Andric 13040b57cec5SDimitry Andric Value *Addend = nullptr; 13050b57cec5SDimitry Andric if (BOp->getOpcode() == Instruction::FAdd) { 13060b57cec5SDimitry Andric if (BOp->getOperand(0) == Phi) 13070b57cec5SDimitry Andric Addend = BOp->getOperand(1); 13080b57cec5SDimitry Andric else if (BOp->getOperand(1) == Phi) 13090b57cec5SDimitry Andric Addend = BOp->getOperand(0); 13100b57cec5SDimitry Andric } else if (BOp->getOpcode() == Instruction::FSub) 13110b57cec5SDimitry Andric if (BOp->getOperand(0) == Phi) 13120b57cec5SDimitry Andric Addend = BOp->getOperand(1); 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric if (!Addend) 13150b57cec5SDimitry Andric return false; 13160b57cec5SDimitry Andric 13170b57cec5SDimitry Andric // The addend should be loop invariant 13180b57cec5SDimitry Andric if (auto *I = dyn_cast<Instruction>(Addend)) 13190b57cec5SDimitry Andric if (TheLoop->contains(I)) 13200b57cec5SDimitry Andric return false; 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric // FP Step has unknown SCEV 13230b57cec5SDimitry Andric const SCEV *Step = SE->getUnknown(Addend); 13240b57cec5SDimitry Andric D = InductionDescriptor(StartValue, IK_FpInduction, Step, BOp); 13250b57cec5SDimitry Andric return true; 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric /// This function is called when we suspect that the update-chain of a phi node 13290b57cec5SDimitry Andric /// (whose symbolic SCEV expression sin \p PhiScev) contains redundant casts, 13300b57cec5SDimitry Andric /// that can be ignored. (This can happen when the PSCEV rewriter adds a runtime 13310b57cec5SDimitry Andric /// predicate P under which the SCEV expression for the phi can be the 13320b57cec5SDimitry Andric /// AddRecurrence \p AR; See createAddRecFromPHIWithCast). We want to find the 13330b57cec5SDimitry Andric /// cast instructions that are involved in the update-chain of this induction. 13340b57cec5SDimitry Andric /// A caller that adds the required runtime predicate can be free to drop these 13350b57cec5SDimitry Andric /// cast instructions, and compute the phi using \p AR (instead of some scev 13360b57cec5SDimitry Andric /// expression with casts). 13370b57cec5SDimitry Andric /// 13380b57cec5SDimitry Andric /// For example, without a predicate the scev expression can take the following 13390b57cec5SDimitry Andric /// form: 13400b57cec5SDimitry Andric /// (Ext ix (Trunc iy ( Start + i*Step ) to ix) to iy) 13410b57cec5SDimitry Andric /// 13420b57cec5SDimitry Andric /// It corresponds to the following IR sequence: 13430b57cec5SDimitry Andric /// %for.body: 13440b57cec5SDimitry Andric /// %x = phi i64 [ 0, %ph ], [ %add, %for.body ] 13450b57cec5SDimitry Andric /// %casted_phi = "ExtTrunc i64 %x" 13460b57cec5SDimitry Andric /// %add = add i64 %casted_phi, %step 13470b57cec5SDimitry Andric /// 13480b57cec5SDimitry Andric /// where %x is given in \p PN, 13490b57cec5SDimitry Andric /// PSE.getSCEV(%x) is equal to PSE.getSCEV(%casted_phi) under a predicate, 13500b57cec5SDimitry Andric /// and the IR sequence that "ExtTrunc i64 %x" represents can take one of 13510b57cec5SDimitry Andric /// several forms, for example, such as: 13520b57cec5SDimitry Andric /// ExtTrunc1: %casted_phi = and %x, 2^n-1 13530b57cec5SDimitry Andric /// or: 13540b57cec5SDimitry Andric /// ExtTrunc2: %t = shl %x, m 13550b57cec5SDimitry Andric /// %casted_phi = ashr %t, m 13560b57cec5SDimitry Andric /// 13570b57cec5SDimitry Andric /// If we are able to find such sequence, we return the instructions 13580b57cec5SDimitry Andric /// we found, namely %casted_phi and the instructions on its use-def chain up 13590b57cec5SDimitry Andric /// to the phi (not including the phi). 13600b57cec5SDimitry Andric static bool getCastsForInductionPHI(PredicatedScalarEvolution &PSE, 13610b57cec5SDimitry Andric const SCEVUnknown *PhiScev, 13620b57cec5SDimitry Andric const SCEVAddRecExpr *AR, 13630b57cec5SDimitry Andric SmallVectorImpl<Instruction *> &CastInsts) { 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric assert(CastInsts.empty() && "CastInsts is expected to be empty."); 13660b57cec5SDimitry Andric auto *PN = cast<PHINode>(PhiScev->getValue()); 13670b57cec5SDimitry Andric assert(PSE.getSCEV(PN) == AR && "Unexpected phi node SCEV expression"); 13680b57cec5SDimitry Andric const Loop *L = AR->getLoop(); 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric // Find any cast instructions that participate in the def-use chain of 13710b57cec5SDimitry Andric // PhiScev in the loop. 13720b57cec5SDimitry Andric // FORNOW/TODO: We currently expect the def-use chain to include only 13730b57cec5SDimitry Andric // two-operand instructions, where one of the operands is an invariant. 13740b57cec5SDimitry Andric // createAddRecFromPHIWithCasts() currently does not support anything more 13750b57cec5SDimitry Andric // involved than that, so we keep the search simple. This can be 13760b57cec5SDimitry Andric // extended/generalized as needed. 13770b57cec5SDimitry Andric 13780b57cec5SDimitry Andric auto getDef = [&](const Value *Val) -> Value * { 13790b57cec5SDimitry Andric const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Val); 13800b57cec5SDimitry Andric if (!BinOp) 13810b57cec5SDimitry Andric return nullptr; 13820b57cec5SDimitry Andric Value *Op0 = BinOp->getOperand(0); 13830b57cec5SDimitry Andric Value *Op1 = BinOp->getOperand(1); 13840b57cec5SDimitry Andric Value *Def = nullptr; 13850b57cec5SDimitry Andric if (L->isLoopInvariant(Op0)) 13860b57cec5SDimitry Andric Def = Op1; 13870b57cec5SDimitry Andric else if (L->isLoopInvariant(Op1)) 13880b57cec5SDimitry Andric Def = Op0; 13890b57cec5SDimitry Andric return Def; 13900b57cec5SDimitry Andric }; 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andric // Look for the instruction that defines the induction via the 13930b57cec5SDimitry Andric // loop backedge. 13940b57cec5SDimitry Andric BasicBlock *Latch = L->getLoopLatch(); 13950b57cec5SDimitry Andric if (!Latch) 13960b57cec5SDimitry Andric return false; 13970b57cec5SDimitry Andric Value *Val = PN->getIncomingValueForBlock(Latch); 13980b57cec5SDimitry Andric if (!Val) 13990b57cec5SDimitry Andric return false; 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andric // Follow the def-use chain until the induction phi is reached. 14020b57cec5SDimitry Andric // If on the way we encounter a Value that has the same SCEV Expr as the 14030b57cec5SDimitry Andric // phi node, we can consider the instructions we visit from that point 14040b57cec5SDimitry Andric // as part of the cast-sequence that can be ignored. 14050b57cec5SDimitry Andric bool InCastSequence = false; 14060b57cec5SDimitry Andric auto *Inst = dyn_cast<Instruction>(Val); 14070b57cec5SDimitry Andric while (Val != PN) { 14080b57cec5SDimitry Andric // If we encountered a phi node other than PN, or if we left the loop, 14090b57cec5SDimitry Andric // we bail out. 14100b57cec5SDimitry Andric if (!Inst || !L->contains(Inst)) { 14110b57cec5SDimitry Andric return false; 14120b57cec5SDimitry Andric } 14130b57cec5SDimitry Andric auto *AddRec = dyn_cast<SCEVAddRecExpr>(PSE.getSCEV(Val)); 14140b57cec5SDimitry Andric if (AddRec && PSE.areAddRecsEqualWithPreds(AddRec, AR)) 14150b57cec5SDimitry Andric InCastSequence = true; 14160b57cec5SDimitry Andric if (InCastSequence) { 14170b57cec5SDimitry Andric // Only the last instruction in the cast sequence is expected to have 14180b57cec5SDimitry Andric // uses outside the induction def-use chain. 14190b57cec5SDimitry Andric if (!CastInsts.empty()) 14200b57cec5SDimitry Andric if (!Inst->hasOneUse()) 14210b57cec5SDimitry Andric return false; 14220b57cec5SDimitry Andric CastInsts.push_back(Inst); 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric Val = getDef(Val); 14250b57cec5SDimitry Andric if (!Val) 14260b57cec5SDimitry Andric return false; 14270b57cec5SDimitry Andric Inst = dyn_cast<Instruction>(Val); 14280b57cec5SDimitry Andric } 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric return InCastSequence; 14310b57cec5SDimitry Andric } 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop, 14340b57cec5SDimitry Andric PredicatedScalarEvolution &PSE, 14350b57cec5SDimitry Andric InductionDescriptor &D, bool Assume) { 14360b57cec5SDimitry Andric Type *PhiTy = Phi->getType(); 14370b57cec5SDimitry Andric 14380b57cec5SDimitry Andric // Handle integer and pointer inductions variables. 14390b57cec5SDimitry Andric // Now we handle also FP induction but not trying to make a 14400b57cec5SDimitry Andric // recurrent expression from the PHI node in-place. 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy() && !PhiTy->isFloatTy() && 14430b57cec5SDimitry Andric !PhiTy->isDoubleTy() && !PhiTy->isHalfTy()) 14440b57cec5SDimitry Andric return false; 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric if (PhiTy->isFloatingPointTy()) 14470b57cec5SDimitry Andric return isFPInductionPHI(Phi, TheLoop, PSE.getSE(), D); 14480b57cec5SDimitry Andric 14490b57cec5SDimitry Andric const SCEV *PhiScev = PSE.getSCEV(Phi); 14500b57cec5SDimitry Andric const auto *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric // We need this expression to be an AddRecExpr. 14530b57cec5SDimitry Andric if (Assume && !AR) 14540b57cec5SDimitry Andric AR = PSE.getAsAddRec(Phi); 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric if (!AR) { 14570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); 14580b57cec5SDimitry Andric return false; 14590b57cec5SDimitry Andric } 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andric // Record any Cast instructions that participate in the induction update 14620b57cec5SDimitry Andric const auto *SymbolicPhi = dyn_cast<SCEVUnknown>(PhiScev); 14630b57cec5SDimitry Andric // If we started from an UnknownSCEV, and managed to build an addRecurrence 14640b57cec5SDimitry Andric // only after enabling Assume with PSCEV, this means we may have encountered 14650b57cec5SDimitry Andric // cast instructions that required adding a runtime check in order to 14660b57cec5SDimitry Andric // guarantee the correctness of the AddRecurrence respresentation of the 14670b57cec5SDimitry Andric // induction. 14680b57cec5SDimitry Andric if (PhiScev != AR && SymbolicPhi) { 14690b57cec5SDimitry Andric SmallVector<Instruction *, 2> Casts; 14700b57cec5SDimitry Andric if (getCastsForInductionPHI(PSE, SymbolicPhi, AR, Casts)) 14710b57cec5SDimitry Andric return isInductionPHI(Phi, TheLoop, PSE.getSE(), D, AR, &Casts); 14720b57cec5SDimitry Andric } 14730b57cec5SDimitry Andric 14740b57cec5SDimitry Andric return isInductionPHI(Phi, TheLoop, PSE.getSE(), D, AR); 14750b57cec5SDimitry Andric } 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric bool InductionDescriptor::isInductionPHI( 14780b57cec5SDimitry Andric PHINode *Phi, const Loop *TheLoop, ScalarEvolution *SE, 14790b57cec5SDimitry Andric InductionDescriptor &D, const SCEV *Expr, 14800b57cec5SDimitry Andric SmallVectorImpl<Instruction *> *CastsToIgnore) { 14810b57cec5SDimitry Andric Type *PhiTy = Phi->getType(); 14820b57cec5SDimitry Andric // We only handle integer and pointer inductions variables. 14830b57cec5SDimitry Andric if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy()) 14840b57cec5SDimitry Andric return false; 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric // Check that the PHI is consecutive. 14870b57cec5SDimitry Andric const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi); 14880b57cec5SDimitry Andric const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); 14890b57cec5SDimitry Andric 14900b57cec5SDimitry Andric if (!AR) { 14910b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); 14920b57cec5SDimitry Andric return false; 14930b57cec5SDimitry Andric } 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric if (AR->getLoop() != TheLoop) { 14960b57cec5SDimitry Andric // FIXME: We should treat this as a uniform. Unfortunately, we 14970b57cec5SDimitry Andric // don't currently know how to handled uniform PHIs. 14980b57cec5SDimitry Andric LLVM_DEBUG( 14990b57cec5SDimitry Andric dbgs() << "LV: PHI is a recurrence with respect to an outer loop.\n"); 15000b57cec5SDimitry Andric return false; 15010b57cec5SDimitry Andric } 15020b57cec5SDimitry Andric 150306c3fb27SDimitry Andric // This function assumes that InductionPhi is called only on Phi nodes 150406c3fb27SDimitry Andric // present inside loop headers. Check for the same, and throw an assert if 150506c3fb27SDimitry Andric // the current Phi is not present inside the loop header. 150606c3fb27SDimitry Andric assert(Phi->getParent() == AR->getLoop()->getHeader() 150706c3fb27SDimitry Andric && "Invalid Phi node, not present in loop header"); 150806c3fb27SDimitry Andric 15090b57cec5SDimitry Andric Value *StartValue = 15100b57cec5SDimitry Andric Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader()); 15110b57cec5SDimitry Andric 15120b57cec5SDimitry Andric BasicBlock *Latch = AR->getLoop()->getLoopLatch(); 15130b57cec5SDimitry Andric if (!Latch) 15140b57cec5SDimitry Andric return false; 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andric const SCEV *Step = AR->getStepRecurrence(*SE); 15170b57cec5SDimitry Andric // Calculate the pointer stride and check if it is consecutive. 15180b57cec5SDimitry Andric // The stride may be a constant or a loop invariant integer value. 15190b57cec5SDimitry Andric const SCEVConstant *ConstStep = dyn_cast<SCEVConstant>(Step); 15200b57cec5SDimitry Andric if (!ConstStep && !SE->isLoopInvariant(Step, TheLoop)) 15210b57cec5SDimitry Andric return false; 15220b57cec5SDimitry Andric 15230b57cec5SDimitry Andric if (PhiTy->isIntegerTy()) { 1524349cc55cSDimitry Andric BinaryOperator *BOp = 1525349cc55cSDimitry Andric dyn_cast<BinaryOperator>(Phi->getIncomingValueForBlock(Latch)); 15260b57cec5SDimitry Andric D = InductionDescriptor(StartValue, IK_IntInduction, Step, BOp, 152706c3fb27SDimitry Andric CastsToIgnore); 15280b57cec5SDimitry Andric return true; 15290b57cec5SDimitry Andric } 15300b57cec5SDimitry Andric 15310b57cec5SDimitry Andric assert(PhiTy->isPointerTy() && "The PHI must be a pointer"); 15320b57cec5SDimitry Andric 153306c3fb27SDimitry Andric // This allows induction variables w/non-constant steps. 153406c3fb27SDimitry Andric D = InductionDescriptor(StartValue, IK_PtrInduction, Step); 15350b57cec5SDimitry Andric return true; 15360b57cec5SDimitry Andric } 1537