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
This commit is contained in:
Chris Lattner 2010-03-05 07:18:54 +00:00
parent 25ec483cfc
commit 893075f46e
2 changed files with 34 additions and 7 deletions

View File

@ -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.

View File

@ -23,11 +23,22 @@ entry:
%3 = add nsw i32 undef, %1
%4 = add nsw i32 %3, %2
%5 = add nsw i32 %4, 4
%6 = shl i32 %0, 3 ; <i32> [#uses=1]
%6 = shl i32 %0, 3
%7 = add nsw i32 %5, %6
br label %bb4.i9
bb4.i9: ; preds = %bb3.i7, %bb1.i25.i
bb4.i9:
%8 = add nsw i32 undef, %1
ret i32 0
}
define i32 @test3(i32 %Arg, i32 %x1, i32 %x2, i32 %x3) {
%A = mul i32 %x1, %Arg
%B = mul i32 %Arg, %x2 ;; Part of add operation being factored, also used by C
%C = mul i32 %x3, %B
%D = add i32 %A, %B
%E = add i32 %D, %C
ret i32 %E
}