1ff0cc061SDimitry Andric //===-- LoopUtils.cpp - Loop Utility functions -------------------------===//
2ff0cc061SDimitry Andric //
3ff0cc061SDimitry Andric //                     The LLVM Compiler Infrastructure
4ff0cc061SDimitry Andric //
5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source
6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details.
7ff0cc061SDimitry Andric //
8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
9ff0cc061SDimitry Andric //
10ff0cc061SDimitry Andric // This file defines common loop utility functions.
11ff0cc061SDimitry Andric //
12ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
13ff0cc061SDimitry Andric 
14d88c1a5aSDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h"
15edd7eaddSDimitry Andric #include "llvm/ADT/ScopeExit.h"
163ca95b02SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
173ca95b02SDimitry Andric #include "llvm/Analysis/BasicAliasAnalysis.h"
183ca95b02SDimitry Andric #include "llvm/Analysis/GlobalsModRef.h"
194ba319b5SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
20d88c1a5aSDimitry Andric #include "llvm/Analysis/LoopInfo.h"
21d88c1a5aSDimitry Andric #include "llvm/Analysis/LoopPass.h"
224ba319b5SDimitry Andric #include "llvm/Analysis/MustExecute.h"
237d523365SDimitry Andric #include "llvm/Analysis/ScalarEvolution.h"
24d88c1a5aSDimitry Andric #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
253ca95b02SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpander.h"
267d523365SDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h"
27db17bf38SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
284f8786afSDimitry Andric #include "llvm/Analysis/ValueTracking.h"
29*b5893f02SDimitry Andric #include "llvm/IR/DIBuilder.h"
30*b5893f02SDimitry Andric #include "llvm/IR/DomTreeUpdater.h"
313ca95b02SDimitry Andric #include "llvm/IR/Dominators.h"
32ff0cc061SDimitry Andric #include "llvm/IR/Instructions.h"
33*b5893f02SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
347d523365SDimitry Andric #include "llvm/IR/Module.h"
35ff0cc061SDimitry Andric #include "llvm/IR/PatternMatch.h"
36ff0cc061SDimitry Andric #include "llvm/IR/ValueHandle.h"
373ca95b02SDimitry Andric #include "llvm/Pass.h"
38ff0cc061SDimitry Andric #include "llvm/Support/Debug.h"
394f8786afSDimitry Andric #include "llvm/Support/KnownBits.h"
40edd7eaddSDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
41ff0cc061SDimitry Andric 
42ff0cc061SDimitry Andric using namespace llvm;
43ff0cc061SDimitry Andric using namespace llvm::PatternMatch;
44ff0cc061SDimitry Andric 
45ff0cc061SDimitry Andric #define DEBUG_TYPE "loop-utils"
46ff0cc061SDimitry Andric 
47*b5893f02SDimitry Andric static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced";
487d523365SDimitry Andric 
formDedicatedExitBlocks(Loop * L,DominatorTree * DT,LoopInfo * LI,bool PreserveLCSSA)49edd7eaddSDimitry Andric bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
50edd7eaddSDimitry Andric                                    bool PreserveLCSSA) {
51edd7eaddSDimitry Andric   bool Changed = false;
52edd7eaddSDimitry Andric 
53edd7eaddSDimitry Andric   // We re-use a vector for the in-loop predecesosrs.
54edd7eaddSDimitry Andric   SmallVector<BasicBlock *, 4> InLoopPredecessors;
55edd7eaddSDimitry Andric 
56edd7eaddSDimitry Andric   auto RewriteExit = [&](BasicBlock *BB) {
57edd7eaddSDimitry Andric     assert(InLoopPredecessors.empty() &&
58edd7eaddSDimitry Andric            "Must start with an empty predecessors list!");
59edd7eaddSDimitry Andric     auto Cleanup = make_scope_exit([&] { InLoopPredecessors.clear(); });
60edd7eaddSDimitry Andric 
61edd7eaddSDimitry Andric     // See if there are any non-loop predecessors of this exit block and
62edd7eaddSDimitry Andric     // keep track of the in-loop predecessors.
63edd7eaddSDimitry Andric     bool IsDedicatedExit = true;
64edd7eaddSDimitry Andric     for (auto *PredBB : predecessors(BB))
65edd7eaddSDimitry Andric       if (L->contains(PredBB)) {
66edd7eaddSDimitry Andric         if (isa<IndirectBrInst>(PredBB->getTerminator()))
67edd7eaddSDimitry Andric           // We cannot rewrite exiting edges from an indirectbr.
68edd7eaddSDimitry Andric           return false;
69edd7eaddSDimitry Andric 
70edd7eaddSDimitry Andric         InLoopPredecessors.push_back(PredBB);
71edd7eaddSDimitry Andric       } else {
72edd7eaddSDimitry Andric         IsDedicatedExit = false;
73edd7eaddSDimitry Andric       }
74edd7eaddSDimitry Andric 
75edd7eaddSDimitry Andric     assert(!InLoopPredecessors.empty() && "Must have *some* loop predecessor!");
76edd7eaddSDimitry Andric 
77edd7eaddSDimitry Andric     // Nothing to do if this is already a dedicated exit.
78edd7eaddSDimitry Andric     if (IsDedicatedExit)
79edd7eaddSDimitry Andric       return false;
80edd7eaddSDimitry Andric 
81edd7eaddSDimitry Andric     auto *NewExitBB = SplitBlockPredecessors(
82*b5893f02SDimitry Andric         BB, InLoopPredecessors, ".loopexit", DT, LI, nullptr, PreserveLCSSA);
83edd7eaddSDimitry Andric 
84edd7eaddSDimitry Andric     if (!NewExitBB)
854ba319b5SDimitry Andric       LLVM_DEBUG(
864ba319b5SDimitry Andric           dbgs() << "WARNING: Can't create a dedicated exit block for loop: "
87edd7eaddSDimitry Andric                  << *L << "\n");
88edd7eaddSDimitry Andric     else
894ba319b5SDimitry Andric       LLVM_DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block "
90edd7eaddSDimitry Andric                         << NewExitBB->getName() << "\n");
91edd7eaddSDimitry Andric     return true;
92edd7eaddSDimitry Andric   };
93edd7eaddSDimitry Andric 
94edd7eaddSDimitry Andric   // Walk the exit blocks directly rather than building up a data structure for
95edd7eaddSDimitry Andric   // them, but only visit each one once.
96edd7eaddSDimitry Andric   SmallPtrSet<BasicBlock *, 4> Visited;
97edd7eaddSDimitry Andric   for (auto *BB : L->blocks())
98edd7eaddSDimitry Andric     for (auto *SuccBB : successors(BB)) {
99edd7eaddSDimitry Andric       // We're looking for exit blocks so skip in-loop successors.
100edd7eaddSDimitry Andric       if (L->contains(SuccBB))
101edd7eaddSDimitry Andric         continue;
102edd7eaddSDimitry Andric 
103edd7eaddSDimitry Andric       // Visit each exit block exactly once.
104edd7eaddSDimitry Andric       if (!Visited.insert(SuccBB).second)
105edd7eaddSDimitry Andric         continue;
106edd7eaddSDimitry Andric 
107edd7eaddSDimitry Andric       Changed |= RewriteExit(SuccBB);
108edd7eaddSDimitry Andric     }
109edd7eaddSDimitry Andric 
110edd7eaddSDimitry Andric   return Changed;
111edd7eaddSDimitry Andric }
112edd7eaddSDimitry Andric 
1134ba319b5SDimitry Andric /// Returns the instructions that use values defined in the loop.
findDefsUsedOutsideOfLoop(Loop * L)1147d523365SDimitry Andric SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) {
1157d523365SDimitry Andric   SmallVector<Instruction *, 8> UsedOutside;
1167d523365SDimitry Andric 
1177d523365SDimitry Andric   for (auto *Block : L->getBlocks())
1187d523365SDimitry Andric     // FIXME: I believe that this could use copy_if if the Inst reference could
1197d523365SDimitry Andric     // be adapted into a pointer.
1207d523365SDimitry Andric     for (auto &Inst : *Block) {
1217d523365SDimitry Andric       auto Users = Inst.users();
122d88c1a5aSDimitry Andric       if (any_of(Users, [&](User *U) {
1237d523365SDimitry Andric             auto *Use = cast<Instruction>(U);
1247d523365SDimitry Andric             return !L->contains(Use->getParent());
1257d523365SDimitry Andric           }))
1267d523365SDimitry Andric         UsedOutside.push_back(&Inst);
1277d523365SDimitry Andric     }
1287d523365SDimitry Andric 
1297d523365SDimitry Andric   return UsedOutside;
1307d523365SDimitry Andric }
1313ca95b02SDimitry Andric 
getLoopAnalysisUsage(AnalysisUsage & AU)1323ca95b02SDimitry Andric void llvm::getLoopAnalysisUsage(AnalysisUsage &AU) {
1333ca95b02SDimitry Andric   // By definition, all loop passes need the LoopInfo analysis and the
1343ca95b02SDimitry Andric   // Dominator tree it depends on. Because they all participate in the loop
1353ca95b02SDimitry Andric   // pass manager, they must also preserve these.
1363ca95b02SDimitry Andric   AU.addRequired<DominatorTreeWrapperPass>();
1373ca95b02SDimitry Andric   AU.addPreserved<DominatorTreeWrapperPass>();
1383ca95b02SDimitry Andric   AU.addRequired<LoopInfoWrapperPass>();
1393ca95b02SDimitry Andric   AU.addPreserved<LoopInfoWrapperPass>();
1403ca95b02SDimitry Andric 
1413ca95b02SDimitry Andric   // We must also preserve LoopSimplify and LCSSA. We locally access their IDs
1423ca95b02SDimitry Andric   // here because users shouldn't directly get them from this header.
1433ca95b02SDimitry Andric   extern char &LoopSimplifyID;
1443ca95b02SDimitry Andric   extern char &LCSSAID;
1453ca95b02SDimitry Andric   AU.addRequiredID(LoopSimplifyID);
1463ca95b02SDimitry Andric   AU.addPreservedID(LoopSimplifyID);
1473ca95b02SDimitry Andric   AU.addRequiredID(LCSSAID);
1483ca95b02SDimitry Andric   AU.addPreservedID(LCSSAID);
149d88c1a5aSDimitry Andric   // This is used in the LPPassManager to perform LCSSA verification on passes
150d88c1a5aSDimitry Andric   // which preserve lcssa form
151d88c1a5aSDimitry Andric   AU.addRequired<LCSSAVerificationPass>();
152d88c1a5aSDimitry Andric   AU.addPreserved<LCSSAVerificationPass>();
1533ca95b02SDimitry Andric 
1543ca95b02SDimitry Andric   // Loop passes are designed to run inside of a loop pass manager which means
1553ca95b02SDimitry Andric   // that any function analyses they require must be required by the first loop
1563ca95b02SDimitry Andric   // pass in the manager (so that it is computed before the loop pass manager
1573ca95b02SDimitry Andric   // runs) and preserved by all loop pasess in the manager. To make this
1583ca95b02SDimitry Andric   // reasonably robust, the set needed for most loop passes is maintained here.
1593ca95b02SDimitry Andric   // If your loop pass requires an analysis not listed here, you will need to
1603ca95b02SDimitry Andric   // carefully audit the loop pass manager nesting structure that results.
1613ca95b02SDimitry Andric   AU.addRequired<AAResultsWrapperPass>();
1623ca95b02SDimitry Andric   AU.addPreserved<AAResultsWrapperPass>();
1633ca95b02SDimitry Andric   AU.addPreserved<BasicAAWrapperPass>();
1643ca95b02SDimitry Andric   AU.addPreserved<GlobalsAAWrapperPass>();
1653ca95b02SDimitry Andric   AU.addPreserved<SCEVAAWrapperPass>();
1663ca95b02SDimitry Andric   AU.addRequired<ScalarEvolutionWrapperPass>();
1673ca95b02SDimitry Andric   AU.addPreserved<ScalarEvolutionWrapperPass>();
1683ca95b02SDimitry Andric }
1693ca95b02SDimitry Andric 
1703ca95b02SDimitry Andric /// Manually defined generic "LoopPass" dependency initialization. This is used
1713ca95b02SDimitry Andric /// to initialize the exact set of passes from above in \c
1723ca95b02SDimitry Andric /// getLoopAnalysisUsage. It can be used within a loop pass's initialization
1733ca95b02SDimitry Andric /// with:
1743ca95b02SDimitry Andric ///
1753ca95b02SDimitry Andric ///   INITIALIZE_PASS_DEPENDENCY(LoopPass)
1763ca95b02SDimitry Andric ///
1773ca95b02SDimitry Andric /// As-if "LoopPass" were a pass.
initializeLoopPassPass(PassRegistry & Registry)1783ca95b02SDimitry Andric void llvm::initializeLoopPassPass(PassRegistry &Registry) {
1793ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
1803ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
1813ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
1823ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(LCSSAWrapperPass)
1833ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
1843ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
1853ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
1863ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
1873ca95b02SDimitry Andric   INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
1883ca95b02SDimitry Andric }
1893ca95b02SDimitry Andric 
1904ba319b5SDimitry Andric /// Find string metadata for loop
1913ca95b02SDimitry Andric ///
1923ca95b02SDimitry Andric /// If it has a value (e.g. {"llvm.distribute", 1} return the value as an
1933ca95b02SDimitry Andric /// operand or null otherwise.  If the string metadata is not found return
1943ca95b02SDimitry Andric /// Optional's not-a-value.
findStringMetadataForLoop(const Loop * TheLoop,StringRef Name)195*b5893f02SDimitry Andric Optional<const MDOperand *> llvm::findStringMetadataForLoop(const Loop *TheLoop,
1963ca95b02SDimitry Andric                                                             StringRef Name) {
197*b5893f02SDimitry Andric   MDNode *MD = findOptionMDForLoop(TheLoop, Name);
1983ca95b02SDimitry Andric   if (!MD)
199*b5893f02SDimitry Andric     return None;
2003ca95b02SDimitry Andric   switch (MD->getNumOperands()) {
2013ca95b02SDimitry Andric   case 1:
2023ca95b02SDimitry Andric     return nullptr;
2033ca95b02SDimitry Andric   case 2:
2043ca95b02SDimitry Andric     return &MD->getOperand(1);
2053ca95b02SDimitry Andric   default:
2063ca95b02SDimitry Andric     llvm_unreachable("loop metadata has 0 or 1 operand");
2073ca95b02SDimitry Andric   }
2083ca95b02SDimitry Andric }
209*b5893f02SDimitry Andric 
getOptionalBoolLoopAttribute(const Loop * TheLoop,StringRef Name)210*b5893f02SDimitry Andric static Optional<bool> getOptionalBoolLoopAttribute(const Loop *TheLoop,
211*b5893f02SDimitry Andric                                                    StringRef Name) {
212*b5893f02SDimitry Andric   MDNode *MD = findOptionMDForLoop(TheLoop, Name);
213*b5893f02SDimitry Andric   if (!MD)
2143ca95b02SDimitry Andric     return None;
215*b5893f02SDimitry Andric   switch (MD->getNumOperands()) {
216*b5893f02SDimitry Andric   case 1:
217*b5893f02SDimitry Andric     // When the value is absent it is interpreted as 'attribute set'.
218*b5893f02SDimitry Andric     return true;
219*b5893f02SDimitry Andric   case 2:
220*b5893f02SDimitry Andric     if (ConstantInt *IntMD =
221*b5893f02SDimitry Andric             mdconst::extract_or_null<ConstantInt>(MD->getOperand(1).get()))
222*b5893f02SDimitry Andric       return IntMD->getZExtValue();
223*b5893f02SDimitry Andric     return true;
224*b5893f02SDimitry Andric   }
225*b5893f02SDimitry Andric   llvm_unreachable("unexpected number of options");
226*b5893f02SDimitry Andric }
227*b5893f02SDimitry Andric 
getBooleanLoopAttribute(const Loop * TheLoop,StringRef Name)228*b5893f02SDimitry Andric static bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name) {
229*b5893f02SDimitry Andric   return getOptionalBoolLoopAttribute(TheLoop, Name).getValueOr(false);
230*b5893f02SDimitry Andric }
231*b5893f02SDimitry Andric 
getOptionalIntLoopAttribute(Loop * TheLoop,StringRef Name)232*b5893f02SDimitry Andric llvm::Optional<int> llvm::getOptionalIntLoopAttribute(Loop *TheLoop,
233*b5893f02SDimitry Andric                                                       StringRef Name) {
234*b5893f02SDimitry Andric   const MDOperand *AttrMD =
235*b5893f02SDimitry Andric       findStringMetadataForLoop(TheLoop, Name).getValueOr(nullptr);
236*b5893f02SDimitry Andric   if (!AttrMD)
237*b5893f02SDimitry Andric     return None;
238*b5893f02SDimitry Andric 
239*b5893f02SDimitry Andric   ConstantInt *IntMD = mdconst::extract_or_null<ConstantInt>(AttrMD->get());
240*b5893f02SDimitry Andric   if (!IntMD)
241*b5893f02SDimitry Andric     return None;
242*b5893f02SDimitry Andric 
243*b5893f02SDimitry Andric   return IntMD->getSExtValue();
244*b5893f02SDimitry Andric }
245*b5893f02SDimitry Andric 
makeFollowupLoopID(MDNode * OrigLoopID,ArrayRef<StringRef> FollowupOptions,const char * InheritOptionsExceptPrefix,bool AlwaysNew)246*b5893f02SDimitry Andric Optional<MDNode *> llvm::makeFollowupLoopID(
247*b5893f02SDimitry Andric     MDNode *OrigLoopID, ArrayRef<StringRef> FollowupOptions,
248*b5893f02SDimitry Andric     const char *InheritOptionsExceptPrefix, bool AlwaysNew) {
249*b5893f02SDimitry Andric   if (!OrigLoopID) {
250*b5893f02SDimitry Andric     if (AlwaysNew)
251*b5893f02SDimitry Andric       return nullptr;
252*b5893f02SDimitry Andric     return None;
253*b5893f02SDimitry Andric   }
254*b5893f02SDimitry Andric 
255*b5893f02SDimitry Andric   assert(OrigLoopID->getOperand(0) == OrigLoopID);
256*b5893f02SDimitry Andric 
257*b5893f02SDimitry Andric   bool InheritAllAttrs = !InheritOptionsExceptPrefix;
258*b5893f02SDimitry Andric   bool InheritSomeAttrs =
259*b5893f02SDimitry Andric       InheritOptionsExceptPrefix && InheritOptionsExceptPrefix[0] != '\0';
260*b5893f02SDimitry Andric   SmallVector<Metadata *, 8> MDs;
261*b5893f02SDimitry Andric   MDs.push_back(nullptr);
262*b5893f02SDimitry Andric 
263*b5893f02SDimitry Andric   bool Changed = false;
264*b5893f02SDimitry Andric   if (InheritAllAttrs || InheritSomeAttrs) {
265*b5893f02SDimitry Andric     for (const MDOperand &Existing : drop_begin(OrigLoopID->operands(), 1)) {
266*b5893f02SDimitry Andric       MDNode *Op = cast<MDNode>(Existing.get());
267*b5893f02SDimitry Andric 
268*b5893f02SDimitry Andric       auto InheritThisAttribute = [InheritSomeAttrs,
269*b5893f02SDimitry Andric                                    InheritOptionsExceptPrefix](MDNode *Op) {
270*b5893f02SDimitry Andric         if (!InheritSomeAttrs)
271*b5893f02SDimitry Andric           return false;
272*b5893f02SDimitry Andric 
273*b5893f02SDimitry Andric         // Skip malformatted attribute metadata nodes.
274*b5893f02SDimitry Andric         if (Op->getNumOperands() == 0)
275*b5893f02SDimitry Andric           return true;
276*b5893f02SDimitry Andric         Metadata *NameMD = Op->getOperand(0).get();
277*b5893f02SDimitry Andric         if (!isa<MDString>(NameMD))
278*b5893f02SDimitry Andric           return true;
279*b5893f02SDimitry Andric         StringRef AttrName = cast<MDString>(NameMD)->getString();
280*b5893f02SDimitry Andric 
281*b5893f02SDimitry Andric         // Do not inherit excluded attributes.
282*b5893f02SDimitry Andric         return !AttrName.startswith(InheritOptionsExceptPrefix);
283*b5893f02SDimitry Andric       };
284*b5893f02SDimitry Andric 
285*b5893f02SDimitry Andric       if (InheritThisAttribute(Op))
286*b5893f02SDimitry Andric         MDs.push_back(Op);
287*b5893f02SDimitry Andric       else
288*b5893f02SDimitry Andric         Changed = true;
289*b5893f02SDimitry Andric     }
290*b5893f02SDimitry Andric   } else {
291*b5893f02SDimitry Andric     // Modified if we dropped at least one attribute.
292*b5893f02SDimitry Andric     Changed = OrigLoopID->getNumOperands() > 1;
293*b5893f02SDimitry Andric   }
294*b5893f02SDimitry Andric 
295*b5893f02SDimitry Andric   bool HasAnyFollowup = false;
296*b5893f02SDimitry Andric   for (StringRef OptionName : FollowupOptions) {
297*b5893f02SDimitry Andric     MDNode *FollowupNode = findOptionMDForLoopID(OrigLoopID, OptionName);
298*b5893f02SDimitry Andric     if (!FollowupNode)
299*b5893f02SDimitry Andric       continue;
300*b5893f02SDimitry Andric 
301*b5893f02SDimitry Andric     HasAnyFollowup = true;
302*b5893f02SDimitry Andric     for (const MDOperand &Option : drop_begin(FollowupNode->operands(), 1)) {
303*b5893f02SDimitry Andric       MDs.push_back(Option.get());
304*b5893f02SDimitry Andric       Changed = true;
305*b5893f02SDimitry Andric     }
306*b5893f02SDimitry Andric   }
307*b5893f02SDimitry Andric 
308*b5893f02SDimitry Andric   // Attributes of the followup loop not specified explicity, so signal to the
309*b5893f02SDimitry Andric   // transformation pass to add suitable attributes.
310*b5893f02SDimitry Andric   if (!AlwaysNew && !HasAnyFollowup)
311*b5893f02SDimitry Andric     return None;
312*b5893f02SDimitry Andric 
313*b5893f02SDimitry Andric   // If no attributes were added or remove, the previous loop Id can be reused.
314*b5893f02SDimitry Andric   if (!AlwaysNew && !Changed)
315*b5893f02SDimitry Andric     return OrigLoopID;
316*b5893f02SDimitry Andric 
317*b5893f02SDimitry Andric   // No attributes is equivalent to having no !llvm.loop metadata at all.
318*b5893f02SDimitry Andric   if (MDs.size() == 1)
319*b5893f02SDimitry Andric     return nullptr;
320*b5893f02SDimitry Andric 
321*b5893f02SDimitry Andric   // Build the new loop ID.
322*b5893f02SDimitry Andric   MDTuple *FollowupLoopID = MDNode::get(OrigLoopID->getContext(), MDs);
323*b5893f02SDimitry Andric   FollowupLoopID->replaceOperandWith(0, FollowupLoopID);
324*b5893f02SDimitry Andric   return FollowupLoopID;
325*b5893f02SDimitry Andric }
326*b5893f02SDimitry Andric 
hasDisableAllTransformsHint(const Loop * L)327*b5893f02SDimitry Andric bool llvm::hasDisableAllTransformsHint(const Loop *L) {
328*b5893f02SDimitry Andric   return getBooleanLoopAttribute(L, LLVMLoopDisableNonforced);
329*b5893f02SDimitry Andric }
330*b5893f02SDimitry Andric 
hasUnrollTransformation(Loop * L)331*b5893f02SDimitry Andric TransformationMode llvm::hasUnrollTransformation(Loop *L) {
332*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.unroll.disable"))
333*b5893f02SDimitry Andric     return TM_SuppressedByUser;
334*b5893f02SDimitry Andric 
335*b5893f02SDimitry Andric   Optional<int> Count =
336*b5893f02SDimitry Andric       getOptionalIntLoopAttribute(L, "llvm.loop.unroll.count");
337*b5893f02SDimitry Andric   if (Count.hasValue())
338*b5893f02SDimitry Andric     return Count.getValue() == 1 ? TM_SuppressedByUser : TM_ForcedByUser;
339*b5893f02SDimitry Andric 
340*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.unroll.enable"))
341*b5893f02SDimitry Andric     return TM_ForcedByUser;
342*b5893f02SDimitry Andric 
343*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.unroll.full"))
344*b5893f02SDimitry Andric     return TM_ForcedByUser;
345*b5893f02SDimitry Andric 
346*b5893f02SDimitry Andric   if (hasDisableAllTransformsHint(L))
347*b5893f02SDimitry Andric     return TM_Disable;
348*b5893f02SDimitry Andric 
349*b5893f02SDimitry Andric   return TM_Unspecified;
350*b5893f02SDimitry Andric }
351*b5893f02SDimitry Andric 
hasUnrollAndJamTransformation(Loop * L)352*b5893f02SDimitry Andric TransformationMode llvm::hasUnrollAndJamTransformation(Loop *L) {
353*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.unroll_and_jam.disable"))
354*b5893f02SDimitry Andric     return TM_SuppressedByUser;
355*b5893f02SDimitry Andric 
356*b5893f02SDimitry Andric   Optional<int> Count =
357*b5893f02SDimitry Andric       getOptionalIntLoopAttribute(L, "llvm.loop.unroll_and_jam.count");
358*b5893f02SDimitry Andric   if (Count.hasValue())
359*b5893f02SDimitry Andric     return Count.getValue() == 1 ? TM_SuppressedByUser : TM_ForcedByUser;
360*b5893f02SDimitry Andric 
361*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.unroll_and_jam.enable"))
362*b5893f02SDimitry Andric     return TM_ForcedByUser;
363*b5893f02SDimitry Andric 
364*b5893f02SDimitry Andric   if (hasDisableAllTransformsHint(L))
365*b5893f02SDimitry Andric     return TM_Disable;
366*b5893f02SDimitry Andric 
367*b5893f02SDimitry Andric   return TM_Unspecified;
368*b5893f02SDimitry Andric }
369*b5893f02SDimitry Andric 
hasVectorizeTransformation(Loop * L)370*b5893f02SDimitry Andric TransformationMode llvm::hasVectorizeTransformation(Loop *L) {
371*b5893f02SDimitry Andric   Optional<bool> Enable =
372*b5893f02SDimitry Andric       getOptionalBoolLoopAttribute(L, "llvm.loop.vectorize.enable");
373*b5893f02SDimitry Andric 
374*b5893f02SDimitry Andric   if (Enable == false)
375*b5893f02SDimitry Andric     return TM_SuppressedByUser;
376*b5893f02SDimitry Andric 
377*b5893f02SDimitry Andric   Optional<int> VectorizeWidth =
378*b5893f02SDimitry Andric       getOptionalIntLoopAttribute(L, "llvm.loop.vectorize.width");
379*b5893f02SDimitry Andric   Optional<int> InterleaveCount =
380*b5893f02SDimitry Andric       getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count");
381*b5893f02SDimitry Andric 
382*b5893f02SDimitry Andric   // 'Forcing' vector width and interleave count to one effectively disables
383*b5893f02SDimitry Andric   // this tranformation.
384*b5893f02SDimitry Andric   if (Enable == true && VectorizeWidth == 1 && InterleaveCount == 1)
385*b5893f02SDimitry Andric     return TM_SuppressedByUser;
386*b5893f02SDimitry Andric 
387*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.isvectorized"))
388*b5893f02SDimitry Andric     return TM_Disable;
389*b5893f02SDimitry Andric 
390*b5893f02SDimitry Andric   if (Enable == true)
391*b5893f02SDimitry Andric     return TM_ForcedByUser;
392*b5893f02SDimitry Andric 
393*b5893f02SDimitry Andric   if (VectorizeWidth == 1 && InterleaveCount == 1)
394*b5893f02SDimitry Andric     return TM_Disable;
395*b5893f02SDimitry Andric 
396*b5893f02SDimitry Andric   if (VectorizeWidth > 1 || InterleaveCount > 1)
397*b5893f02SDimitry Andric     return TM_Enable;
398*b5893f02SDimitry Andric 
399*b5893f02SDimitry Andric   if (hasDisableAllTransformsHint(L))
400*b5893f02SDimitry Andric     return TM_Disable;
401*b5893f02SDimitry Andric 
402*b5893f02SDimitry Andric   return TM_Unspecified;
403*b5893f02SDimitry Andric }
404*b5893f02SDimitry Andric 
hasDistributeTransformation(Loop * L)405*b5893f02SDimitry Andric TransformationMode llvm::hasDistributeTransformation(Loop *L) {
406*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.distribute.enable"))
407*b5893f02SDimitry Andric     return TM_ForcedByUser;
408*b5893f02SDimitry Andric 
409*b5893f02SDimitry Andric   if (hasDisableAllTransformsHint(L))
410*b5893f02SDimitry Andric     return TM_Disable;
411*b5893f02SDimitry Andric 
412*b5893f02SDimitry Andric   return TM_Unspecified;
413*b5893f02SDimitry Andric }
414*b5893f02SDimitry Andric 
hasLICMVersioningTransformation(Loop * L)415*b5893f02SDimitry Andric TransformationMode llvm::hasLICMVersioningTransformation(Loop *L) {
416*b5893f02SDimitry Andric   if (getBooleanLoopAttribute(L, "llvm.loop.licm_versioning.disable"))
417*b5893f02SDimitry Andric     return TM_SuppressedByUser;
418*b5893f02SDimitry Andric 
419*b5893f02SDimitry Andric   if (hasDisableAllTransformsHint(L))
420*b5893f02SDimitry Andric     return TM_Disable;
421*b5893f02SDimitry Andric 
422*b5893f02SDimitry Andric   return TM_Unspecified;
4233ca95b02SDimitry Andric }
4243ca95b02SDimitry Andric 
4252cab237bSDimitry Andric /// Does a BFS from a given node to all of its children inside a given loop.
4262cab237bSDimitry Andric /// The returned vector of nodes includes the starting point.
4272cab237bSDimitry Andric SmallVector<DomTreeNode *, 16>
collectChildrenInLoop(DomTreeNode * N,const Loop * CurLoop)4282cab237bSDimitry Andric llvm::collectChildrenInLoop(DomTreeNode *N, const Loop *CurLoop) {
4292cab237bSDimitry Andric   SmallVector<DomTreeNode *, 16> Worklist;
4302cab237bSDimitry Andric   auto AddRegionToWorklist = [&](DomTreeNode *DTN) {
4312cab237bSDimitry Andric     // Only include subregions in the top level loop.
4322cab237bSDimitry Andric     BasicBlock *BB = DTN->getBlock();
4332cab237bSDimitry Andric     if (CurLoop->contains(BB))
4342cab237bSDimitry Andric       Worklist.push_back(DTN);
4352cab237bSDimitry Andric   };
4362cab237bSDimitry Andric 
4372cab237bSDimitry Andric   AddRegionToWorklist(N);
4382cab237bSDimitry Andric 
4392cab237bSDimitry Andric   for (size_t I = 0; I < Worklist.size(); I++)
4402cab237bSDimitry Andric     for (DomTreeNode *Child : Worklist[I]->getChildren())
4412cab237bSDimitry Andric       AddRegionToWorklist(Child);
4422cab237bSDimitry Andric 
4432cab237bSDimitry Andric   return Worklist;
4442cab237bSDimitry Andric }
4452cab237bSDimitry Andric 
deleteDeadLoop(Loop * L,DominatorTree * DT=nullptr,ScalarEvolution * SE=nullptr,LoopInfo * LI=nullptr)4462cab237bSDimitry Andric void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr,
4472cab237bSDimitry Andric                           ScalarEvolution *SE = nullptr,
4482cab237bSDimitry Andric                           LoopInfo *LI = nullptr) {
4492cab237bSDimitry Andric   assert((!DT || L->isLCSSAForm(*DT)) && "Expected LCSSA!");
4502cab237bSDimitry Andric   auto *Preheader = L->getLoopPreheader();
4512cab237bSDimitry Andric   assert(Preheader && "Preheader should exist!");
4522cab237bSDimitry Andric 
4532cab237bSDimitry Andric   // Now that we know the removal is safe, remove the loop by changing the
4542cab237bSDimitry Andric   // branch from the preheader to go to the single exit block.
4552cab237bSDimitry Andric   //
4562cab237bSDimitry Andric   // Because we're deleting a large chunk of code at once, the sequence in which
4572cab237bSDimitry Andric   // we remove things is very important to avoid invalidation issues.
4582cab237bSDimitry Andric 
4592cab237bSDimitry Andric   // Tell ScalarEvolution that the loop is deleted. Do this before
4602cab237bSDimitry Andric   // deleting the loop so that ScalarEvolution can look at the loop
4612cab237bSDimitry Andric   // to determine what it needs to clean up.
4622cab237bSDimitry Andric   if (SE)
4632cab237bSDimitry Andric     SE->forgetLoop(L);
4642cab237bSDimitry Andric 
4652cab237bSDimitry Andric   auto *ExitBlock = L->getUniqueExitBlock();
4662cab237bSDimitry Andric   assert(ExitBlock && "Should have a unique exit block!");
4672cab237bSDimitry Andric   assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
4682cab237bSDimitry Andric 
4692cab237bSDimitry Andric   auto *OldBr = dyn_cast<BranchInst>(Preheader->getTerminator());
4702cab237bSDimitry Andric   assert(OldBr && "Preheader must end with a branch");
4712cab237bSDimitry Andric   assert(OldBr->isUnconditional() && "Preheader must have a single successor");
4722cab237bSDimitry Andric   // Connect the preheader to the exit block. Keep the old edge to the header
4732cab237bSDimitry Andric   // around to perform the dominator tree update in two separate steps
4742cab237bSDimitry Andric   // -- #1 insertion of the edge preheader -> exit and #2 deletion of the edge
4752cab237bSDimitry Andric   // preheader -> header.
4762cab237bSDimitry Andric   //
4772cab237bSDimitry Andric   //
4782cab237bSDimitry Andric   // 0.  Preheader          1.  Preheader           2.  Preheader
4792cab237bSDimitry Andric   //        |                    |   |                   |
4802cab237bSDimitry Andric   //        V                    |   V                   |
4812cab237bSDimitry Andric   //      Header <--\            | Header <--\           | Header <--\
4822cab237bSDimitry Andric   //       |  |     |            |  |  |     |           |  |  |     |
4832cab237bSDimitry Andric   //       |  V     |            |  |  V     |           |  |  V     |
4842cab237bSDimitry Andric   //       | Body --/            |  | Body --/           |  | Body --/
4852cab237bSDimitry Andric   //       V                     V  V                    V  V
4862cab237bSDimitry Andric   //      Exit                   Exit                    Exit
4872cab237bSDimitry Andric   //
4882cab237bSDimitry Andric   // By doing this is two separate steps we can perform the dominator tree
4892cab237bSDimitry Andric   // update without using the batch update API.
4902cab237bSDimitry Andric   //
4912cab237bSDimitry Andric   // Even when the loop is never executed, we cannot remove the edge from the
4922cab237bSDimitry Andric   // source block to the exit block. Consider the case where the unexecuted loop
4932cab237bSDimitry Andric   // branches back to an outer loop. If we deleted the loop and removed the edge
4942cab237bSDimitry Andric   // coming to this inner loop, this will break the outer loop structure (by
4952cab237bSDimitry Andric   // deleting the backedge of the outer loop). If the outer loop is indeed a
4962cab237bSDimitry Andric   // non-loop, it will be deleted in a future iteration of loop deletion pass.
4972cab237bSDimitry Andric   IRBuilder<> Builder(OldBr);
4982cab237bSDimitry Andric   Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock);
4992cab237bSDimitry Andric   // Remove the old branch. The conditional branch becomes a new terminator.
5002cab237bSDimitry Andric   OldBr->eraseFromParent();
5012cab237bSDimitry Andric 
5022cab237bSDimitry Andric   // Rewrite phis in the exit block to get their inputs from the Preheader
5032cab237bSDimitry Andric   // instead of the exiting block.
50430785c0eSDimitry Andric   for (PHINode &P : ExitBlock->phis()) {
5052cab237bSDimitry Andric     // Set the zero'th element of Phi to be from the preheader and remove all
5062cab237bSDimitry Andric     // other incoming values. Given the loop has dedicated exits, all other
5072cab237bSDimitry Andric     // incoming values must be from the exiting blocks.
5082cab237bSDimitry Andric     int PredIndex = 0;
50930785c0eSDimitry Andric     P.setIncomingBlock(PredIndex, Preheader);
5102cab237bSDimitry Andric     // Removes all incoming values from all other exiting blocks (including
5112cab237bSDimitry Andric     // duplicate values from an exiting block).
5122cab237bSDimitry Andric     // Nuke all entries except the zero'th entry which is the preheader entry.
5132cab237bSDimitry Andric     // NOTE! We need to remove Incoming Values in the reverse order as done
5142cab237bSDimitry Andric     // below, to keep the indices valid for deletion (removeIncomingValues
5152cab237bSDimitry Andric     // updates getNumIncomingValues and shifts all values down into the operand
5162cab237bSDimitry Andric     // being deleted).
51730785c0eSDimitry Andric     for (unsigned i = 0, e = P.getNumIncomingValues() - 1; i != e; ++i)
51830785c0eSDimitry Andric       P.removeIncomingValue(e - i, false);
5192cab237bSDimitry Andric 
52030785c0eSDimitry Andric     assert((P.getNumIncomingValues() == 1 &&
52130785c0eSDimitry Andric             P.getIncomingBlock(PredIndex) == Preheader) &&
5222cab237bSDimitry Andric            "Should have exactly one value and that's from the preheader!");
5232cab237bSDimitry Andric   }
5242cab237bSDimitry Andric 
5252cab237bSDimitry Andric   // Disconnect the loop body by branching directly to its exit.
5262cab237bSDimitry Andric   Builder.SetInsertPoint(Preheader->getTerminator());
5272cab237bSDimitry Andric   Builder.CreateBr(ExitBlock);
5282cab237bSDimitry Andric   // Remove the old branch.
5292cab237bSDimitry Andric   Preheader->getTerminator()->eraseFromParent();
5302cab237bSDimitry Andric 
531*b5893f02SDimitry Andric   DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
5322cab237bSDimitry Andric   if (DT) {
5332cab237bSDimitry Andric     // Update the dominator tree by informing it about the new edge from the
5342cab237bSDimitry Andric     // preheader to the exit.
535*b5893f02SDimitry Andric     DTU.insertEdge(Preheader, ExitBlock);
5362cab237bSDimitry Andric     // Inform the dominator tree about the removed edge.
537*b5893f02SDimitry Andric     DTU.deleteEdge(Preheader, L->getHeader());
5382cab237bSDimitry Andric   }
5392cab237bSDimitry Andric 
540*b5893f02SDimitry Andric   // Use a map to unique and a vector to guarantee deterministic ordering.
541*b5893f02SDimitry Andric   llvm::SmallDenseSet<std::pair<DIVariable *, DIExpression *>, 4> DeadDebugSet;
542*b5893f02SDimitry Andric   llvm::SmallVector<DbgVariableIntrinsic *, 4> DeadDebugInst;
543*b5893f02SDimitry Andric 
5444ba319b5SDimitry Andric   // Given LCSSA form is satisfied, we should not have users of instructions
5454ba319b5SDimitry Andric   // within the dead loop outside of the loop. However, LCSSA doesn't take
5464ba319b5SDimitry Andric   // unreachable uses into account. We handle them here.
5474ba319b5SDimitry Andric   // We could do it after drop all references (in this case all users in the
5484ba319b5SDimitry Andric   // loop will be already eliminated and we have less work to do but according
5494ba319b5SDimitry Andric   // to API doc of User::dropAllReferences only valid operation after dropping
5504ba319b5SDimitry Andric   // references, is deletion. So let's substitute all usages of
5514ba319b5SDimitry Andric   // instruction from the loop with undef value of corresponding type first.
5524ba319b5SDimitry Andric   for (auto *Block : L->blocks())
5534ba319b5SDimitry Andric     for (Instruction &I : *Block) {
5544ba319b5SDimitry Andric       auto *Undef = UndefValue::get(I.getType());
5554ba319b5SDimitry Andric       for (Value::use_iterator UI = I.use_begin(), E = I.use_end(); UI != E;) {
5564ba319b5SDimitry Andric         Use &U = *UI;
5574ba319b5SDimitry Andric         ++UI;
5584ba319b5SDimitry Andric         if (auto *Usr = dyn_cast<Instruction>(U.getUser()))
5594ba319b5SDimitry Andric           if (L->contains(Usr->getParent()))
5604ba319b5SDimitry Andric             continue;
5614ba319b5SDimitry Andric         // If we have a DT then we can check that uses outside a loop only in
5624ba319b5SDimitry Andric         // unreachable block.
5634ba319b5SDimitry Andric         if (DT)
5644ba319b5SDimitry Andric           assert(!DT->isReachableFromEntry(U) &&
5654ba319b5SDimitry Andric                  "Unexpected user in reachable block");
5664ba319b5SDimitry Andric         U.set(Undef);
5674ba319b5SDimitry Andric       }
568*b5893f02SDimitry Andric       auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I);
569*b5893f02SDimitry Andric       if (!DVI)
570*b5893f02SDimitry Andric         continue;
571*b5893f02SDimitry Andric       auto Key = DeadDebugSet.find({DVI->getVariable(), DVI->getExpression()});
572*b5893f02SDimitry Andric       if (Key != DeadDebugSet.end())
573*b5893f02SDimitry Andric         continue;
574*b5893f02SDimitry Andric       DeadDebugSet.insert({DVI->getVariable(), DVI->getExpression()});
575*b5893f02SDimitry Andric       DeadDebugInst.push_back(DVI);
5764ba319b5SDimitry Andric     }
5774ba319b5SDimitry Andric 
578*b5893f02SDimitry Andric   // After the loop has been deleted all the values defined and modified
579*b5893f02SDimitry Andric   // inside the loop are going to be unavailable.
580*b5893f02SDimitry Andric   // Since debug values in the loop have been deleted, inserting an undef
581*b5893f02SDimitry Andric   // dbg.value truncates the range of any dbg.value before the loop where the
582*b5893f02SDimitry Andric   // loop used to be. This is particularly important for constant values.
583*b5893f02SDimitry Andric   DIBuilder DIB(*ExitBlock->getModule());
584*b5893f02SDimitry Andric   for (auto *DVI : DeadDebugInst)
585*b5893f02SDimitry Andric     DIB.insertDbgValueIntrinsic(
586*b5893f02SDimitry Andric         UndefValue::get(Builder.getInt32Ty()), DVI->getVariable(),
587*b5893f02SDimitry Andric         DVI->getExpression(), DVI->getDebugLoc(), ExitBlock->getFirstNonPHI());
588*b5893f02SDimitry Andric 
5892cab237bSDimitry Andric   // Remove the block from the reference counting scheme, so that we can
5902cab237bSDimitry Andric   // delete it freely later.
5912cab237bSDimitry Andric   for (auto *Block : L->blocks())
5922cab237bSDimitry Andric     Block->dropAllReferences();
5932cab237bSDimitry Andric 
5942cab237bSDimitry Andric   if (LI) {
5952cab237bSDimitry Andric     // Erase the instructions and the blocks without having to worry
5962cab237bSDimitry Andric     // about ordering because we already dropped the references.
5972cab237bSDimitry Andric     // NOTE: This iteration is safe because erasing the block does not remove
5982cab237bSDimitry Andric     // its entry from the loop's block list.  We do that in the next section.
5992cab237bSDimitry Andric     for (Loop::block_iterator LpI = L->block_begin(), LpE = L->block_end();
6002cab237bSDimitry Andric          LpI != LpE; ++LpI)
6012cab237bSDimitry Andric       (*LpI)->eraseFromParent();
6022cab237bSDimitry Andric 
6032cab237bSDimitry Andric     // Finally, the blocks from loopinfo.  This has to happen late because
6042cab237bSDimitry Andric     // otherwise our loop iterators won't work.
6052cab237bSDimitry Andric 
6062cab237bSDimitry Andric     SmallPtrSet<BasicBlock *, 8> blocks;
6072cab237bSDimitry Andric     blocks.insert(L->block_begin(), L->block_end());
6082cab237bSDimitry Andric     for (BasicBlock *BB : blocks)
6092cab237bSDimitry Andric       LI->removeBlock(BB);
6102cab237bSDimitry Andric 
6112cab237bSDimitry Andric     // The last step is to update LoopInfo now that we've eliminated this loop.
6122cab237bSDimitry Andric     LI->erase(L);
6132cab237bSDimitry Andric   }
6142cab237bSDimitry Andric }
6152cab237bSDimitry Andric 
getLoopEstimatedTripCount(Loop * L)616d88c1a5aSDimitry Andric Optional<unsigned> llvm::getLoopEstimatedTripCount(Loop *L) {
617d88c1a5aSDimitry Andric   // Only support loops with a unique exiting block, and a latch.
618d88c1a5aSDimitry Andric   if (!L->getExitingBlock())
619d88c1a5aSDimitry Andric     return None;
620d88c1a5aSDimitry Andric 
6214ba319b5SDimitry Andric   // Get the branch weights for the loop's backedge.
622d88c1a5aSDimitry Andric   BranchInst *LatchBR =
623d88c1a5aSDimitry Andric       dyn_cast<BranchInst>(L->getLoopLatch()->getTerminator());
624d88c1a5aSDimitry Andric   if (!LatchBR || LatchBR->getNumSuccessors() != 2)
625d88c1a5aSDimitry Andric     return None;
626d88c1a5aSDimitry Andric 
627d88c1a5aSDimitry Andric   assert((LatchBR->getSuccessor(0) == L->getHeader() ||
628d88c1a5aSDimitry Andric           LatchBR->getSuccessor(1) == L->getHeader()) &&
629d88c1a5aSDimitry Andric          "At least one edge out of the latch must go to the header");
630d88c1a5aSDimitry Andric 
631d88c1a5aSDimitry Andric   // To estimate the number of times the loop body was executed, we want to
632d88c1a5aSDimitry Andric   // know the number of times the backedge was taken, vs. the number of times
633d88c1a5aSDimitry Andric   // we exited the loop.
634d88c1a5aSDimitry Andric   uint64_t TrueVal, FalseVal;
635d88c1a5aSDimitry Andric   if (!LatchBR->extractProfMetadata(TrueVal, FalseVal))
636d88c1a5aSDimitry Andric     return None;
637d88c1a5aSDimitry Andric 
638d88c1a5aSDimitry Andric   if (!TrueVal || !FalseVal)
639d88c1a5aSDimitry Andric     return 0;
640d88c1a5aSDimitry Andric 
641d88c1a5aSDimitry Andric   // Divide the count of the backedge by the count of the edge exiting the loop,
642d88c1a5aSDimitry Andric   // rounding to nearest.
643d88c1a5aSDimitry Andric   if (LatchBR->getSuccessor(0) == L->getHeader())
644d88c1a5aSDimitry Andric     return (TrueVal + (FalseVal / 2)) / FalseVal;
645d88c1a5aSDimitry Andric   else
646d88c1a5aSDimitry Andric     return (FalseVal + (TrueVal / 2)) / TrueVal;
647d88c1a5aSDimitry Andric }
6485517e702SDimitry Andric 
hasIterationCountInvariantInParent(Loop * InnerLoop,ScalarEvolution & SE)649*b5893f02SDimitry Andric bool llvm::hasIterationCountInvariantInParent(Loop *InnerLoop,
650*b5893f02SDimitry Andric                                               ScalarEvolution &SE) {
651*b5893f02SDimitry Andric   Loop *OuterL = InnerLoop->getParentLoop();
652*b5893f02SDimitry Andric   if (!OuterL)
653*b5893f02SDimitry Andric     return true;
654*b5893f02SDimitry Andric 
655*b5893f02SDimitry Andric   // Get the backedge taken count for the inner loop
656*b5893f02SDimitry Andric   BasicBlock *InnerLoopLatch = InnerLoop->getLoopLatch();
657*b5893f02SDimitry Andric   const SCEV *InnerLoopBECountSC = SE.getExitCount(InnerLoop, InnerLoopLatch);
658*b5893f02SDimitry Andric   if (isa<SCEVCouldNotCompute>(InnerLoopBECountSC) ||
659*b5893f02SDimitry Andric       !InnerLoopBECountSC->getType()->isIntegerTy())
660*b5893f02SDimitry Andric     return false;
661*b5893f02SDimitry Andric 
662*b5893f02SDimitry Andric   // Get whether count is invariant to the outer loop
663*b5893f02SDimitry Andric   ScalarEvolution::LoopDisposition LD =
664*b5893f02SDimitry Andric       SE.getLoopDisposition(InnerLoopBECountSC, OuterL);
665*b5893f02SDimitry Andric   if (LD != ScalarEvolution::LoopInvariant)
666*b5893f02SDimitry Andric     return false;
667*b5893f02SDimitry Andric 
668*b5893f02SDimitry Andric   return true;
669*b5893f02SDimitry Andric }
670*b5893f02SDimitry Andric 
6714ba319b5SDimitry Andric /// Adds a 'fast' flag to floating point operations.
addFastMathFlag(Value * V)6725517e702SDimitry Andric static Value *addFastMathFlag(Value *V) {
6735517e702SDimitry Andric   if (isa<FPMathOperator>(V)) {
6745517e702SDimitry Andric     FastMathFlags Flags;
6752cab237bSDimitry Andric     Flags.setFast();
6765517e702SDimitry Andric     cast<Instruction>(V)->setFastMathFlags(Flags);
6775517e702SDimitry Andric   }
6785517e702SDimitry Andric   return V;
6795517e702SDimitry Andric }
6805517e702SDimitry Andric 
createMinMaxOp(IRBuilder<> & Builder,RecurrenceDescriptor::MinMaxRecurrenceKind RK,Value * Left,Value * Right)681*b5893f02SDimitry Andric Value *llvm::createMinMaxOp(IRBuilder<> &Builder,
682*b5893f02SDimitry Andric                             RecurrenceDescriptor::MinMaxRecurrenceKind RK,
683*b5893f02SDimitry Andric                             Value *Left, Value *Right) {
684*b5893f02SDimitry Andric   CmpInst::Predicate P = CmpInst::ICMP_NE;
685*b5893f02SDimitry Andric   switch (RK) {
686*b5893f02SDimitry Andric   default:
687*b5893f02SDimitry Andric     llvm_unreachable("Unknown min/max recurrence kind");
688*b5893f02SDimitry Andric   case RecurrenceDescriptor::MRK_UIntMin:
689*b5893f02SDimitry Andric     P = CmpInst::ICMP_ULT;
690*b5893f02SDimitry Andric     break;
691*b5893f02SDimitry Andric   case RecurrenceDescriptor::MRK_UIntMax:
692*b5893f02SDimitry Andric     P = CmpInst::ICMP_UGT;
693*b5893f02SDimitry Andric     break;
694*b5893f02SDimitry Andric   case RecurrenceDescriptor::MRK_SIntMin:
695*b5893f02SDimitry Andric     P = CmpInst::ICMP_SLT;
696*b5893f02SDimitry Andric     break;
697*b5893f02SDimitry Andric   case RecurrenceDescriptor::MRK_SIntMax:
698*b5893f02SDimitry Andric     P = CmpInst::ICMP_SGT;
699*b5893f02SDimitry Andric     break;
700*b5893f02SDimitry Andric   case RecurrenceDescriptor::MRK_FloatMin:
701*b5893f02SDimitry Andric     P = CmpInst::FCMP_OLT;
702*b5893f02SDimitry Andric     break;
703*b5893f02SDimitry Andric   case RecurrenceDescriptor::MRK_FloatMax:
704*b5893f02SDimitry Andric     P = CmpInst::FCMP_OGT;
705*b5893f02SDimitry Andric     break;
706*b5893f02SDimitry Andric   }
707*b5893f02SDimitry Andric 
708*b5893f02SDimitry Andric   // We only match FP sequences that are 'fast', so we can unconditionally
709*b5893f02SDimitry Andric   // set it on any generated instructions.
710*b5893f02SDimitry Andric   IRBuilder<>::FastMathFlagGuard FMFG(Builder);
711*b5893f02SDimitry Andric   FastMathFlags FMF;
712*b5893f02SDimitry Andric   FMF.setFast();
713*b5893f02SDimitry Andric   Builder.setFastMathFlags(FMF);
714*b5893f02SDimitry Andric 
715*b5893f02SDimitry Andric   Value *Cmp;
716*b5893f02SDimitry Andric   if (RK == RecurrenceDescriptor::MRK_FloatMin ||
717*b5893f02SDimitry Andric       RK == RecurrenceDescriptor::MRK_FloatMax)
718*b5893f02SDimitry Andric     Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp");
719*b5893f02SDimitry Andric   else
720*b5893f02SDimitry Andric     Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp");
721*b5893f02SDimitry Andric 
722*b5893f02SDimitry Andric   Value *Select = Builder.CreateSelect(Cmp, Left, Right, "rdx.minmax.select");
723*b5893f02SDimitry Andric   return Select;
724*b5893f02SDimitry Andric }
725*b5893f02SDimitry Andric 
7264ba319b5SDimitry Andric // Helper to generate an ordered reduction.
7274ba319b5SDimitry Andric Value *
getOrderedReduction(IRBuilder<> & Builder,Value * Acc,Value * Src,unsigned Op,RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind,ArrayRef<Value * > RedOps)7284ba319b5SDimitry Andric llvm::getOrderedReduction(IRBuilder<> &Builder, Value *Acc, Value *Src,
7294ba319b5SDimitry Andric                           unsigned Op,
7304ba319b5SDimitry Andric                           RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind,
7314ba319b5SDimitry Andric                           ArrayRef<Value *> RedOps) {
7324ba319b5SDimitry Andric   unsigned VF = Src->getType()->getVectorNumElements();
7334ba319b5SDimitry Andric 
7344ba319b5SDimitry Andric   // Extract and apply reduction ops in ascending order:
7354ba319b5SDimitry Andric   // e.g. ((((Acc + Scl[0]) + Scl[1]) + Scl[2]) + ) ... + Scl[VF-1]
7364ba319b5SDimitry Andric   Value *Result = Acc;
7374ba319b5SDimitry Andric   for (unsigned ExtractIdx = 0; ExtractIdx != VF; ++ExtractIdx) {
7384ba319b5SDimitry Andric     Value *Ext =
7394ba319b5SDimitry Andric         Builder.CreateExtractElement(Src, Builder.getInt32(ExtractIdx));
7404ba319b5SDimitry Andric 
7414ba319b5SDimitry Andric     if (Op != Instruction::ICmp && Op != Instruction::FCmp) {
7424ba319b5SDimitry Andric       Result = Builder.CreateBinOp((Instruction::BinaryOps)Op, Result, Ext,
7434ba319b5SDimitry Andric                                    "bin.rdx");
7444ba319b5SDimitry Andric     } else {
7454ba319b5SDimitry Andric       assert(MinMaxKind != RecurrenceDescriptor::MRK_Invalid &&
7464ba319b5SDimitry Andric              "Invalid min/max");
747*b5893f02SDimitry Andric       Result = createMinMaxOp(Builder, MinMaxKind, Result, Ext);
7484ba319b5SDimitry Andric     }
7494ba319b5SDimitry Andric 
7504ba319b5SDimitry Andric     if (!RedOps.empty())
7514ba319b5SDimitry Andric       propagateIRFlags(Result, RedOps);
7524ba319b5SDimitry Andric   }
7534ba319b5SDimitry Andric 
7544ba319b5SDimitry Andric   return Result;
7554ba319b5SDimitry Andric }
7564ba319b5SDimitry Andric 
7575517e702SDimitry Andric // Helper to generate a log2 shuffle reduction.
7585517e702SDimitry Andric Value *
getShuffleReduction(IRBuilder<> & Builder,Value * Src,unsigned Op,RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind,ArrayRef<Value * > RedOps)7595517e702SDimitry Andric llvm::getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
7605517e702SDimitry Andric                           RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind,
7615517e702SDimitry Andric                           ArrayRef<Value *> RedOps) {
7625517e702SDimitry Andric   unsigned VF = Src->getType()->getVectorNumElements();
7635517e702SDimitry Andric   // VF is a power of 2 so we can emit the reduction using log2(VF) shuffles
7645517e702SDimitry Andric   // and vector ops, reducing the set of values being computed by half each
7655517e702SDimitry Andric   // round.
7665517e702SDimitry Andric   assert(isPowerOf2_32(VF) &&
7675517e702SDimitry Andric          "Reduction emission only supported for pow2 vectors!");
7685517e702SDimitry Andric   Value *TmpVec = Src;
7695517e702SDimitry Andric   SmallVector<Constant *, 32> ShuffleMask(VF, nullptr);
7705517e702SDimitry Andric   for (unsigned i = VF; i != 1; i >>= 1) {
7715517e702SDimitry Andric     // Move the upper half of the vector to the lower half.
7725517e702SDimitry Andric     for (unsigned j = 0; j != i / 2; ++j)
7735517e702SDimitry Andric       ShuffleMask[j] = Builder.getInt32(i / 2 + j);
7745517e702SDimitry Andric 
7755517e702SDimitry Andric     // Fill the rest of the mask with undef.
7765517e702SDimitry Andric     std::fill(&ShuffleMask[i / 2], ShuffleMask.end(),
7775517e702SDimitry Andric               UndefValue::get(Builder.getInt32Ty()));
7785517e702SDimitry Andric 
7795517e702SDimitry Andric     Value *Shuf = Builder.CreateShuffleVector(
7805517e702SDimitry Andric         TmpVec, UndefValue::get(TmpVec->getType()),
7815517e702SDimitry Andric         ConstantVector::get(ShuffleMask), "rdx.shuf");
7825517e702SDimitry Andric 
7835517e702SDimitry Andric     if (Op != Instruction::ICmp && Op != Instruction::FCmp) {
7845517e702SDimitry Andric       // Floating point operations had to be 'fast' to enable the reduction.
7855517e702SDimitry Andric       TmpVec = addFastMathFlag(Builder.CreateBinOp((Instruction::BinaryOps)Op,
7865517e702SDimitry Andric                                                    TmpVec, Shuf, "bin.rdx"));
7875517e702SDimitry Andric     } else {
7885517e702SDimitry Andric       assert(MinMaxKind != RecurrenceDescriptor::MRK_Invalid &&
7895517e702SDimitry Andric              "Invalid min/max");
790*b5893f02SDimitry Andric       TmpVec = createMinMaxOp(Builder, MinMaxKind, TmpVec, Shuf);
7915517e702SDimitry Andric     }
7925517e702SDimitry Andric     if (!RedOps.empty())
7935517e702SDimitry Andric       propagateIRFlags(TmpVec, RedOps);
7945517e702SDimitry Andric   }
7955517e702SDimitry Andric   // The result is in the first element of the vector.
7965517e702SDimitry Andric   return Builder.CreateExtractElement(TmpVec, Builder.getInt32(0));
7975517e702SDimitry Andric }
7985517e702SDimitry Andric 
7995517e702SDimitry Andric /// Create a simple vector reduction specified by an opcode and some
8005517e702SDimitry Andric /// flags (if generating min/max reductions).
createSimpleTargetReduction(IRBuilder<> & Builder,const TargetTransformInfo * TTI,unsigned Opcode,Value * Src,TargetTransformInfo::ReductionFlags Flags,ArrayRef<Value * > RedOps)8015517e702SDimitry Andric Value *llvm::createSimpleTargetReduction(
8025517e702SDimitry Andric     IRBuilder<> &Builder, const TargetTransformInfo *TTI, unsigned Opcode,
8035517e702SDimitry Andric     Value *Src, TargetTransformInfo::ReductionFlags Flags,
8045517e702SDimitry Andric     ArrayRef<Value *> RedOps) {
8055517e702SDimitry Andric   assert(isa<VectorType>(Src->getType()) && "Type must be a vector");
8065517e702SDimitry Andric 
8075517e702SDimitry Andric   Value *ScalarUdf = UndefValue::get(Src->getType()->getVectorElementType());
8085517e702SDimitry Andric   std::function<Value *()> BuildFunc;
8095517e702SDimitry Andric   using RD = RecurrenceDescriptor;
8105517e702SDimitry Andric   RD::MinMaxRecurrenceKind MinMaxKind = RD::MRK_Invalid;
8115517e702SDimitry Andric   // TODO: Support creating ordered reductions.
8122cab237bSDimitry Andric   FastMathFlags FMFFast;
8132cab237bSDimitry Andric   FMFFast.setFast();
8145517e702SDimitry Andric 
8155517e702SDimitry Andric   switch (Opcode) {
8165517e702SDimitry Andric   case Instruction::Add:
8175517e702SDimitry Andric     BuildFunc = [&]() { return Builder.CreateAddReduce(Src); };
8185517e702SDimitry Andric     break;
8195517e702SDimitry Andric   case Instruction::Mul:
8205517e702SDimitry Andric     BuildFunc = [&]() { return Builder.CreateMulReduce(Src); };
8215517e702SDimitry Andric     break;
8225517e702SDimitry Andric   case Instruction::And:
8235517e702SDimitry Andric     BuildFunc = [&]() { return Builder.CreateAndReduce(Src); };
8245517e702SDimitry Andric     break;
8255517e702SDimitry Andric   case Instruction::Or:
8265517e702SDimitry Andric     BuildFunc = [&]() { return Builder.CreateOrReduce(Src); };
8275517e702SDimitry Andric     break;
8285517e702SDimitry Andric   case Instruction::Xor:
8295517e702SDimitry Andric     BuildFunc = [&]() { return Builder.CreateXorReduce(Src); };
8305517e702SDimitry Andric     break;
8315517e702SDimitry Andric   case Instruction::FAdd:
8325517e702SDimitry Andric     BuildFunc = [&]() {
8335517e702SDimitry Andric       auto Rdx = Builder.CreateFAddReduce(ScalarUdf, Src);
8342cab237bSDimitry Andric       cast<CallInst>(Rdx)->setFastMathFlags(FMFFast);
8355517e702SDimitry Andric       return Rdx;
8365517e702SDimitry Andric     };
8375517e702SDimitry Andric     break;
8385517e702SDimitry Andric   case Instruction::FMul:
8395517e702SDimitry Andric     BuildFunc = [&]() {
8405517e702SDimitry Andric       auto Rdx = Builder.CreateFMulReduce(ScalarUdf, Src);
8412cab237bSDimitry Andric       cast<CallInst>(Rdx)->setFastMathFlags(FMFFast);
8425517e702SDimitry Andric       return Rdx;
8435517e702SDimitry Andric     };
8445517e702SDimitry Andric     break;
8455517e702SDimitry Andric   case Instruction::ICmp:
8465517e702SDimitry Andric     if (Flags.IsMaxOp) {
8475517e702SDimitry Andric       MinMaxKind = Flags.IsSigned ? RD::MRK_SIntMax : RD::MRK_UIntMax;
8485517e702SDimitry Andric       BuildFunc = [&]() {
8495517e702SDimitry Andric         return Builder.CreateIntMaxReduce(Src, Flags.IsSigned);
8505517e702SDimitry Andric       };
8515517e702SDimitry Andric     } else {
8525517e702SDimitry Andric       MinMaxKind = Flags.IsSigned ? RD::MRK_SIntMin : RD::MRK_UIntMin;
8535517e702SDimitry Andric       BuildFunc = [&]() {
8545517e702SDimitry Andric         return Builder.CreateIntMinReduce(Src, Flags.IsSigned);
8555517e702SDimitry Andric       };
8565517e702SDimitry Andric     }
8575517e702SDimitry Andric     break;
8585517e702SDimitry Andric   case Instruction::FCmp:
8595517e702SDimitry Andric     if (Flags.IsMaxOp) {
8605517e702SDimitry Andric       MinMaxKind = RD::MRK_FloatMax;
8615517e702SDimitry Andric       BuildFunc = [&]() { return Builder.CreateFPMaxReduce(Src, Flags.NoNaN); };
8625517e702SDimitry Andric     } else {
8635517e702SDimitry Andric       MinMaxKind = RD::MRK_FloatMin;
8645517e702SDimitry Andric       BuildFunc = [&]() { return Builder.CreateFPMinReduce(Src, Flags.NoNaN); };
8655517e702SDimitry Andric     }
8665517e702SDimitry Andric     break;
8675517e702SDimitry Andric   default:
8685517e702SDimitry Andric     llvm_unreachable("Unhandled opcode");
8695517e702SDimitry Andric     break;
8705517e702SDimitry Andric   }
8715517e702SDimitry Andric   if (TTI->useReductionIntrinsic(Opcode, Src->getType(), Flags))
8725517e702SDimitry Andric     return BuildFunc();
8735517e702SDimitry Andric   return getShuffleReduction(Builder, Src, Opcode, MinMaxKind, RedOps);
8745517e702SDimitry Andric }
8755517e702SDimitry Andric 
8765517e702SDimitry Andric /// Create a vector reduction using a given recurrence descriptor.
createTargetReduction(IRBuilder<> & B,const TargetTransformInfo * TTI,RecurrenceDescriptor & Desc,Value * Src,bool NoNaN)8772cab237bSDimitry Andric Value *llvm::createTargetReduction(IRBuilder<> &B,
8785517e702SDimitry Andric                                    const TargetTransformInfo *TTI,
8795517e702SDimitry Andric                                    RecurrenceDescriptor &Desc, Value *Src,
8805517e702SDimitry Andric                                    bool NoNaN) {
8815517e702SDimitry Andric   // TODO: Support in-order reductions based on the recurrence descriptor.
8822cab237bSDimitry Andric   using RD = RecurrenceDescriptor;
8832cab237bSDimitry Andric   RD::RecurrenceKind RecKind = Desc.getRecurrenceKind();
8845517e702SDimitry Andric   TargetTransformInfo::ReductionFlags Flags;
8855517e702SDimitry Andric   Flags.NoNaN = NoNaN;
8865517e702SDimitry Andric   switch (RecKind) {
8872cab237bSDimitry Andric   case RD::RK_FloatAdd:
8882cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::FAdd, Src, Flags);
8892cab237bSDimitry Andric   case RD::RK_FloatMult:
8902cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::FMul, Src, Flags);
8912cab237bSDimitry Andric   case RD::RK_IntegerAdd:
8922cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::Add, Src, Flags);
8932cab237bSDimitry Andric   case RD::RK_IntegerMult:
8942cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::Mul, Src, Flags);
8952cab237bSDimitry Andric   case RD::RK_IntegerAnd:
8962cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::And, Src, Flags);
8972cab237bSDimitry Andric   case RD::RK_IntegerOr:
8982cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::Or, Src, Flags);
8992cab237bSDimitry Andric   case RD::RK_IntegerXor:
9002cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::Xor, Src, Flags);
9012cab237bSDimitry Andric   case RD::RK_IntegerMinMax: {
9022cab237bSDimitry Andric     RD::MinMaxRecurrenceKind MMKind = Desc.getMinMaxRecurrenceKind();
9032cab237bSDimitry Andric     Flags.IsMaxOp = (MMKind == RD::MRK_SIntMax || MMKind == RD::MRK_UIntMax);
9042cab237bSDimitry Andric     Flags.IsSigned = (MMKind == RD::MRK_SIntMax || MMKind == RD::MRK_SIntMin);
9052cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::ICmp, Src, Flags);
9065517e702SDimitry Andric   }
9072cab237bSDimitry Andric   case RD::RK_FloatMinMax: {
9082cab237bSDimitry Andric     Flags.IsMaxOp = Desc.getMinMaxRecurrenceKind() == RD::MRK_FloatMax;
9092cab237bSDimitry Andric     return createSimpleTargetReduction(B, TTI, Instruction::FCmp, Src, Flags);
9105517e702SDimitry Andric   }
9115517e702SDimitry Andric   default:
9125517e702SDimitry Andric     llvm_unreachable("Unhandled RecKind");
9135517e702SDimitry Andric   }
9145517e702SDimitry Andric }
9155517e702SDimitry Andric 
propagateIRFlags(Value * I,ArrayRef<Value * > VL,Value * OpValue)91637cd60a3SDimitry Andric void llvm::propagateIRFlags(Value *I, ArrayRef<Value *> VL, Value *OpValue) {
91737cd60a3SDimitry Andric   auto *VecOp = dyn_cast<Instruction>(I);
91837cd60a3SDimitry Andric   if (!VecOp)
91937cd60a3SDimitry Andric     return;
92037cd60a3SDimitry Andric   auto *Intersection = (OpValue == nullptr) ? dyn_cast<Instruction>(VL[0])
92137cd60a3SDimitry Andric                                             : dyn_cast<Instruction>(OpValue);
92237cd60a3SDimitry Andric   if (!Intersection)
92337cd60a3SDimitry Andric     return;
92437cd60a3SDimitry Andric   const unsigned Opcode = Intersection->getOpcode();
92537cd60a3SDimitry Andric   VecOp->copyIRFlags(Intersection);
92637cd60a3SDimitry Andric   for (auto *V : VL) {
92737cd60a3SDimitry Andric     auto *Instr = dyn_cast<Instruction>(V);
92837cd60a3SDimitry Andric     if (!Instr)
92937cd60a3SDimitry Andric       continue;
93037cd60a3SDimitry Andric     if (OpValue == nullptr || Opcode == Instr->getOpcode())
93137cd60a3SDimitry Andric       VecOp->andIRFlags(V);
9325517e702SDimitry Andric   }
9335517e702SDimitry Andric }
934*b5893f02SDimitry Andric 
isKnownNegativeInLoop(const SCEV * S,const Loop * L,ScalarEvolution & SE)935*b5893f02SDimitry Andric bool llvm::isKnownNegativeInLoop(const SCEV *S, const Loop *L,
936*b5893f02SDimitry Andric                                  ScalarEvolution &SE) {
937*b5893f02SDimitry Andric   const SCEV *Zero = SE.getZero(S->getType());
938*b5893f02SDimitry Andric   return SE.isAvailableAtLoopEntry(S, L) &&
939*b5893f02SDimitry Andric          SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SLT, S, Zero);
940*b5893f02SDimitry Andric }
941*b5893f02SDimitry Andric 
isKnownNonNegativeInLoop(const SCEV * S,const Loop * L,ScalarEvolution & SE)942*b5893f02SDimitry Andric bool llvm::isKnownNonNegativeInLoop(const SCEV *S, const Loop *L,
943*b5893f02SDimitry Andric                                     ScalarEvolution &SE) {
944*b5893f02SDimitry Andric   const SCEV *Zero = SE.getZero(S->getType());
945*b5893f02SDimitry Andric   return SE.isAvailableAtLoopEntry(S, L) &&
946*b5893f02SDimitry Andric          SE.isLoopEntryGuardedByCond(L, ICmpInst::ICMP_SGE, S, Zero);
947*b5893f02SDimitry Andric }
948*b5893f02SDimitry Andric 
cannotBeMinInLoop(const SCEV * S,const Loop * L,ScalarEvolution & SE,bool Signed)949*b5893f02SDimitry Andric bool llvm::cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
950*b5893f02SDimitry Andric                              bool Signed) {
951*b5893f02SDimitry Andric   unsigned BitWidth = cast<IntegerType>(S->getType())->getBitWidth();
952*b5893f02SDimitry Andric   APInt Min = Signed ? APInt::getSignedMinValue(BitWidth) :
953*b5893f02SDimitry Andric     APInt::getMinValue(BitWidth);
954*b5893f02SDimitry Andric   auto Predicate = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
955*b5893f02SDimitry Andric   return SE.isAvailableAtLoopEntry(S, L) &&
956*b5893f02SDimitry Andric          SE.isLoopEntryGuardedByCond(L, Predicate, S,
957*b5893f02SDimitry Andric                                      SE.getConstant(Min));
958*b5893f02SDimitry Andric }
959*b5893f02SDimitry Andric 
cannotBeMaxInLoop(const SCEV * S,const Loop * L,ScalarEvolution & SE,bool Signed)960*b5893f02SDimitry Andric bool llvm::cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
961*b5893f02SDimitry Andric                              bool Signed) {
962*b5893f02SDimitry Andric   unsigned BitWidth = cast<IntegerType>(S->getType())->getBitWidth();
963*b5893f02SDimitry Andric   APInt Max = Signed ? APInt::getSignedMaxValue(BitWidth) :
964*b5893f02SDimitry Andric     APInt::getMaxValue(BitWidth);
965*b5893f02SDimitry Andric   auto Predicate = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
966*b5893f02SDimitry Andric   return SE.isAvailableAtLoopEntry(S, L) &&
967*b5893f02SDimitry Andric          SE.isLoopEntryGuardedByCond(L, Predicate, S,
968*b5893f02SDimitry Andric                                      SE.getConstant(Max));
969*b5893f02SDimitry Andric }
970