summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/LoopUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUtils.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index b5e6418ad32..444bc16e0a1 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -553,13 +553,23 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence(PHINode *Phi, Loop *TheLoop,
if (!Previous || !TheLoop->contains(Previous) || isa<PHINode>(Previous))
return false;
- // Ensure every user of the phi node is dominated by the previous value. The
- // dominance requirement ensures the loop vectorizer will not need to
- // vectorize the initial value prior to the first iteration of the loop.
for (User *U : Phi->users())
- if (auto *I = dyn_cast<Instruction>(U))
+ if (auto *I = dyn_cast<Instruction>(U)) {
+ // Ensure every user of the phi node is dominated by the previous value.
+ // The dominance requirement ensures the loop vectorizer will not need to
+ // vectorize the initial value prior to the first iteration of the loop.
if (!DT->dominates(Previous, I))
return false;
+ // When the phi node has users outside the loop, the current logic for
+ // fixFirstOrderRecurrences may generate incorrect code. Specifically, we
+ // extract the last element from the vectorized phi, which would be the
+ // update to the phi before exiting the loop. However, what we want is the
+ // previous phi value before the update (i.e. the second last update
+ // before end of the vectorized loop).
+ // See added test cases in first-order-recurrence.ll
+ if (!TheLoop->contains(I))
+ return false;
+ }
return true;
}
OpenPOWER on IntegriCloud