[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Feb 6 23:28:04 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.420 -> 1.421
---
Log message:
Make MaskedValueIsZero take a uint64_t instead of a ConstantIntegral as a
mask. This allows the code to be simpler and more efficient.
Also, generalize some of the cases in MVIZ a bit, making it slightly more aggressive.
---
Diffs of the changes: (+58 -69)
InstructionCombining.cpp | 127 +++++++++++++++++++++--------------------------
1 files changed, 58 insertions(+), 69 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.420 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.421
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.420 Tue Feb 7 01:00:41 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 7 01:27:52 2006
@@ -406,20 +406,19 @@
}
/// 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,
- unsigned Depth = 0) {
+/// this predicate to simplify operations downstream. Mask is known to be zero
+/// for bits that V cannot have.
+static bool MaskedValueIsZero(Value *V, uint64_t 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
+ // it to be an explicit zero. If we don't change it to zero, other code could
// optimized based on the contradictory assumption that it is non-zero.
// Because instcombine aggressively folds operations with undef args anyway,
// this won't lose us code quality.
- if (Mask->isNullValue())
+ if (Mask == 0)
return true;
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V))
- return ConstantExpr::getAnd(CI, Mask)->isNullValue();
+ return (CI->getRawValue() & Mask) == 0;
if (Depth == 6) return false; // Limit search depth.
@@ -427,12 +426,9 @@
switch (I->getOpcode()) {
case Instruction::And:
// (X & C1) & C2 == 0 iff C1 & C2 == 0.
- if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1))) {
- ConstantIntegral *C1C2 =
- cast<ConstantIntegral>(ConstantExpr::getAnd(CI, Mask));
- if (MaskedValueIsZero(I->getOperand(0), C1C2, Depth+1))
- return true;
- }
+ if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1)))
+ return MaskedValueIsZero(I->getOperand(0), CI->getRawValue() & Mask,
+ Depth+1);
// If either the LHS or the RHS are MaskedValueIsZero, the result is zero.
return MaskedValueIsZero(I->getOperand(1), Mask, Depth+1) ||
MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
@@ -448,41 +444,34 @@
case Instruction::Cast: {
const Type *SrcTy = I->getOperand(0)->getType();
if (SrcTy == Type::BoolTy)
- return (Mask->getRawValue() & 1) == 0;
+ return (Mask & 1) == 0;
+ if (!SrcTy->isInteger()) return false;
- if (SrcTy->isInteger()) {
- // (cast <ty> X to int) & C2 == 0 iff <ty> could not have contained C2.
- if (SrcTy->isUnsigned() && // Only handle zero ext.
- ConstantExpr::getCast(Mask, SrcTy)->isNullValue())
- return true;
-
- // If this is a noop cast, recurse.
- if ((SrcTy->isSigned() && SrcTy->getUnsignedVersion() == I->getType())||
- SrcTy->getSignedVersion() == I->getType()) {
- Constant *NewMask =
- ConstantExpr::getCast(Mask, I->getOperand(0)->getType());
- return MaskedValueIsZero(I->getOperand(0),
- cast<ConstantIntegral>(NewMask), Depth+1);
- }
- }
+ // (cast <ty> X to int) & C2 == 0 iff <ty> could not have contained C2.
+ if (SrcTy->isUnsigned()) // Only handle zero ext.
+ return MaskedValueIsZero(I->getOperand(0),
+ Mask & SrcTy->getIntegralTypeMask(), Depth+1);
+
+ // If this is a noop or trunc cast, recurse.
+ if (SrcTy->getPrimitiveSizeInBits() >=
+ I->getType()->getPrimitiveSizeInBits())
+ return MaskedValueIsZero(I->getOperand(0),
+ Mask & SrcTy->getIntegralTypeMask(), Depth+1);
break;
}
case Instruction::Shl:
// (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)),
+ return MaskedValueIsZero(I->getOperand(0), Mask >> SA->getValue(),
Depth+1);
break;
case Instruction::Shr:
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
if (I->getType()->isUnsigned()) {
- Constant *C1 = ConstantIntegral::getAllOnesValue(I->getType());
- C1 = ConstantExpr::getShr(C1, SA);
- C1 = ConstantExpr::getAnd(C1, Mask);
- if (C1->isNullValue())
- return true;
+ Mask <<= SA->getValue();
+ Mask &= I->getType()->getIntegralTypeMask();
+ return MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
}
break;
}
@@ -877,10 +866,9 @@
}
if (Found) {
// This is a sign extend if the top bits are known zero.
- Constant *Mask = ConstantInt::getAllOnesValue(XorLHS->getType());
- Mask = ConstantExpr::getShl(Mask,
- ConstantInt::get(Type::UByteTy, 64-(TySizeBits-Size)));
- if (!MaskedValueIsZero(XorLHS, cast<ConstantInt>(Mask)))
+ uint64_t Mask = XorLHS->getType()->getIntegralTypeMask();
+ Mask <<= 64-(TySizeBits-Size);
+ if (!MaskedValueIsZero(XorLHS, Mask))
Size = 0; // Not a sign ext, but can't be any others either.
goto FoundSExt;
}
@@ -1375,10 +1363,10 @@
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
if (I.getType()->isSigned()) {
- // If the top bits of both operands are zero (i.e. we can prove they are
+ // If the sign bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a udiv.
- ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
- if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
+ uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
+ if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
const Type *NTy = Op0->getType()->getUnsignedVersion();
Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
InsertNewInstBefore(LHS, I);
@@ -1430,8 +1418,8 @@
// If the top bits of both operands are zero (i.e. we can prove they are
// unsigned inputs), turn this into a urem.
- ConstantIntegral *MaskV = ConstantSInt::getMinValue(I.getType());
- if (MaskedValueIsZero(Op1, MaskV) && MaskedValueIsZero(Op0, MaskV)) {
+ uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1);
+ if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) {
const Type *NTy = Op0->getType()->getUnsignedVersion();
Instruction *LHS = new CastInst(Op0, NTy, Op0->getName());
InsertNewInstBefore(LHS, I);
@@ -1888,11 +1876,9 @@
// is all N is, ignore it.
unsigned MB, ME;
if (isRunOfOnes(Mask, MB, ME)) { // begin/end bit of run, inclusive
- Constant *Mask = ConstantInt::getAllOnesValue(RHS->getType());
- Mask = ConstantExpr::getUShr(Mask,
- ConstantInt::get(Type::UByteTy,
- (64-MB+1)));
- if (MaskedValueIsZero(RHS, cast<ConstantIntegral>(Mask)))
+ uint64_t Mask = RHS->getType()->getIntegralTypeMask();
+ Mask >>= 64-MB+1;
+ if (MaskedValueIsZero(RHS, Mask))
break;
}
}
@@ -1939,13 +1925,13 @@
return BinaryOperator::createAnd(X, ConstantExpr::getAnd(C1, AndRHS));
}
- if (MaskedValueIsZero(Op0, AndRHS)) // LHS & RHS == 0
+ if (MaskedValueIsZero(Op0, AndRHS->getZExtValue())) // LHS & RHS == 0
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// If the mask is not masking out any bits, there is no reason to do the
// and in the first place.
- ConstantIntegral *NotAndRHS =
- cast<ConstantIntegral>(ConstantExpr::getNot(AndRHS));
+ uint64_t NotAndRHS = // ~ANDRHS
+ AndRHS->getZExtValue()^Op0->getType()->getIntegralTypeMask();
if (MaskedValueIsZero(Op0, NotAndRHS))
return ReplaceInstUsesWith(I, Op0);
@@ -1964,9 +1950,9 @@
case Instruction::Or:
// (X ^ V) & C2 --> (X & C2) iff (V & C2) == 0
// (X | V) & C2 --> (X & C2) iff (V & C2) == 0
- if (MaskedValueIsZero(Op0LHS, AndRHS))
+ if (MaskedValueIsZero(Op0LHS, AndRHS->getZExtValue()))
return BinaryOperator::createAnd(Op0RHS, AndRHS);
- if (MaskedValueIsZero(Op0RHS, AndRHS))
+ if (MaskedValueIsZero(Op0RHS, AndRHS->getZExtValue()))
return BinaryOperator::createAnd(Op0LHS, AndRHS);
// If the mask is only needed on one incoming arm, push it up.
@@ -1979,7 +1965,7 @@
return BinaryOperator::create(
cast<BinaryOperator>(Op0I)->getOpcode(), Op0LHS, NewRHS);
}
- if (!isa<Constant>(NotAndRHS) &&
+ if (!isa<Constant>(Op0RHS) &&
MaskedValueIsZero(Op0RHS, NotAndRHS)) {
// Not masking anything out for the RHS, move to LHS.
Instruction *NewLHS = BinaryOperator::createAnd(Op0LHS, AndRHS,
@@ -1993,8 +1979,8 @@
break;
case Instruction::And:
// (X & V) & C2 --> 0 iff (V & C2) == 0
- if (MaskedValueIsZero(Op0LHS, AndRHS) ||
- MaskedValueIsZero(Op0RHS, AndRHS))
+ if (MaskedValueIsZero(Op0LHS, AndRHS->getZExtValue()) ||
+ MaskedValueIsZero(Op0RHS, AndRHS->getZExtValue()))
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
break;
case Instruction::Add:
@@ -2239,8 +2225,8 @@
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
// If X is known to only contain bits that already exist in RHS, just
// replace this instruction with RHS directly.
- if (MaskedValueIsZero(Op0,
- cast<ConstantIntegral>(ConstantExpr::getNot(RHS))))
+ if (MaskedValueIsZero(Op0,
+ RHS->getZExtValue()^RHS->getType()->getIntegralTypeMask()))
return ReplaceInstUsesWith(I, RHS);
ConstantInt *C1 = 0; Value *X = 0;
@@ -2282,7 +2268,7 @@
// (X^C)|Y -> (X|Y)^C iff Y&C == 0
if (Op0->hasOneUse() && match(Op0, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
- MaskedValueIsZero(Op1, C1)) {
+ MaskedValueIsZero(Op1, C1->getZExtValue())) {
Instruction *NOr = BinaryOperator::createOr(A, Op1, Op0->getName());
Op0->setName("");
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
@@ -2290,7 +2276,7 @@
// Y|(X^C) -> (X|Y)^C iff Y&C == 0
if (Op1->hasOneUse() && match(Op1, m_Xor(m_Value(A), m_ConstantInt(C1))) &&
- MaskedValueIsZero(Op0, C1)) {
+ MaskedValueIsZero(Op0, C1->getZExtValue())) {
Instruction *NOr = BinaryOperator::createOr(A, Op0, Op1->getName());
Op0->setName("");
return BinaryOperator::createXor(InsertNewInstBefore(NOr, I), C1);
@@ -2312,18 +2298,18 @@
if ((C2->getRawValue() & (C2->getRawValue()+1)) == 0 && // C2 == 0+1+
match(A, m_Add(m_Value(V1), m_Value(V2)))) {
// Add commutes, try both ways.
- if (V1 == B && MaskedValueIsZero(V2, C2))
+ if (V1 == B && MaskedValueIsZero(V2, C2->getZExtValue()))
return ReplaceInstUsesWith(I, A);
- if (V2 == B && MaskedValueIsZero(V1, C2))
+ if (V2 == B && MaskedValueIsZero(V1, C2->getZExtValue()))
return ReplaceInstUsesWith(I, A);
}
// Or commutes, try both ways.
if ((C1->getRawValue() & (C1->getRawValue()+1)) == 0 &&
match(B, m_Add(m_Value(V1), m_Value(V2)))) {
// Add commutes, try both ways.
- if (V1 == A && MaskedValueIsZero(V2, C1))
+ if (V1 == A && MaskedValueIsZero(V2, C1->getZExtValue()))
return ReplaceInstUsesWith(I, B);
- if (V2 == A && MaskedValueIsZero(V1, C1))
+ if (V2 == A && MaskedValueIsZero(V1, C1->getZExtValue()))
return ReplaceInstUsesWith(I, B);
}
}
@@ -3599,7 +3585,8 @@
// See if we can turn a signed shr into an unsigned shr.
if (!isLeftShift && I.getType()->isSigned()) {
- if (MaskedValueIsZero(Op0, ConstantInt::getMinValue(I.getType()))) {
+ if (MaskedValueIsZero(Op0,
+ 1ULL << (I.getType()->getPrimitiveSizeInBits()-1))) {
Value *V = InsertCastBefore(Op0, I.getType()->getUnsignedVersion(), I);
V = InsertNewInstBefore(new ShiftInst(Instruction::Shr, V, Op1,
I.getName()), I);
@@ -4373,7 +4360,8 @@
Constant *Not1 =
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
// cast (X != 0) to int --> X if X&~1 == 0
- if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
+ if (MaskedValueIsZero(Op0,
+ cast<ConstantIntegral>(Not1)->getZExtValue())) {
if (CI.getType() == Op0->getType())
return ReplaceInstUsesWith(CI, Op0);
else
@@ -4415,7 +4403,8 @@
if (Op1C->getRawValue() == 1) {
Constant *Not1 =
ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
- if (MaskedValueIsZero(Op0, cast<ConstantIntegral>(Not1))) {
+ if (MaskedValueIsZero(Op0,
+ cast<ConstantIntegral>(Not1)->getZExtValue())) {
if (CI.getType() == Op0->getType())
return ReplaceInstUsesWith(CI, Op0);
else
More information about the llvm-commits
mailing list