diff options
author | Chris Lattner <sabre@nondot.org> | 2005-10-31 18:35:52 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-10-31 18:35:52 +0000 |
commit | 76ff2c75044fc97ef1af9936c65d344ab7b7e59b (patch) | |
tree | 4572ca8513469f6a6d78651a78affebbf4d9a292 | |
parent | b5a0c0ee059db5994d4fec7ebd03c048b4fcd308 (diff) |
Limit the search depth of MaskedValueIsZero to 6 instructions, to avoid
bad cases. This fixes Markus's second testcase in PR639, and should
seal it for good.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24123 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index c4e07d7747..adafccddf0 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -389,7 +389,8 @@ static ConstantInt *SubOne(ConstantInt *C) { /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use /// this predicate to simplify operations downstream. V and Mask are known to /// be the same type. -static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { +static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask, + unsigned Depth = 0) { // Note, we cannot consider 'undef' to be "IsZero" here. The problem is that // we cannot optimize based on the assumption that it is zero without changing // to to an explicit zero. If we don't change it to zero, other code could @@ -400,6 +401,8 @@ static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { return true; if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V)) return ConstantExpr::getAnd(CI, Mask)->isNullValue(); + + if (Depth == 6) return false; // Limit search depth. if (Instruction *I = dyn_cast<Instruction>(V)) { switch (I->getOpcode()) { @@ -408,21 +411,21 @@ static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1))) { ConstantIntegral *C1C2 = cast<ConstantIntegral>(ConstantExpr::getAnd(CI, Mask)); - if (MaskedValueIsZero(I->getOperand(0), C1C2)) + if (MaskedValueIsZero(I->getOperand(0), C1C2, Depth+1)) return true; } // If either the LHS or the RHS are MaskedValueIsZero, the result is zero. - return MaskedValueIsZero(I->getOperand(1), Mask) || - MaskedValueIsZero(I->getOperand(0), Mask); + return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) || + MaskedValueIsZero(I->getOperand(0), Mask, Depth+1); case Instruction::Or: case Instruction::Xor: // If the LHS and the RHS are MaskedValueIsZero, the result is also zero. - return MaskedValueIsZero(I->getOperand(1), Mask) && - MaskedValueIsZero(I->getOperand(0), Mask); + return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) && + MaskedValueIsZero(I->getOperand(0), Mask, Depth+1); case Instruction::Select: // If the T and F values are MaskedValueIsZero, the result is also zero. - return MaskedValueIsZero(I->getOperand(2), Mask) && - MaskedValueIsZero(I->getOperand(1), Mask); + return MaskedValueIsZero(I->getOperand(2), Mask, Depth+1) && + MaskedValueIsZero(I->getOperand(1), Mask, Depth+1); case Instruction::Cast: { const Type *SrcTy = I->getOperand(0)->getType(); if (SrcTy == Type::BoolTy) @@ -440,7 +443,7 @@ static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { Constant *NewMask = ConstantExpr::getCast(Mask, I->getOperand(0)->getType()); return MaskedValueIsZero(I->getOperand(0), - cast<ConstantIntegral>(NewMask)); + cast<ConstantIntegral>(NewMask), Depth+1); } } break; @@ -449,7 +452,8 @@ static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { // (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0 if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) return MaskedValueIsZero(I->getOperand(0), - cast<ConstantIntegral>(ConstantExpr::getUShr(Mask, SA))); + cast<ConstantIntegral>(ConstantExpr::getUShr(Mask, SA)), + Depth+1); break; case Instruction::Shr: // (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0 |