[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Tue Feb 7 00:05:34 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.421 -> 1.422
---
Log message:
Generalize MaskedValueIsZero into a ComputeMaskedNonZeroBits function, which
is just as efficient as MVIZ and is also more general.
Fix a few minor bugs introduced in recent patches
---
Diffs of the changes: (+53 -44)
InstructionCombining.cpp | 97 +++++++++++++++++++++++++----------------------
1 files changed, 53 insertions(+), 44 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.421 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.422
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.421 Tue Feb 7 01:27:52 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Feb 7 02:05:22 2006
@@ -405,65 +405,66 @@
ConstantInt::get(C->getType(), 1)));
}
-/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
-/// 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) {
+/// ComputeMaskedNonZeroBits - Determine which of the bits specified in Mask are
+/// not known to be zero and return them as a bitmask. The bits that we can
+/// guarantee to be zero are returned as zero bits in the result.
+static uint64_t ComputeMaskedNonZeroBits(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
// 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 == 0)
- return true;
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V))
- return (CI->getRawValue() & Mask) == 0;
-
- if (Depth == 6) return false; // Limit search depth.
+ return CI->getRawValue() & Mask;
+ if (Depth == 6 || Mask == 0)
+ return Mask; // Limit search depth.
if (Instruction *I = dyn_cast<Instruction>(V)) {
switch (I->getOpcode()) {
case Instruction::And:
// (X & C1) & C2 == 0 iff C1 & C2 == 0.
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1)))
- return MaskedValueIsZero(I->getOperand(0), CI->getRawValue() & Mask,
- Depth+1);
+ return ComputeMaskedNonZeroBits(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);
+ Mask = ComputeMaskedNonZeroBits(I->getOperand(1), Mask, Depth+1);
+ Mask = ComputeMaskedNonZeroBits(I->getOperand(0), Mask, Depth+1);
+ return Mask;
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, Depth+1) &&
- MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
+ // Any non-zero bits in the LHS or RHS are potentially non-zero in the
+ // result.
+ return ComputeMaskedNonZeroBits(I->getOperand(1), Mask, Depth+1) |
+ ComputeMaskedNonZeroBits(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, Depth+1) &&
- MaskedValueIsZero(I->getOperand(1), Mask, Depth+1);
+ // Any non-zero bits in the T or F values are potentially non-zero in the
+ // result.
+ return ComputeMaskedNonZeroBits(I->getOperand(2), Mask, Depth+1) |
+ ComputeMaskedNonZeroBits(I->getOperand(1), Mask, Depth+1);
case Instruction::Cast: {
const Type *SrcTy = I->getOperand(0)->getType();
if (SrcTy == Type::BoolTy)
- return (Mask & 1) == 0;
- if (!SrcTy->isInteger()) return false;
+ return ComputeMaskedNonZeroBits(I->getOperand(0), Mask & 1, Depth+1);
+ if (!SrcTy->isInteger()) return Mask;
// (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);
+ if (SrcTy->isUnsigned() || // Only handle zero ext/trunc/noop
+ SrcTy->getPrimitiveSizeInBits() >=
+ I->getType()->getPrimitiveSizeInBits()) {
+ Mask &= SrcTy->getIntegralTypeMask();
+ return ComputeMaskedNonZeroBits(I->getOperand(0), Mask, Depth+1);
+ }
+
+ // FIXME: handle sext casts.
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), Mask >> SA->getValue(),
- Depth+1);
+ return ComputeMaskedNonZeroBits(I->getOperand(0),Mask >> SA->getValue(),
+ Depth+1);
break;
case Instruction::Shr:
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
@@ -471,13 +472,20 @@
if (I->getType()->isUnsigned()) {
Mask <<= SA->getValue();
Mask &= I->getType()->getIntegralTypeMask();
- return MaskedValueIsZero(I->getOperand(0), Mask, Depth+1);
+ return ComputeMaskedNonZeroBits(I->getOperand(0), Mask, Depth+1);
}
break;
}
}
- return false;
+ return Mask;
+}
+
+/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
+/// 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) {
+ return ComputeMaskedNonZeroBits(V, Mask, Depth) == 0;
}
/// SimplifyDemandedBits - Look at V. At this point, we know that only the Mask
@@ -493,7 +501,9 @@
// just set the Mask to all bits.
Mask = V->getType()->getIntegralTypeMask();
} else if (Mask == 0) { // Not demanding any bits from V.
- return UpdateValueUsesWith(V, UndefValue::get(V->getType()));
+ if (V != UndefValue::get(V->getType()))
+ return UpdateValueUsesWith(V, UndefValue::get(V->getType()));
+ return false;
} else if (Depth == 6) { // Limit search depth.
return false;
}
@@ -509,15 +519,14 @@
if (SimplifyDemandedBits(I->getOperand(0), RHS->getRawValue() & Mask,
Depth+1))
return true;
- if (~Mask & RHS->getRawValue()) {
+ if (~Mask & RHS->getZExtValue()) {
// If this is producing any bits that are not needed, simplify the RHS.
- if (I->getType()->isSigned()) {
- int64_t Val = Mask & cast<ConstantSInt>(RHS)->getValue();
- I->setOperand(1, ConstantSInt::get(I->getType(), Val));
- } else {
- uint64_t Val = Mask & cast<ConstantUInt>(RHS)->getValue();
- I->setOperand(1, ConstantUInt::get(I->getType(), Val));
- }
+ uint64_t Val = Mask & RHS->getZExtValue();
+ Constant *RHS =
+ ConstantUInt::get(I->getType()->getUnsignedVersion(), Val);
+ if (I->getType()->isSigned())
+ RHS = ConstantExpr::getCast(RHS, I->getType());
+ I->setOperand(1, RHS);
return UpdateValueUsesWith(I, I);
}
}
@@ -833,7 +842,7 @@
// X + (signbit) --> X ^ signbit
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHSC)) {
- uint64_t Val = CI->getRawValue() & CI->getType()->getIntegralTypeMask();
+ uint64_t Val = CI->getZExtValue();
if (Val == (1ULL << (CI->getType()->getPrimitiveSizeInBits()-1)))
return BinaryOperator::createXor(LHS, RHS);
}
More information about the llvm-commits
mailing list