176aa662cSKarthik Bhat //===-- LoopUtils.cpp - Loop Utility functions -------------------------===// 276aa662cSKarthik Bhat // 376aa662cSKarthik Bhat // The LLVM Compiler Infrastructure 476aa662cSKarthik Bhat // 576aa662cSKarthik Bhat // This file is distributed under the University of Illinois Open Source 676aa662cSKarthik Bhat // License. See LICENSE.TXT for details. 776aa662cSKarthik Bhat // 876aa662cSKarthik Bhat //===----------------------------------------------------------------------===// 976aa662cSKarthik Bhat // 1076aa662cSKarthik Bhat // This file defines common loop utility functions. 1176aa662cSKarthik Bhat // 1276aa662cSKarthik Bhat //===----------------------------------------------------------------------===// 1376aa662cSKarthik Bhat 1476aa662cSKarthik Bhat #include "llvm/Analysis/LoopInfo.h" 1576aa662cSKarthik Bhat #include "llvm/IR/Instructions.h" 1676aa662cSKarthik Bhat #include "llvm/IR/PatternMatch.h" 1776aa662cSKarthik Bhat #include "llvm/IR/ValueHandle.h" 1876aa662cSKarthik Bhat #include "llvm/Support/Debug.h" 19*24e6cc2dSKarthik Bhat #include "llvm/Analysis/ScalarEvolution.h" 20*24e6cc2dSKarthik Bhat #include "llvm/Analysis/ScalarEvolutionExpressions.h" 21*24e6cc2dSKarthik Bhat #include "llvm/IR/Module.h" 2276aa662cSKarthik Bhat #include "llvm/Transforms/Utils/LoopUtils.h" 2376aa662cSKarthik Bhat 2476aa662cSKarthik Bhat using namespace llvm; 2576aa662cSKarthik Bhat using namespace llvm::PatternMatch; 2676aa662cSKarthik Bhat 2776aa662cSKarthik Bhat #define DEBUG_TYPE "loop-utils" 2876aa662cSKarthik Bhat 2976aa662cSKarthik Bhat bool ReductionDescriptor::areAllUsesIn(Instruction *I, 3076aa662cSKarthik Bhat SmallPtrSetImpl<Instruction *> &Set) { 3176aa662cSKarthik Bhat for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; ++Use) 3276aa662cSKarthik Bhat if (!Set.count(dyn_cast<Instruction>(*Use))) 3376aa662cSKarthik Bhat return false; 3476aa662cSKarthik Bhat return true; 3576aa662cSKarthik Bhat } 3676aa662cSKarthik Bhat 3776aa662cSKarthik Bhat bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, 3876aa662cSKarthik Bhat Loop *TheLoop, bool HasFunNoNaNAttr, 3976aa662cSKarthik Bhat ReductionDescriptor &RedDes) { 4076aa662cSKarthik Bhat if (Phi->getNumIncomingValues() != 2) 4176aa662cSKarthik Bhat return false; 4276aa662cSKarthik Bhat 4376aa662cSKarthik Bhat // Reduction variables are only found in the loop header block. 4476aa662cSKarthik Bhat if (Phi->getParent() != TheLoop->getHeader()) 4576aa662cSKarthik Bhat return false; 4676aa662cSKarthik Bhat 4776aa662cSKarthik Bhat // Obtain the reduction start value from the value that comes from the loop 4876aa662cSKarthik Bhat // preheader. 4976aa662cSKarthik Bhat Value *RdxStart = Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader()); 5076aa662cSKarthik Bhat 5176aa662cSKarthik Bhat // ExitInstruction is the single value which is used outside the loop. 5276aa662cSKarthik Bhat // We only allow for a single reduction value to be used outside the loop. 5376aa662cSKarthik Bhat // This includes users of the reduction, variables (which form a cycle 5476aa662cSKarthik Bhat // which ends in the phi node). 5576aa662cSKarthik Bhat Instruction *ExitInstruction = nullptr; 5676aa662cSKarthik Bhat // Indicates that we found a reduction operation in our scan. 5776aa662cSKarthik Bhat bool FoundReduxOp = false; 5876aa662cSKarthik Bhat 5976aa662cSKarthik Bhat // We start with the PHI node and scan for all of the users of this 6076aa662cSKarthik Bhat // instruction. All users must be instructions that can be used as reduction 6176aa662cSKarthik Bhat // variables (such as ADD). We must have a single out-of-block user. The cycle 6276aa662cSKarthik Bhat // must include the original PHI. 6376aa662cSKarthik Bhat bool FoundStartPHI = false; 6476aa662cSKarthik Bhat 6576aa662cSKarthik Bhat // To recognize min/max patterns formed by a icmp select sequence, we store 6676aa662cSKarthik Bhat // the number of instruction we saw from the recognized min/max pattern, 6776aa662cSKarthik Bhat // to make sure we only see exactly the two instructions. 6876aa662cSKarthik Bhat unsigned NumCmpSelectPatternInst = 0; 6976aa662cSKarthik Bhat ReductionInstDesc ReduxDesc(false, nullptr); 7076aa662cSKarthik Bhat 7176aa662cSKarthik Bhat SmallPtrSet<Instruction *, 8> VisitedInsts; 7276aa662cSKarthik Bhat SmallVector<Instruction *, 8> Worklist; 7376aa662cSKarthik Bhat Worklist.push_back(Phi); 7476aa662cSKarthik Bhat VisitedInsts.insert(Phi); 7576aa662cSKarthik Bhat 7676aa662cSKarthik Bhat // A value in the reduction can be used: 7776aa662cSKarthik Bhat // - By the reduction: 7876aa662cSKarthik Bhat // - Reduction operation: 7976aa662cSKarthik Bhat // - One use of reduction value (safe). 8076aa662cSKarthik Bhat // - Multiple use of reduction value (not safe). 8176aa662cSKarthik Bhat // - PHI: 8276aa662cSKarthik Bhat // - All uses of the PHI must be the reduction (safe). 8376aa662cSKarthik Bhat // - Otherwise, not safe. 8476aa662cSKarthik Bhat // - By one instruction outside of the loop (safe). 8576aa662cSKarthik Bhat // - By further instructions outside of the loop (not safe). 8676aa662cSKarthik Bhat // - By an instruction that is not part of the reduction (not safe). 8776aa662cSKarthik Bhat // This is either: 8876aa662cSKarthik Bhat // * An instruction type other than PHI or the reduction operation. 8976aa662cSKarthik Bhat // * A PHI in the header other than the initial PHI. 9076aa662cSKarthik Bhat while (!Worklist.empty()) { 9176aa662cSKarthik Bhat Instruction *Cur = Worklist.back(); 9276aa662cSKarthik Bhat Worklist.pop_back(); 9376aa662cSKarthik Bhat 9476aa662cSKarthik Bhat // No Users. 9576aa662cSKarthik Bhat // If the instruction has no users then this is a broken chain and can't be 9676aa662cSKarthik Bhat // a reduction variable. 9776aa662cSKarthik Bhat if (Cur->use_empty()) 9876aa662cSKarthik Bhat return false; 9976aa662cSKarthik Bhat 10076aa662cSKarthik Bhat bool IsAPhi = isa<PHINode>(Cur); 10176aa662cSKarthik Bhat 10276aa662cSKarthik Bhat // A header PHI use other than the original PHI. 10376aa662cSKarthik Bhat if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent()) 10476aa662cSKarthik Bhat return false; 10576aa662cSKarthik Bhat 10676aa662cSKarthik Bhat // Reductions of instructions such as Div, and Sub is only possible if the 10776aa662cSKarthik Bhat // LHS is the reduction variable. 10876aa662cSKarthik Bhat if (!Cur->isCommutative() && !IsAPhi && !isa<SelectInst>(Cur) && 10976aa662cSKarthik Bhat !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) && 11076aa662cSKarthik Bhat !VisitedInsts.count(dyn_cast<Instruction>(Cur->getOperand(0)))) 11176aa662cSKarthik Bhat return false; 11276aa662cSKarthik Bhat 11376aa662cSKarthik Bhat // Any reduction instruction must be of one of the allowed kinds. 11476aa662cSKarthik Bhat ReduxDesc = isReductionInstr(Cur, Kind, ReduxDesc, HasFunNoNaNAttr); 11576aa662cSKarthik Bhat if (!ReduxDesc.isReduction()) 11676aa662cSKarthik Bhat return false; 11776aa662cSKarthik Bhat 11876aa662cSKarthik Bhat // A reduction operation must only have one use of the reduction value. 11976aa662cSKarthik Bhat if (!IsAPhi && Kind != RK_IntegerMinMax && Kind != RK_FloatMinMax && 12076aa662cSKarthik Bhat hasMultipleUsesOf(Cur, VisitedInsts)) 12176aa662cSKarthik Bhat return false; 12276aa662cSKarthik Bhat 12376aa662cSKarthik Bhat // All inputs to a PHI node must be a reduction value. 12476aa662cSKarthik Bhat if (IsAPhi && Cur != Phi && !areAllUsesIn(Cur, VisitedInsts)) 12576aa662cSKarthik Bhat return false; 12676aa662cSKarthik Bhat 12776aa662cSKarthik Bhat if (Kind == RK_IntegerMinMax && 12876aa662cSKarthik Bhat (isa<ICmpInst>(Cur) || isa<SelectInst>(Cur))) 12976aa662cSKarthik Bhat ++NumCmpSelectPatternInst; 13076aa662cSKarthik Bhat if (Kind == RK_FloatMinMax && (isa<FCmpInst>(Cur) || isa<SelectInst>(Cur))) 13176aa662cSKarthik Bhat ++NumCmpSelectPatternInst; 13276aa662cSKarthik Bhat 13376aa662cSKarthik Bhat // Check whether we found a reduction operator. 13476aa662cSKarthik Bhat FoundReduxOp |= !IsAPhi; 13576aa662cSKarthik Bhat 13676aa662cSKarthik Bhat // Process users of current instruction. Push non-PHI nodes after PHI nodes 13776aa662cSKarthik Bhat // onto the stack. This way we are going to have seen all inputs to PHI 13876aa662cSKarthik Bhat // nodes once we get to them. 13976aa662cSKarthik Bhat SmallVector<Instruction *, 8> NonPHIs; 14076aa662cSKarthik Bhat SmallVector<Instruction *, 8> PHIs; 14176aa662cSKarthik Bhat for (User *U : Cur->users()) { 14276aa662cSKarthik Bhat Instruction *UI = cast<Instruction>(U); 14376aa662cSKarthik Bhat 14476aa662cSKarthik Bhat // Check if we found the exit user. 14576aa662cSKarthik Bhat BasicBlock *Parent = UI->getParent(); 14676aa662cSKarthik Bhat if (!TheLoop->contains(Parent)) { 14776aa662cSKarthik Bhat // Exit if you find multiple outside users or if the header phi node is 14876aa662cSKarthik Bhat // being used. In this case the user uses the value of the previous 14976aa662cSKarthik Bhat // iteration, in which case we would loose "VF-1" iterations of the 15076aa662cSKarthik Bhat // reduction operation if we vectorize. 15176aa662cSKarthik Bhat if (ExitInstruction != nullptr || Cur == Phi) 15276aa662cSKarthik Bhat return false; 15376aa662cSKarthik Bhat 15476aa662cSKarthik Bhat // The instruction used by an outside user must be the last instruction 15576aa662cSKarthik Bhat // before we feed back to the reduction phi. Otherwise, we loose VF-1 15676aa662cSKarthik Bhat // operations on the value. 15776aa662cSKarthik Bhat if (std::find(Phi->op_begin(), Phi->op_end(), Cur) == Phi->op_end()) 15876aa662cSKarthik Bhat return false; 15976aa662cSKarthik Bhat 16076aa662cSKarthik Bhat ExitInstruction = Cur; 16176aa662cSKarthik Bhat continue; 16276aa662cSKarthik Bhat } 16376aa662cSKarthik Bhat 16476aa662cSKarthik Bhat // Process instructions only once (termination). Each reduction cycle 16576aa662cSKarthik Bhat // value must only be used once, except by phi nodes and min/max 16676aa662cSKarthik Bhat // reductions which are represented as a cmp followed by a select. 16776aa662cSKarthik Bhat ReductionInstDesc IgnoredVal(false, nullptr); 16876aa662cSKarthik Bhat if (VisitedInsts.insert(UI).second) { 16976aa662cSKarthik Bhat if (isa<PHINode>(UI)) 17076aa662cSKarthik Bhat PHIs.push_back(UI); 17176aa662cSKarthik Bhat else 17276aa662cSKarthik Bhat NonPHIs.push_back(UI); 17376aa662cSKarthik Bhat } else if (!isa<PHINode>(UI) && 17476aa662cSKarthik Bhat ((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) && 17576aa662cSKarthik Bhat !isa<SelectInst>(UI)) || 17676aa662cSKarthik Bhat !isMinMaxSelectCmpPattern(UI, IgnoredVal).isReduction())) 17776aa662cSKarthik Bhat return false; 17876aa662cSKarthik Bhat 17976aa662cSKarthik Bhat // Remember that we completed the cycle. 18076aa662cSKarthik Bhat if (UI == Phi) 18176aa662cSKarthik Bhat FoundStartPHI = true; 18276aa662cSKarthik Bhat } 18376aa662cSKarthik Bhat Worklist.append(PHIs.begin(), PHIs.end()); 18476aa662cSKarthik Bhat Worklist.append(NonPHIs.begin(), NonPHIs.end()); 18576aa662cSKarthik Bhat } 18676aa662cSKarthik Bhat 18776aa662cSKarthik Bhat // This means we have seen one but not the other instruction of the 18876aa662cSKarthik Bhat // pattern or more than just a select and cmp. 18976aa662cSKarthik Bhat if ((Kind == RK_IntegerMinMax || Kind == RK_FloatMinMax) && 19076aa662cSKarthik Bhat NumCmpSelectPatternInst != 2) 19176aa662cSKarthik Bhat return false; 19276aa662cSKarthik Bhat 19376aa662cSKarthik Bhat if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction) 19476aa662cSKarthik Bhat return false; 19576aa662cSKarthik Bhat 19676aa662cSKarthik Bhat // We found a reduction var if we have reached the original phi node and we 19776aa662cSKarthik Bhat // only have a single instruction with out-of-loop users. 19876aa662cSKarthik Bhat 19976aa662cSKarthik Bhat // The ExitInstruction(Instruction which is allowed to have out-of-loop users) 20076aa662cSKarthik Bhat // is saved as part of the ReductionDescriptor. 20176aa662cSKarthik Bhat 20276aa662cSKarthik Bhat // Save the description of this reduction variable. 20376aa662cSKarthik Bhat ReductionDescriptor RD(RdxStart, ExitInstruction, Kind, 20476aa662cSKarthik Bhat ReduxDesc.getMinMaxKind()); 20576aa662cSKarthik Bhat 20676aa662cSKarthik Bhat RedDes = RD; 20776aa662cSKarthik Bhat 20876aa662cSKarthik Bhat return true; 20976aa662cSKarthik Bhat } 21076aa662cSKarthik Bhat 21176aa662cSKarthik Bhat /// Returns true if the instruction is a Select(ICmp(X, Y), X, Y) instruction 21276aa662cSKarthik Bhat /// pattern corresponding to a min(X, Y) or max(X, Y). 21376aa662cSKarthik Bhat ReductionInstDesc 21476aa662cSKarthik Bhat ReductionDescriptor::isMinMaxSelectCmpPattern(Instruction *I, 21576aa662cSKarthik Bhat ReductionInstDesc &Prev) { 21676aa662cSKarthik Bhat 21776aa662cSKarthik Bhat assert((isa<ICmpInst>(I) || isa<FCmpInst>(I) || isa<SelectInst>(I)) && 21876aa662cSKarthik Bhat "Expect a select instruction"); 21976aa662cSKarthik Bhat Instruction *Cmp = nullptr; 22076aa662cSKarthik Bhat SelectInst *Select = nullptr; 22176aa662cSKarthik Bhat 22276aa662cSKarthik Bhat // We must handle the select(cmp()) as a single instruction. Advance to the 22376aa662cSKarthik Bhat // select. 22476aa662cSKarthik Bhat if ((Cmp = dyn_cast<ICmpInst>(I)) || (Cmp = dyn_cast<FCmpInst>(I))) { 22576aa662cSKarthik Bhat if (!Cmp->hasOneUse() || !(Select = dyn_cast<SelectInst>(*I->user_begin()))) 22676aa662cSKarthik Bhat return ReductionInstDesc(false, I); 22776aa662cSKarthik Bhat return ReductionInstDesc(Select, Prev.getMinMaxKind()); 22876aa662cSKarthik Bhat } 22976aa662cSKarthik Bhat 23076aa662cSKarthik Bhat // Only handle single use cases for now. 23176aa662cSKarthik Bhat if (!(Select = dyn_cast<SelectInst>(I))) 23276aa662cSKarthik Bhat return ReductionInstDesc(false, I); 23376aa662cSKarthik Bhat if (!(Cmp = dyn_cast<ICmpInst>(I->getOperand(0))) && 23476aa662cSKarthik Bhat !(Cmp = dyn_cast<FCmpInst>(I->getOperand(0)))) 23576aa662cSKarthik Bhat return ReductionInstDesc(false, I); 23676aa662cSKarthik Bhat if (!Cmp->hasOneUse()) 23776aa662cSKarthik Bhat return ReductionInstDesc(false, I); 23876aa662cSKarthik Bhat 23976aa662cSKarthik Bhat Value *CmpLeft; 24076aa662cSKarthik Bhat Value *CmpRight; 24176aa662cSKarthik Bhat 24276aa662cSKarthik Bhat // Look for a min/max pattern. 24376aa662cSKarthik Bhat if (m_UMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 24476aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_UIntMin); 24576aa662cSKarthik Bhat else if (m_UMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 24676aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_UIntMax); 24776aa662cSKarthik Bhat else if (m_SMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 24876aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_SIntMax); 24976aa662cSKarthik Bhat else if (m_SMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25076aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_SIntMin); 25176aa662cSKarthik Bhat else if (m_OrdFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25276aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMin); 25376aa662cSKarthik Bhat else if (m_OrdFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25476aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMax); 25576aa662cSKarthik Bhat else if (m_UnordFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25676aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMin); 25776aa662cSKarthik Bhat else if (m_UnordFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) 25876aa662cSKarthik Bhat return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMax); 25976aa662cSKarthik Bhat 26076aa662cSKarthik Bhat return ReductionInstDesc(false, I); 26176aa662cSKarthik Bhat } 26276aa662cSKarthik Bhat 26376aa662cSKarthik Bhat ReductionInstDesc ReductionDescriptor::isReductionInstr(Instruction *I, 26476aa662cSKarthik Bhat ReductionKind Kind, 26576aa662cSKarthik Bhat ReductionInstDesc &Prev, 26676aa662cSKarthik Bhat bool HasFunNoNaNAttr) { 26776aa662cSKarthik Bhat bool FP = I->getType()->isFloatingPointTy(); 26876aa662cSKarthik Bhat bool FastMath = FP && I->hasUnsafeAlgebra(); 26976aa662cSKarthik Bhat switch (I->getOpcode()) { 27076aa662cSKarthik Bhat default: 27176aa662cSKarthik Bhat return ReductionInstDesc(false, I); 27276aa662cSKarthik Bhat case Instruction::PHI: 27376aa662cSKarthik Bhat if (FP && 27476aa662cSKarthik Bhat (Kind != RK_FloatMult && Kind != RK_FloatAdd && Kind != RK_FloatMinMax)) 27576aa662cSKarthik Bhat return ReductionInstDesc(false, I); 27676aa662cSKarthik Bhat return ReductionInstDesc(I, Prev.getMinMaxKind()); 27776aa662cSKarthik Bhat case Instruction::Sub: 27876aa662cSKarthik Bhat case Instruction::Add: 27976aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_IntegerAdd, I); 28076aa662cSKarthik Bhat case Instruction::Mul: 28176aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_IntegerMult, I); 28276aa662cSKarthik Bhat case Instruction::And: 28376aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_IntegerAnd, I); 28476aa662cSKarthik Bhat case Instruction::Or: 28576aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_IntegerOr, I); 28676aa662cSKarthik Bhat case Instruction::Xor: 28776aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_IntegerXor, I); 28876aa662cSKarthik Bhat case Instruction::FMul: 28976aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_FloatMult && FastMath, I); 29076aa662cSKarthik Bhat case Instruction::FSub: 29176aa662cSKarthik Bhat case Instruction::FAdd: 29276aa662cSKarthik Bhat return ReductionInstDesc(Kind == RK_FloatAdd && FastMath, I); 29376aa662cSKarthik Bhat case Instruction::FCmp: 29476aa662cSKarthik Bhat case Instruction::ICmp: 29576aa662cSKarthik Bhat case Instruction::Select: 29676aa662cSKarthik Bhat if (Kind != RK_IntegerMinMax && 29776aa662cSKarthik Bhat (!HasFunNoNaNAttr || Kind != RK_FloatMinMax)) 29876aa662cSKarthik Bhat return ReductionInstDesc(false, I); 29976aa662cSKarthik Bhat return isMinMaxSelectCmpPattern(I, Prev); 30076aa662cSKarthik Bhat } 30176aa662cSKarthik Bhat } 30276aa662cSKarthik Bhat 30376aa662cSKarthik Bhat bool ReductionDescriptor::hasMultipleUsesOf( 30476aa662cSKarthik Bhat Instruction *I, SmallPtrSetImpl<Instruction *> &Insts) { 30576aa662cSKarthik Bhat unsigned NumUses = 0; 30676aa662cSKarthik Bhat for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; 30776aa662cSKarthik Bhat ++Use) { 30876aa662cSKarthik Bhat if (Insts.count(dyn_cast<Instruction>(*Use))) 30976aa662cSKarthik Bhat ++NumUses; 31076aa662cSKarthik Bhat if (NumUses > 1) 31176aa662cSKarthik Bhat return true; 31276aa662cSKarthik Bhat } 31376aa662cSKarthik Bhat 31476aa662cSKarthik Bhat return false; 31576aa662cSKarthik Bhat } 31676aa662cSKarthik Bhat bool ReductionDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, 31776aa662cSKarthik Bhat ReductionDescriptor &RedDes) { 31876aa662cSKarthik Bhat 31976aa662cSKarthik Bhat bool HasFunNoNaNAttr = false; 32076aa662cSKarthik Bhat BasicBlock *Header = TheLoop->getHeader(); 32176aa662cSKarthik Bhat Function &F = *Header->getParent(); 32276aa662cSKarthik Bhat if (F.hasFnAttribute("no-nans-fp-math")) 32376aa662cSKarthik Bhat HasFunNoNaNAttr = 32476aa662cSKarthik Bhat F.getFnAttribute("no-nans-fp-math").getValueAsString() == "true"; 32576aa662cSKarthik Bhat 32676aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerAdd, TheLoop, HasFunNoNaNAttr, RedDes)) { 32776aa662cSKarthik Bhat DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n"); 32876aa662cSKarthik Bhat return true; 32976aa662cSKarthik Bhat } 33076aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerMult, TheLoop, HasFunNoNaNAttr, RedDes)) { 33176aa662cSKarthik Bhat DEBUG(dbgs() << "Found a MUL reduction PHI." << *Phi << "\n"); 33276aa662cSKarthik Bhat return true; 33376aa662cSKarthik Bhat } 33476aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerOr, TheLoop, HasFunNoNaNAttr, RedDes)) { 33576aa662cSKarthik Bhat DEBUG(dbgs() << "Found an OR reduction PHI." << *Phi << "\n"); 33676aa662cSKarthik Bhat return true; 33776aa662cSKarthik Bhat } 33876aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerAnd, TheLoop, HasFunNoNaNAttr, RedDes)) { 33976aa662cSKarthik Bhat DEBUG(dbgs() << "Found an AND reduction PHI." << *Phi << "\n"); 34076aa662cSKarthik Bhat return true; 34176aa662cSKarthik Bhat } 34276aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerXor, TheLoop, HasFunNoNaNAttr, RedDes)) { 34376aa662cSKarthik Bhat DEBUG(dbgs() << "Found a XOR reduction PHI." << *Phi << "\n"); 34476aa662cSKarthik Bhat return true; 34576aa662cSKarthik Bhat } 34676aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_IntegerMinMax, TheLoop, HasFunNoNaNAttr, 34776aa662cSKarthik Bhat RedDes)) { 34876aa662cSKarthik Bhat DEBUG(dbgs() << "Found a MINMAX reduction PHI." << *Phi << "\n"); 34976aa662cSKarthik Bhat return true; 35076aa662cSKarthik Bhat } 35176aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_FloatMult, TheLoop, HasFunNoNaNAttr, RedDes)) { 35276aa662cSKarthik Bhat DEBUG(dbgs() << "Found an FMult reduction PHI." << *Phi << "\n"); 35376aa662cSKarthik Bhat return true; 35476aa662cSKarthik Bhat } 35576aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_FloatAdd, TheLoop, HasFunNoNaNAttr, RedDes)) { 35676aa662cSKarthik Bhat DEBUG(dbgs() << "Found an FAdd reduction PHI." << *Phi << "\n"); 35776aa662cSKarthik Bhat return true; 35876aa662cSKarthik Bhat } 35976aa662cSKarthik Bhat if (AddReductionVar(Phi, RK_FloatMinMax, TheLoop, HasFunNoNaNAttr, RedDes)) { 36076aa662cSKarthik Bhat DEBUG(dbgs() << "Found an float MINMAX reduction PHI." << *Phi << "\n"); 36176aa662cSKarthik Bhat return true; 36276aa662cSKarthik Bhat } 36376aa662cSKarthik Bhat // Not a reduction of known type. 36476aa662cSKarthik Bhat return false; 36576aa662cSKarthik Bhat } 36676aa662cSKarthik Bhat 36776aa662cSKarthik Bhat /// This function returns the identity element (or neutral element) for 36876aa662cSKarthik Bhat /// the operation K. 36976aa662cSKarthik Bhat Constant *ReductionDescriptor::getReductionIdentity(ReductionKind K, Type *Tp) { 37076aa662cSKarthik Bhat switch (K) { 37176aa662cSKarthik Bhat case RK_IntegerXor: 37276aa662cSKarthik Bhat case RK_IntegerAdd: 37376aa662cSKarthik Bhat case RK_IntegerOr: 37476aa662cSKarthik Bhat // Adding, Xoring, Oring zero to a number does not change it. 37576aa662cSKarthik Bhat return ConstantInt::get(Tp, 0); 37676aa662cSKarthik Bhat case RK_IntegerMult: 37776aa662cSKarthik Bhat // Multiplying a number by 1 does not change it. 37876aa662cSKarthik Bhat return ConstantInt::get(Tp, 1); 37976aa662cSKarthik Bhat case RK_IntegerAnd: 38076aa662cSKarthik Bhat // AND-ing a number with an all-1 value does not change it. 38176aa662cSKarthik Bhat return ConstantInt::get(Tp, -1, true); 38276aa662cSKarthik Bhat case RK_FloatMult: 38376aa662cSKarthik Bhat // Multiplying a number by 1 does not change it. 38476aa662cSKarthik Bhat return ConstantFP::get(Tp, 1.0L); 38576aa662cSKarthik Bhat case RK_FloatAdd: 38676aa662cSKarthik Bhat // Adding zero to a number does not change it. 38776aa662cSKarthik Bhat return ConstantFP::get(Tp, 0.0L); 38876aa662cSKarthik Bhat default: 38976aa662cSKarthik Bhat llvm_unreachable("Unknown reduction kind"); 39076aa662cSKarthik Bhat } 39176aa662cSKarthik Bhat } 39276aa662cSKarthik Bhat 39376aa662cSKarthik Bhat /// This function translates the reduction kind to an LLVM binary operator. 39476aa662cSKarthik Bhat unsigned ReductionDescriptor::getReductionBinOp(ReductionKind Kind) { 39576aa662cSKarthik Bhat switch (Kind) { 39676aa662cSKarthik Bhat case RK_IntegerAdd: 39776aa662cSKarthik Bhat return Instruction::Add; 39876aa662cSKarthik Bhat case RK_IntegerMult: 39976aa662cSKarthik Bhat return Instruction::Mul; 40076aa662cSKarthik Bhat case RK_IntegerOr: 40176aa662cSKarthik Bhat return Instruction::Or; 40276aa662cSKarthik Bhat case RK_IntegerAnd: 40376aa662cSKarthik Bhat return Instruction::And; 40476aa662cSKarthik Bhat case RK_IntegerXor: 40576aa662cSKarthik Bhat return Instruction::Xor; 40676aa662cSKarthik Bhat case RK_FloatMult: 40776aa662cSKarthik Bhat return Instruction::FMul; 40876aa662cSKarthik Bhat case RK_FloatAdd: 40976aa662cSKarthik Bhat return Instruction::FAdd; 41076aa662cSKarthik Bhat case RK_IntegerMinMax: 41176aa662cSKarthik Bhat return Instruction::ICmp; 41276aa662cSKarthik Bhat case RK_FloatMinMax: 41376aa662cSKarthik Bhat return Instruction::FCmp; 41476aa662cSKarthik Bhat default: 41576aa662cSKarthik Bhat llvm_unreachable("Unknown reduction operation"); 41676aa662cSKarthik Bhat } 41776aa662cSKarthik Bhat } 41876aa662cSKarthik Bhat 41976aa662cSKarthik Bhat Value * 42076aa662cSKarthik Bhat ReductionDescriptor::createMinMaxOp(IRBuilder<> &Builder, 42176aa662cSKarthik Bhat ReductionInstDesc::MinMaxReductionKind RK, 42276aa662cSKarthik Bhat Value *Left, Value *Right) { 42376aa662cSKarthik Bhat CmpInst::Predicate P = CmpInst::ICMP_NE; 42476aa662cSKarthik Bhat switch (RK) { 42576aa662cSKarthik Bhat default: 42676aa662cSKarthik Bhat llvm_unreachable("Unknown min/max reduction kind"); 42776aa662cSKarthik Bhat case ReductionInstDesc::MRK_UIntMin: 42876aa662cSKarthik Bhat P = CmpInst::ICMP_ULT; 42976aa662cSKarthik Bhat break; 43076aa662cSKarthik Bhat case ReductionInstDesc::MRK_UIntMax: 43176aa662cSKarthik Bhat P = CmpInst::ICMP_UGT; 43276aa662cSKarthik Bhat break; 43376aa662cSKarthik Bhat case ReductionInstDesc::MRK_SIntMin: 43476aa662cSKarthik Bhat P = CmpInst::ICMP_SLT; 43576aa662cSKarthik Bhat break; 43676aa662cSKarthik Bhat case ReductionInstDesc::MRK_SIntMax: 43776aa662cSKarthik Bhat P = CmpInst::ICMP_SGT; 43876aa662cSKarthik Bhat break; 43976aa662cSKarthik Bhat case ReductionInstDesc::MRK_FloatMin: 44076aa662cSKarthik Bhat P = CmpInst::FCMP_OLT; 44176aa662cSKarthik Bhat break; 44276aa662cSKarthik Bhat case ReductionInstDesc::MRK_FloatMax: 44376aa662cSKarthik Bhat P = CmpInst::FCMP_OGT; 44476aa662cSKarthik Bhat break; 44576aa662cSKarthik Bhat } 44676aa662cSKarthik Bhat 44776aa662cSKarthik Bhat Value *Cmp; 44876aa662cSKarthik Bhat if (RK == ReductionInstDesc::MRK_FloatMin || 44976aa662cSKarthik Bhat RK == ReductionInstDesc::MRK_FloatMax) 45076aa662cSKarthik Bhat Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp"); 45176aa662cSKarthik Bhat else 45276aa662cSKarthik Bhat Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp"); 45376aa662cSKarthik Bhat 45476aa662cSKarthik Bhat Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select"); 45576aa662cSKarthik Bhat return Select; 45676aa662cSKarthik Bhat } 457*24e6cc2dSKarthik Bhat 458*24e6cc2dSKarthik Bhat bool llvm::isInductionPHI(PHINode *Phi, ScalarEvolution *SE, 459*24e6cc2dSKarthik Bhat ConstantInt *&StepValue) { 460*24e6cc2dSKarthik Bhat Type *PhiTy = Phi->getType(); 461*24e6cc2dSKarthik Bhat // We only handle integer and pointer inductions variables. 462*24e6cc2dSKarthik Bhat if (!PhiTy->isIntegerTy() && !PhiTy->isPointerTy()) 463*24e6cc2dSKarthik Bhat return false; 464*24e6cc2dSKarthik Bhat 465*24e6cc2dSKarthik Bhat // Check that the PHI is consecutive. 466*24e6cc2dSKarthik Bhat const SCEV *PhiScev = SE->getSCEV(Phi); 467*24e6cc2dSKarthik Bhat const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); 468*24e6cc2dSKarthik Bhat if (!AR) { 469*24e6cc2dSKarthik Bhat DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); 470*24e6cc2dSKarthik Bhat return false; 471*24e6cc2dSKarthik Bhat } 472*24e6cc2dSKarthik Bhat 473*24e6cc2dSKarthik Bhat const SCEV *Step = AR->getStepRecurrence(*SE); 474*24e6cc2dSKarthik Bhat // Calculate the pointer stride and check if it is consecutive. 475*24e6cc2dSKarthik Bhat const SCEVConstant *C = dyn_cast<SCEVConstant>(Step); 476*24e6cc2dSKarthik Bhat if (!C) 477*24e6cc2dSKarthik Bhat return false; 478*24e6cc2dSKarthik Bhat 479*24e6cc2dSKarthik Bhat ConstantInt *CV = C->getValue(); 480*24e6cc2dSKarthik Bhat if (PhiTy->isIntegerTy()) { 481*24e6cc2dSKarthik Bhat StepValue = CV; 482*24e6cc2dSKarthik Bhat return true; 483*24e6cc2dSKarthik Bhat } 484*24e6cc2dSKarthik Bhat 485*24e6cc2dSKarthik Bhat assert(PhiTy->isPointerTy() && "The PHI must be a pointer"); 486*24e6cc2dSKarthik Bhat Type *PointerElementType = PhiTy->getPointerElementType(); 487*24e6cc2dSKarthik Bhat // The pointer stride cannot be determined if the pointer element type is not 488*24e6cc2dSKarthik Bhat // sized. 489*24e6cc2dSKarthik Bhat if (!PointerElementType->isSized()) 490*24e6cc2dSKarthik Bhat return false; 491*24e6cc2dSKarthik Bhat 492*24e6cc2dSKarthik Bhat const DataLayout &DL = Phi->getModule()->getDataLayout(); 493*24e6cc2dSKarthik Bhat int64_t Size = static_cast<int64_t>(DL.getTypeAllocSize(PointerElementType)); 494*24e6cc2dSKarthik Bhat int64_t CVSize = CV->getSExtValue(); 495*24e6cc2dSKarthik Bhat if (CVSize % Size) 496*24e6cc2dSKarthik Bhat return false; 497*24e6cc2dSKarthik Bhat StepValue = ConstantInt::getSigned(CV->getType(), CVSize / Size); 498*24e6cc2dSKarthik Bhat return true; 499*24e6cc2dSKarthik Bhat } 500