diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Analysis/IVDescriptors.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) | |
download | src-e3b557809604d036af6e00c60f012c2025b59a5e.tar.gz src-e3b557809604d036af6e00c60f012c2025b59a5e.zip |
Diffstat (limited to 'llvm/lib/Analysis/IVDescriptors.cpp')
-rw-r--r-- | llvm/lib/Analysis/IVDescriptors.cpp | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp index a51e974003f6..950541ace9d7 100644 --- a/llvm/lib/Analysis/IVDescriptors.cpp +++ b/llvm/lib/Analysis/IVDescriptors.cpp @@ -789,7 +789,7 @@ RecurrenceDescriptor::isRecurrenceInstr(Loop *L, PHINode *OrigPhi, case Instruction::Select: if (Kind == RecurKind::FAdd || Kind == RecurKind::FMul) return isConditionalRdxPattern(Kind, I); - LLVM_FALLTHROUGH; + [[fallthrough]]; case Instruction::FCmp: case Instruction::ICmp: case Instruction::Call: @@ -921,7 +921,7 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, return false; } -bool RecurrenceDescriptor::isFirstOrderRecurrence( +bool RecurrenceDescriptor::isFixedOrderRecurrence( PHINode *Phi, Loop *TheLoop, MapVector<Instruction *, Instruction *> &SinkAfter, DominatorTree *DT) { @@ -943,8 +943,22 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence( return false; // Get the previous value. The previous value comes from the latch edge while - // the initial value comes form the preheader edge. + // the initial value comes from the preheader edge. auto *Previous = dyn_cast<Instruction>(Phi->getIncomingValueForBlock(Latch)); + + // If Previous is a phi in the header, go through incoming values from the + // latch until we find a non-phi value. Use this as the new Previous, all uses + // in the header will be dominated by the original phi, but need to be moved + // after the non-phi previous value. + SmallPtrSet<PHINode *, 4> SeenPhis; + while (auto *PrevPhi = dyn_cast_or_null<PHINode>(Previous)) { + if (PrevPhi->getParent() != Phi->getParent()) + return false; + if (!SeenPhis.insert(PrevPhi).second) + return false; + Previous = dyn_cast<Instruction>(PrevPhi->getIncomingValueForBlock(Latch)); + } + if (!Previous || !TheLoop->contains(Previous) || isa<PHINode>(Previous) || SinkAfter.count(Previous)) // Cannot rely on dominance due to motion. return false; @@ -986,7 +1000,7 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence( return false; // Avoid sinking an instruction multiple times (if multiple operands are - // first order recurrences) by sinking once - after the latest 'previous' + // fixed order recurrences) by sinking once - after the latest 'previous' // instruction. auto It = SinkAfter.find(SinkCandidate); if (It != SinkAfter.end()) { @@ -1011,6 +1025,16 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence( // Previous. Nothing left to do. if (DT->dominates(Previous, OtherPrev) || Previous == OtherPrev) return true; + + // If there are other instructions to be sunk after SinkCandidate, remove + // and re-insert SinkCandidate can break those instructions. Bail out for + // simplicity. + if (any_of(SinkAfter, + [SinkCandidate](const std::pair<Instruction *, Instruction *> &P) { + return P.second == SinkCandidate; + })) + return false; + // Otherwise, Previous comes after OtherPrev and SinkCandidate needs to be // re-sunk to Previous, instead of sinking to OtherPrev. Remove // SinkCandidate from SinkAfter to ensure it's insert position is updated. @@ -1087,9 +1111,13 @@ Value *RecurrenceDescriptor::getRecurrenceIdentity(RecurKind K, Type *Tp, return ConstantInt::get(Tp, APInt::getSignedMinValue(Tp->getIntegerBitWidth())); case RecurKind::FMin: - return ConstantFP::getInfinity(Tp, true); + assert((FMF.noNaNs() && FMF.noSignedZeros()) && + "nnan, nsz is expected to be set for FP min reduction."); + return ConstantFP::getInfinity(Tp, false /*Negative*/); case RecurKind::FMax: - return ConstantFP::getInfinity(Tp, false); + assert((FMF.noNaNs() && FMF.noSignedZeros()) && + "nnan, nsz is expected to be set for FP max reduction."); + return ConstantFP::getInfinity(Tp, true /*Negative*/); case RecurKind::SelectICmp: case RecurKind::SelectFCmp: return getRecurrenceStartValue(); @@ -1557,7 +1585,7 @@ bool InductionDescriptor::isInductionPHI( if (TySize.isZero() || TySize.isScalable()) return false; - int64_t Size = static_cast<int64_t>(TySize.getFixedSize()); + int64_t Size = static_cast<int64_t>(TySize.getFixedValue()); int64_t CVSize = CV->getSExtValue(); if (CVSize % Size) return false; |