|
15 | 15 | #include "llvm/Analysis/LoopInfo.h" |
16 | 16 | #include "llvm/Analysis/ScalarEvolution.h" |
17 | 17 | #include "llvm/Analysis/ScalarEvolutionExpressions.h" |
| 18 | +#include "llvm/Analysis/ScalarEvolutionPatternMatch.h" |
18 | 19 | #include "llvm/Analysis/ValueTracking.h" |
19 | 20 | #include "llvm/IR/Dominators.h" |
20 | 21 | #include "llvm/IR/Instructions.h" |
|
25 | 26 |
|
26 | 27 | using namespace llvm; |
27 | 28 | using namespace llvm::PatternMatch; |
| 29 | +using namespace llvm::SCEVPatternMatch; |
28 | 30 |
|
29 | 31 | #define DEBUG_TYPE "iv-descriptors" |
30 | 32 |
|
@@ -721,11 +723,12 @@ RecurrenceDescriptor::isFindIVPattern(RecurKind Kind, Loop *TheLoop, |
721 | 723 | if (!SE.isSCEVable(Ty)) |
722 | 724 | return std::nullopt; |
723 | 725 |
|
724 | | - auto *AR = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(V)); |
725 | | - if (!AR || AR->getLoop() != TheLoop) |
| 726 | + auto *AR = SE.getSCEV(V); |
| 727 | + const SCEV *Step; |
| 728 | + if (!match(AR, m_scev_AffineAddRec(m_SCEV(), m_SCEV(Step), |
| 729 | + m_SpecificLoop(TheLoop)))) |
726 | 730 | return std::nullopt; |
727 | 731 |
|
728 | | - const SCEV *Step = AR->getStepRecurrence(SE); |
729 | 732 | if ((isFindFirstIVRecurrenceKind(Kind) && !SE.isKnownNegative(Step)) || |
730 | 733 | (isFindLastIVRecurrenceKind(Kind) && !SE.isKnownPositive(Step))) |
731 | 734 | return std::nullopt; |
@@ -1616,41 +1619,31 @@ bool InductionDescriptor::isInductionPHI( |
1616 | 1619 |
|
1617 | 1620 | // Check that the PHI is consecutive. |
1618 | 1621 | const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi); |
1619 | | - const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev); |
| 1622 | + const SCEV *Step; |
1620 | 1623 |
|
1621 | | - if (!AR) { |
1622 | | - LLVM_DEBUG(dbgs() << "LV: PHI is not a poly recurrence.\n"); |
1623 | | - return false; |
1624 | | - } |
1625 | | - |
1626 | | - if (AR->getLoop() != TheLoop) { |
1627 | | - // FIXME: We should treat this as a uniform. Unfortunately, we |
1628 | | - // don't currently know how to handled uniform PHIs. |
| 1624 | + // FIXME: We are currently matching the specific loop TheLoop; if it doesn't |
| 1625 | + // match, we should treat it as a uniform. Unfortunately, we don't currently |
| 1626 | + // know how to handled uniform PHIs. |
| 1627 | + if (!match(PhiScev, m_scev_AffineAddRec(m_SCEV(), m_SCEV(Step), |
| 1628 | + m_SpecificLoop(TheLoop)))) { |
1629 | 1629 | LLVM_DEBUG( |
1630 | | - dbgs() << "LV: PHI is a recurrence with respect to an outer loop.\n"); |
| 1630 | + dbgs() << "LV: PHI is not a poly recurrence for requested loop.\n"); |
1631 | 1631 | return false; |
1632 | 1632 | } |
1633 | 1633 |
|
1634 | 1634 | // This function assumes that InductionPhi is called only on Phi nodes |
1635 | 1635 | // present inside loop headers. Check for the same, and throw an assert if |
1636 | 1636 | // the current Phi is not present inside the loop header. |
1637 | | - assert(Phi->getParent() == AR->getLoop()->getHeader() |
1638 | | - && "Invalid Phi node, not present in loop header"); |
| 1637 | + assert(Phi->getParent() == TheLoop->getHeader() && |
| 1638 | + "Invalid Phi node, not present in loop header"); |
1639 | 1639 |
|
1640 | 1640 | Value *StartValue = |
1641 | | - Phi->getIncomingValueForBlock(AR->getLoop()->getLoopPreheader()); |
| 1641 | + Phi->getIncomingValueForBlock(TheLoop->getLoopPreheader()); |
1642 | 1642 |
|
1643 | | - BasicBlock *Latch = AR->getLoop()->getLoopLatch(); |
| 1643 | + BasicBlock *Latch = TheLoop->getLoopLatch(); |
1644 | 1644 | if (!Latch) |
1645 | 1645 | return false; |
1646 | 1646 |
|
1647 | | - const SCEV *Step = AR->getStepRecurrence(*SE); |
1648 | | - // Calculate the pointer stride and check if it is consecutive. |
1649 | | - // The stride may be a constant or a loop invariant integer value. |
1650 | | - const SCEVConstant *ConstStep = dyn_cast<SCEVConstant>(Step); |
1651 | | - if (!ConstStep && !SE->isLoopInvariant(Step, TheLoop)) |
1652 | | - return false; |
1653 | | - |
1654 | 1647 | if (PhiTy->isIntegerTy()) { |
1655 | 1648 | BinaryOperator *BOp = |
1656 | 1649 | dyn_cast<BinaryOperator>(Phi->getIncomingValueForBlock(Latch)); |
|
0 commit comments