aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/Reassociate.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-03-05 07:18:54 +0000
committerChris Lattner <sabre@nondot.org>2010-03-05 07:18:54 +0000
commit893075f46e9d07e3fe94e2b0e0f3ff8ae4061549 (patch)
tree559032cbece8aab60e2e7f1d1f988769b2acc45d /lib/Transforms/Scalar/Reassociate.cpp
parent25ec483cfca8d3a3ba8728a4a126e04b92789069 (diff)
downloadexternal_llvm-893075f46e9d07e3fe94e2b0e0f3ff8ae4061549.zip
external_llvm-893075f46e9d07e3fe94e2b0e0f3ff8ae4061549.tar.gz
external_llvm-893075f46e9d07e3fe94e2b0e0f3ff8ae4061549.tar.bz2
fix a nice subtle reassociate bug which would only occur
in a very specific use pattern embodied in the carefully reduced testcase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97794 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/Reassociate.cpp')
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index 12827b6..5aca9cd 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -597,19 +597,35 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) {
/// FindSingleUseMultiplyFactors - If V is a single-use multiply, recursively
/// add its operands as factors, otherwise add V to the list of factors.
+///
+/// Ops is the top-level list of add operands we're trying to factor.
static void FindSingleUseMultiplyFactors(Value *V,
- SmallVectorImpl<Value*> &Factors) {
+ SmallVectorImpl<Value*> &Factors,
+ const SmallVectorImpl<ValueEntry> &Ops,
+ bool IsRoot) {
BinaryOperator *BO;
- if ((!V->hasOneUse() && !V->use_empty()) ||
+ if (!(V->hasOneUse() || V->use_empty()) || // More than one use.
!(BO = dyn_cast<BinaryOperator>(V)) ||
BO->getOpcode() != Instruction::Mul) {
Factors.push_back(V);
return;
}
+ // If this value has a single use because it is another input to the add
+ // tree we're reassociating and we dropped its use, it actually has two
+ // uses and we can't factor it.
+ if (!IsRoot) {
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ if (Ops[i].Op == V) {
+ Factors.push_back(V);
+ return;
+ }
+ }
+
+
// Otherwise, add the LHS and RHS to the list of factors.
- FindSingleUseMultiplyFactors(BO->getOperand(1), Factors);
- FindSingleUseMultiplyFactors(BO->getOperand(0), Factors);
+ FindSingleUseMultiplyFactors(BO->getOperand(1), Factors, Ops, false);
+ FindSingleUseMultiplyFactors(BO->getOperand(0), Factors, Ops, false);
}
/// OptimizeAndOrXor - Optimize a series of operands to an 'and', 'or', or 'xor'
@@ -753,7 +769,7 @@ Value *Reassociate::OptimizeAdd(Instruction *I,
// Compute all of the factors of this added value.
SmallVector<Value*, 8> Factors;
- FindSingleUseMultiplyFactors(BOp, Factors);
+ FindSingleUseMultiplyFactors(BOp, Factors, Ops, true);
assert(Factors.size() > 1 && "Bad linearize!");
// Add one to FactorOccurrences for each unique factor in this op.