aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/IVDescriptors.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Analysis/IVDescriptors.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
downloadsrc-e3b557809604d036af6e00c60f012c2025b59a5e.tar.gz
src-e3b557809604d036af6e00c60f012c2025b59a5e.zip
Diffstat (limited to 'llvm/lib/Analysis/IVDescriptors.cpp')
-rw-r--r--llvm/lib/Analysis/IVDescriptors.cpp42
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;