aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Vectorize/LoopVectorize.cpp
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2012-12-04 22:40:22 +0000
committerNadav Rotem <nrotem@apple.com>2012-12-04 22:40:22 +0000
commite570dee4b03cca54bbf27a7f7a3299c5cdc3d087 (patch)
tree726bf66578555bf99cacb7661049782cd711e36b /lib/Transforms/Vectorize/LoopVectorize.cpp
parentf7999fe1cb2c2bdb0a4080efabb4743719ce45ca (diff)
Fix a bug in vectorization of if-converted reduction variables. If the
reduction variable is not used outside the loop then we ran into an endless loop. This change checks if we found the original PHI. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169324 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Vectorize/LoopVectorize.cpp')
-rw-r--r--lib/Transforms/Vectorize/LoopVectorize.cpp34
1 files changed, 20 insertions, 14 deletions
diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp
index 3502e9e3a6..ac62b110ad 100644
--- a/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -1985,20 +1985,20 @@ bool LoopVectorizationLegality::AddReductionVar(PHINode *Phi,
// Also, we can't have multiple block-local users.
Instruction *Iter = Phi;
while (true) {
+ // If the instruction has no users then this is a broken
+ // chain and can't be a reduction variable.
+ if (Iter->use_empty())
+ return false;
+
// Any reduction instr must be of one of the allowed kinds.
if (!isReductionInstr(Iter, Kind))
return false;
- // Did we found a user inside this block ?
+ // Did we find a user inside this block ?
bool FoundInBlockUser = false;
// Did we reach the initial PHI node ?
bool FoundStartPHI = false;
- // If the instruction has no users then this is a broken
- // chain and can't be a reduction variable.
- if (Iter->use_empty())
- return false;
-
// For each of the *users* of iter.
for (Value::use_iterator it = Iter->use_begin(), e = Iter->use_end();
it != e; ++it) {
@@ -2009,21 +2009,22 @@ bool LoopVectorizationLegality::AddReductionVar(PHINode *Phi,
continue;
}
- // We allow in-loop PHINodes which are not the original reduction PHI
- // node. If this PHI is the only user of Iter (happens in IF w/ no ELSE
- // structure) then don't skip this PHI.
- if (isa<PHINode>(U) && U->getParent() != TheLoop->getHeader() &&
- TheLoop->contains(U->getParent()) && Iter->getNumUses() > 1)
- continue;
-
// Check if we found the exit user.
BasicBlock *Parent = U->getParent();
if (!TheLoop->contains(Parent)) {
- // We must have a single exit instruction.
+ // Exit if you find multiple outside users.
if (ExitInstruction != 0)
return false;
ExitInstruction = Iter;
}
+
+ // We allow in-loop PHINodes which are not the original reduction PHI
+ // node. If this PHI is the only user of Iter (happens in IF w/ no ELSE
+ // structure) then don't skip this PHI.
+ if (isa<PHINode>(U) && U->getParent() != TheLoop->getHeader() &&
+ TheLoop->contains(U) && Iter->getNumUses() > 1)
+ continue;
+
// We can't have multiple inside users.
if (FoundInBlockUser)
return false;
@@ -2043,6 +2044,11 @@ bool LoopVectorizationLegality::AddReductionVar(PHINode *Phi,
Reductions[Phi] = RD;
return true;
}
+
+ // If we've reached the start PHI but did not find an outside user then
+ // this is dead code. Abort.
+ if (FoundStartPHI)
+ return false;
}
}