[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Feb 11 01:32:00 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.428 -> 1.429
---
Log message:
Port the recent innovations in ComputeMaskedBits to SimplifyDemandedBits.
This allows us to simplify on conditions where bits are not known, but they
are not demanded either! This also fixes a couple of bugs in
ComputeMaskedBits that were exposed during this work.
In the future, swaths of instcombine should be removed, as this code
subsumes a bunch of ad-hockery.
---
Diffs of the changes: (+425 -211)
InstructionCombining.cpp | 636 +++++++++++++++++++++++++++++++----------------
1 files changed, 425 insertions(+), 211 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.428 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.429
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.428 Thu Feb 9 01:41:14 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sat Feb 11 03:31:47 2006
@@ -228,7 +228,9 @@
// operators.
bool SimplifyCommutative(BinaryOperator &I);
- bool SimplifyDemandedBits(Value *V, uint64_t Mask, unsigned Depth = 0);
+ bool SimplifyDemandedBits(Value *V, uint64_t Mask,
+ uint64_t &KnownZero, uint64_t &KnownOne,
+ unsigned Depth = 0);
// FoldOpIntoPhi - Given a binary operator or cast instruction which has a
// PHI node as operand #0, see if we can fold the instruction into the PHI
@@ -406,6 +408,18 @@
ConstantInt::get(C->getType(), 1)));
}
+/// GetConstantInType - Return a ConstantInt with the specified type and value.
+///
+static ConstantInt *GetConstantInType(const Type *Ty, uint64_t Val) {
+ if (Ty->isUnsigned())
+ return ConstantUInt::get(Ty, Val);
+ int64_t SVal = Val;
+ SVal <<= 64-Ty->getPrimitiveSizeInBits();
+ SVal >>= 64-Ty->getPrimitiveSizeInBits();
+ return ConstantSInt::get(Ty, SVal);
+}
+
+
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bitsets. This code only analyzes bits in Mask, in order to short-circuit
@@ -420,7 +434,7 @@
// this won't lose us code quality.
if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V)) {
// We know all of the bits for a constant!
- KnownOne = CI->getZExtValue();
+ KnownOne = CI->getZExtValue() & Mask;
KnownZero = ~KnownOne & Mask;
return;
}
@@ -430,147 +444,149 @@
return; // Limit search depth.
uint64_t KnownZero2, KnownOne2;
- if (Instruction *I = dyn_cast<Instruction>(V)) {
- switch (I->getOpcode()) {
- case Instruction::And:
- // If either the LHS or the RHS are Zero, the result is zero.
- ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
- Mask &= ~KnownZero;
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
-
- // Output known-1 bits are only known if set in both the LHS & RHS.
- KnownOne &= KnownOne2;
- // Output known-0 are known to be clear if zero in either the LHS | RHS.
- KnownZero |= KnownZero2;
- return;
- case Instruction::Or:
- ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
-
- // Output known-0 bits are only known if clear in both the LHS & RHS.
- KnownZero &= KnownZero2;
- // Output known-1 are known to be set if set in either the LHS | RHS.
- KnownOne |= KnownOne2;
- return;
- case Instruction::Xor: {
- ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
-
- // Output known-0 bits are known if clear or set in both the LHS & RHS.
- uint64_t KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
- // Output known-1 are known to be set if set in only one of the LHS, RHS.
- KnownOne = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
- KnownZero = KnownZeroOut;
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (!I) return;
+
+ switch (I->getOpcode()) {
+ case Instruction::And:
+ // If either the LHS or the RHS are Zero, the result is zero.
+ ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
+ Mask &= ~KnownZero;
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // Output known-1 bits are only known if set in both the LHS & RHS.
+ KnownOne &= KnownOne2;
+ // Output known-0 are known to be clear if zero in either the LHS | RHS.
+ KnownZero |= KnownZero2;
+ return;
+ case Instruction::Or:
+ ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
+ Mask &= ~KnownOne;
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // Output known-0 bits are only known if clear in both the LHS & RHS.
+ KnownZero &= KnownZero2;
+ // Output known-1 are known to be set if set in either the LHS | RHS.
+ KnownOne |= KnownOne2;
+ return;
+ case Instruction::Xor: {
+ ComputeMaskedBits(I->getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // Output known-0 bits are known if clear or set in both the LHS & RHS.
+ uint64_t KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
+ // Output known-1 are known to be set if set in only one of the LHS, RHS.
+ KnownOne = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
+ KnownZero = KnownZeroOut;
+ return;
+ }
+ case Instruction::Select:
+ ComputeMaskedBits(I->getOperand(2), Mask, KnownZero, KnownOne, Depth+1);
+ ComputeMaskedBits(I->getOperand(1), Mask, KnownZero2, KnownOne2, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // Only known if known in both the LHS and RHS.
+ KnownOne &= KnownOne2;
+ KnownZero &= KnownZero2;
+ return;
+ case Instruction::Cast: {
+ const Type *SrcTy = I->getOperand(0)->getType();
+ if (!SrcTy->isIntegral()) return;
+
+ // If this is an integer truncate or noop, just look in the input.
+ if (SrcTy->getPrimitiveSizeInBits() >=
+ I->getType()->getPrimitiveSizeInBits()) {
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
return;
}
- case Instruction::Select:
- ComputeMaskedBits(I->getOperand(2), Mask, KnownZero, KnownOne, Depth+1);
- ComputeMaskedBits(I->getOperand(1), Mask, KnownZero2, KnownOne2, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
- // Only known if known in both the LHS and RHS.
- KnownOne &= KnownOne2;
- KnownZero &= KnownZero2;
- return;
- case Instruction::Cast: {
- const Type *SrcTy = I->getOperand(0)->getType();
- if (!SrcTy->isIntegral()) return;
+ // Sign or Zero extension. Compute the bits in the result that are not
+ // present in the input.
+ uint64_t NotIn = ~SrcTy->getIntegralTypeMask();
+ uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn;
- // If this is an integer truncate or noop, just look in the input.
- if (SrcTy->getPrimitiveSizeInBits() >=
- I->getType()->getPrimitiveSizeInBits()) {
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
- return;
- }
+ // Handle zero extension.
+ if (!SrcTy->isSigned()) {
+ Mask &= SrcTy->getIntegralTypeMask();
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ // The top bits are known to be zero.
+ KnownZero |= NewBits;
+ } else {
+ // Sign extension.
+ Mask &= SrcTy->getIntegralTypeMask();
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- // Sign or Zero extension. Compute the bits in the result that are not
- // present in the input.
- uint64_t NotIn = ~SrcTy->getIntegralTypeMask();
- uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn;
-
- // Handle zero extension.
- if (!SrcTy->isSigned()) {
- Mask &= SrcTy->getIntegralTypeMask();
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- // The top bits are known to be zero.
+ // If the sign bit of the input is known set or clear, then we know the
+ // top bits of the result.
+ uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1);
+ if (KnownZero & InSignBit) { // Input sign bit known zero
KnownZero |= NewBits;
- } else {
- // Sign extension.
- Mask &= SrcTy->getIntegralTypeMask();
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
-
- // If the sign bit of the input is known set or clear, then we know the
- // top bits of the result.
- uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1);
- if (KnownZero & InSignBit) { // Input sign bit known zero
- KnownZero |= NewBits;
- KnownOne &= ~NewBits;
- } else if (KnownOne & InSignBit) { // Input sign bit known set
- KnownOne |= NewBits;
- KnownZero &= ~NewBits;
- } else { // Input sign bit unknown
- KnownZero &= ~NewBits;
- KnownOne &= ~NewBits;
- }
+ KnownOne &= ~NewBits;
+ } else if (KnownOne & InSignBit) { // Input sign bit known set
+ KnownOne |= NewBits;
+ KnownZero &= ~NewBits;
+ } else { // Input sign bit unknown
+ KnownZero &= ~NewBits;
+ KnownOne &= ~NewBits;
}
+ }
+ return;
+ }
+ case Instruction::Shl:
+ // (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0
+ if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
+ Mask >>= SA->getValue();
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ KnownZero <<= SA->getValue();
+ KnownOne <<= SA->getValue();
+ KnownZero |= (1ULL << SA->getValue())-1; // low bits known zero.
return;
}
- case Instruction::Shl:
- // (shl X, C1) & C2 == 0 iff (X & C2 >>u C1) == 0
- if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
- Mask >> SA->getValue();
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
- assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
- KnownZero <<= SA->getValue();
- KnownOne <<= SA->getValue();
- KnownZero |= (1ULL << SA->getValue())-1; // low bits known zero.
- return;
- }
- break;
- case Instruction::Shr:
- // (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
- if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
- // Compute the new bits that are at the top now.
- uint64_t HighBits = (1ULL << SA->getValue())-1;
- HighBits <<= I->getType()->getPrimitiveSizeInBits()-SA->getValue();
+ break;
+ case Instruction::Shr:
+ // (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
+ if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
+ // Compute the new bits that are at the top now.
+ uint64_t HighBits = (1ULL << SA->getValue())-1;
+ HighBits <<= I->getType()->getPrimitiveSizeInBits()-SA->getValue();
+
+ if (I->getType()->isUnsigned()) { // Unsigned shift right.
+ Mask <<= SA->getValue();
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
+ assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
+ KnownZero >>= SA->getValue();
+ KnownOne >>= SA->getValue();
+ KnownZero |= HighBits; // high bits known zero.
+ } else {
+ Mask <<= SA->getValue();
+ ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
+ assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
+ KnownZero >>= SA->getValue();
+ KnownOne >>= SA->getValue();
- if (I->getType()->isUnsigned()) { // Unsigned shift right.
- Mask << SA->getValue();
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
- assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
- KnownZero >>= SA->getValue();
- KnownOne >>= SA->getValue();
- KnownZero |= HighBits; // high bits known zero.
- } else {
- Mask << SA->getValue();
- ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
- assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
- KnownZero >>= SA->getValue();
- KnownOne >>= SA->getValue();
-
- // Handle the sign bits.
- uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
- SignBit >>= SA->getValue(); // Adjust to where it is now in the mask.
-
- if (KnownZero & SignBit) { // New bits are known zero.
- KnownZero |= HighBits;
- } else if (KnownOne & SignBit) { // New bits are known one.
- KnownOne |= HighBits;
- }
+ // Handle the sign bits.
+ uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
+ SignBit >>= SA->getValue(); // Adjust to where it is now in the mask.
+
+ if (KnownZero & SignBit) { // New bits are known zero.
+ KnownZero |= HighBits;
+ } else if (KnownOne & SignBit) { // New bits are known one.
+ KnownOne |= HighBits;
}
- return;
}
- break;
+ return;
}
+ break;
}
}
@@ -584,19 +600,54 @@
return (KnownZero & Mask) == Mask;
}
-/// SimplifyDemandedBits - Look at V. At this point, we know that only the Mask
-/// bits of the result of V are ever used downstream. If we can use this
-/// information to simplify V, return V and set NewVal to the new value we
-/// should use in V's place.
-bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t Mask,
+/// ShrinkDemandedConstant - Check to see if the specified operand of the
+/// specified instruction is a constant integer. If so, check to see if there
+/// are any bits set in the constant that are not demanded. If so, shrink the
+/// constant and return true.
+static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo,
+ uint64_t Demanded) {
+ ConstantInt *OpC = dyn_cast<ConstantInt>(I->getOperand(OpNo));
+ if (!OpC) return false;
+
+ // If there are no bits set that aren't demanded, nothing to do.
+ if ((~Demanded & OpC->getZExtValue()) == 0)
+ return false;
+
+ // This is producing any bits that are not needed, shrink the RHS.
+ uint64_t Val = Demanded & OpC->getZExtValue();
+ I->setOperand(OpNo, GetConstantInType(OpC->getType(), Val));
+ return true;
+}
+
+
+
+/// SimplifyDemandedBits - Look at V. At this point, we know that only the
+/// DemandedMask bits of the result of V are ever used downstream. If we can
+/// use this information to simplify V, do so and return true. Otherwise,
+/// analyze the expression and return a mask of KnownOne and KnownZero bits for
+/// the expression (used to simplify the caller). The KnownZero/One bits may
+/// only be accurate for those bits in the DemandedMask.
+bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask,
+ uint64_t &KnownZero, uint64_t &KnownOne,
unsigned Depth) {
+ if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(V)) {
+ // We know all of the bits for a constant!
+ KnownOne = CI->getZExtValue() & DemandedMask;
+ KnownZero = ~KnownOne & DemandedMask;
+ return false;
+ }
+
+ KnownZero = KnownOne = 0;
if (!V->hasOneUse()) { // Other users may use these bits.
- if (Depth != 0) // Not at the root.
+ if (Depth != 0) { // Not at the root.
+ // Just compute the KnownZero/KnownOne bits to simplify things downstream.
+ ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
return false;
+ }
// If this is the root being simplified, allow it to have multiple uses,
- // just set the Mask to all bits.
- Mask = V->getType()->getIntegralTypeMask();
- } else if (Mask == 0) { // Not demanding any bits from V.
+ // just set the DemandedMask to all bits.
+ DemandedMask = V->getType()->getIntegralTypeMask();
+ } else if (DemandedMask == 0) { // Not demanding any bits from V.
if (V != UndefValue::get(V->getType()))
return UpdateValueUsesWith(V, UndefValue::get(V->getType()));
return false;
@@ -607,99 +658,257 @@
Instruction *I = dyn_cast<Instruction>(V);
if (!I) return false; // Only analyze instructions.
+ uint64_t KnownZero2, KnownOne2;
switch (I->getOpcode()) {
default: break;
case Instruction::And:
- if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
- // Only demanding an intersection of the bits.
- if (SimplifyDemandedBits(I->getOperand(0), RHS->getRawValue() & Mask,
- Depth+1))
- return true;
- if (~Mask & RHS->getZExtValue()) {
- // If this is producing any bits that are not needed, simplify the RHS.
- 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);
+ // If either the LHS or the RHS are Zero, the result is zero.
+ if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+
+ // If something is known zero on the RHS, the bits aren't demanded on the
+ // LHS.
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~KnownZero,
+ KnownZero2, KnownOne2, Depth+1))
+ return true;
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // If all of the demanded bits are known one on one side, return the other.
+ // These bits cannot contribute to the result of the 'and'.
+ if ((DemandedMask & ~KnownZero2 & KnownOne) == (DemandedMask & ~KnownZero2))
+ return UpdateValueUsesWith(I, I->getOperand(0));
+ if ((DemandedMask & ~KnownZero & KnownOne2) == (DemandedMask & ~KnownZero))
+ return UpdateValueUsesWith(I, I->getOperand(1));
+
+ // If the RHS is a constant, see if we can simplify it.
+ if (ShrinkDemandedConstant(I, 1, DemandedMask))
+ return UpdateValueUsesWith(I, I);
+
+ // Output known-1 bits are only known if set in both the LHS & RHS.
+ KnownOne &= KnownOne2;
+ // Output known-0 are known to be clear if zero in either the LHS | RHS.
+ KnownZero |= KnownZero2;
+ break;
+ case Instruction::Or:
+ if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~KnownOne,
+ KnownZero2, KnownOne2, Depth+1))
+ return true;
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // If all of the demanded bits are known zero on one side, return the other.
+ // These bits cannot contribute to the result of the 'or'.
+ if ((DemandedMask & ~KnownOne2 & KnownZero) == DemandedMask & ~KnownOne2)
+ return UpdateValueUsesWith(I, I->getOperand(0));
+ if ((DemandedMask & ~KnownOne & KnownZero2) == DemandedMask & ~KnownOne)
+ return UpdateValueUsesWith(I, I->getOperand(1));
+
+ // If the RHS is a constant, see if we can simplify it.
+ if (ShrinkDemandedConstant(I, 1, DemandedMask))
+ return UpdateValueUsesWith(I, I);
+
+ // Output known-0 bits are only known if clear in both the LHS & RHS.
+ KnownZero &= KnownZero2;
+ // Output known-1 are known to be set if set in either the LHS | RHS.
+ KnownOne |= KnownOne2;
+ break;
+ case Instruction::Xor: {
+ if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ KnownZero2, KnownOne2, Depth+1))
+ return true;
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // If all of the demanded bits are known zero on one side, return the other.
+ // These bits cannot contribute to the result of the 'xor'.
+ if ((DemandedMask & KnownZero) == DemandedMask)
+ return UpdateValueUsesWith(I, I->getOperand(0));
+ if ((DemandedMask & KnownZero2) == DemandedMask)
+ return UpdateValueUsesWith(I, I->getOperand(1));
+
+ // Output known-0 bits are known if clear or set in both the LHS & RHS.
+ uint64_t KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);
+ // Output known-1 are known to be set if set in only one of the LHS, RHS.
+ uint64_t KnownOneOut = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);
+
+ // If all of the unknown bits are known to be zero on one side or the other
+ // (but not both) turn this into an *inclusive* or.
+ if (uint64_t UnknownBits = DemandedMask & ~(KnownZeroOut|KnownOneOut)) {
+ if ((UnknownBits & (KnownZero|KnownZero2)) == UnknownBits) {
+ Instruction *Or =
+ BinaryOperator::createOr(I->getOperand(0), I->getOperand(1),
+ I->getName());
+ InsertNewInstBefore(Or, *I);
+ return UpdateValueUsesWith(I, Or);
}
}
- // Walk the LHS and the RHS.
- return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1) ||
- SimplifyDemandedBits(I->getOperand(1), Mask, Depth+1);
- case Instruction::Or:
- case Instruction::Xor:
- if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
- // If none of the [x]or'd in bits are demanded, don't both with the [x]or.
- if ((Mask & RHS->getRawValue()) == 0)
- return UpdateValueUsesWith(I, I->getOperand(0));
-
- // Otherwise, for an OR, we only demand those bits not set by the OR.
- if (I->getOpcode() == Instruction::Or)
- Mask &= ~RHS->getRawValue();
- return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1);
- }
- // Walk the LHS and the RHS.
- return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1) ||
- SimplifyDemandedBits(I->getOperand(1), Mask, Depth+1);
+
+ // If the RHS is a constant, see if we can simplify it.
+ // FIXME: for XOR, we prefer to force bits to 1 if they will make a -1.
+ if (ShrinkDemandedConstant(I, 1, DemandedMask))
+ return UpdateValueUsesWith(I, I);
+
+ KnownZero = KnownZeroOut;
+ KnownOne = KnownOneOut;
+ break;
+ }
+ case Instruction::Select:
+ if (SimplifyDemandedBits(I->getOperand(2), DemandedMask,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ if (SimplifyDemandedBits(I->getOperand(1), DemandedMask,
+ KnownZero2, KnownOne2, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
+
+ // If the operands are constants, see if we can simplify them.
+ if (ShrinkDemandedConstant(I, 1, DemandedMask))
+ return UpdateValueUsesWith(I, I);
+ if (ShrinkDemandedConstant(I, 2, DemandedMask))
+ return UpdateValueUsesWith(I, I);
+
+ // Only known if known in both the LHS and RHS.
+ KnownOne &= KnownOne2;
+ KnownZero &= KnownZero2;
+ break;
case Instruction::Cast: {
const Type *SrcTy = I->getOperand(0)->getType();
- if (SrcTy == Type::BoolTy)
- return SimplifyDemandedBits(I->getOperand(0), Mask&1, Depth+1);
+ if (!SrcTy->isIntegral()) return false;
- if (!SrcTy->isInteger()) return false;
-
- unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
- // If this is a sign-extend, treat specially.
- if (SrcTy->isSigned() &&
- SrcBits < I->getType()->getPrimitiveSizeInBits()) {
- // If none of the top bits are demanded, convert this into an unsigned
- // extend instead of a sign extend.
- if ((Mask & ((1ULL << SrcBits)-1)) == 0) {
+ // If this is an integer truncate or noop, just look in the input.
+ if (SrcTy->getPrimitiveSizeInBits() >=
+ I->getType()->getPrimitiveSizeInBits()) {
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ break;
+ }
+
+ // Sign or Zero extension. Compute the bits in the result that are not
+ // present in the input.
+ uint64_t NotIn = ~SrcTy->getIntegralTypeMask();
+ uint64_t NewBits = I->getType()->getIntegralTypeMask() & NotIn;
+
+ // Handle zero extension.
+ if (!SrcTy->isSigned()) {
+ DemandedMask &= SrcTy->getIntegralTypeMask();
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ // The top bits are known to be zero.
+ KnownZero |= NewBits;
+ } else {
+ // Sign extension.
+ if (SimplifyDemandedBits(I->getOperand(0),
+ DemandedMask & SrcTy->getIntegralTypeMask(),
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+
+ // If the sign bit of the input is known set or clear, then we know the
+ // top bits of the result.
+ uint64_t InSignBit = 1ULL << (SrcTy->getPrimitiveSizeInBits()-1);
+
+ // If the input sign bit is known zero, or if the NewBits are not demanded
+ // convert this into a zero extension.
+ if ((KnownZero & InSignBit) || (NewBits & ~DemandedMask) == NewBits) {
// Convert to unsigned first.
Instruction *NewVal;
NewVal = new CastInst(I->getOperand(0), SrcTy->getUnsignedVersion(),
I->getOperand(0)->getName());
InsertNewInstBefore(NewVal, *I);
+ // Then cast that to the destination type.
NewVal = new CastInst(NewVal, I->getType(), I->getName());
InsertNewInstBefore(NewVal, *I);
return UpdateValueUsesWith(I, NewVal);
+ } else if (KnownOne & InSignBit) { // Input sign bit known set
+ KnownOne |= NewBits;
+ KnownZero &= ~NewBits;
+ } else { // Input sign bit unknown
+ KnownZero &= ~NewBits;
+ KnownOne &= ~NewBits;
}
-
- // Otherwise, the high-bits *are* demanded. This means that the code
- // implicitly demands computation of the sign bit of the input, make sure
- // we explicitly include it in Mask.
- Mask |= 1ULL << (SrcBits-1);
}
-
- // If this is an extension, the top bits are ignored.
- Mask &= SrcTy->getIntegralTypeMask();
- return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1);
+ break;
}
- case Instruction::Select:
- // Simplify the T and F values if they are not demanded.
- return SimplifyDemandedBits(I->getOperand(2), Mask, Depth+1) ||
- SimplifyDemandedBits(I->getOperand(1), Mask, Depth+1);
case Instruction::Shl:
- // We only demand the low bits of the input.
- if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1)))
- return SimplifyDemandedBits(I->getOperand(0), Mask >> SA->getValue(),
- Depth+1);
+ if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask >> SA->getValue(),
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ KnownZero <<= SA->getValue();
+ KnownOne <<= SA->getValue();
+ KnownZero |= (1ULL << SA->getValue())-1; // low bits known zero.
+ }
break;
case Instruction::Shr:
- // We only demand the high bits of the input.
- if (I->getType()->isUnsigned())
- if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
- Mask <<= SA->getValue();
- Mask &= I->getType()->getIntegralTypeMask();
- return SimplifyDemandedBits(I->getOperand(0), Mask, Depth+1);
+ if (ConstantUInt *SA = dyn_cast<ConstantUInt>(I->getOperand(1))) {
+ unsigned ShAmt = SA->getValue();
+
+ // Compute the new bits that are at the top now.
+ uint64_t HighBits = (1ULL << ShAmt)-1;
+ HighBits <<= I->getType()->getPrimitiveSizeInBits() - ShAmt;
+
+ if (I->getType()->isUnsigned()) { // Unsigned shift right.
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask << ShAmt,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ KnownZero >>= ShAmt;
+ KnownOne >>= ShAmt;
+ KnownZero |= HighBits; // high bits known zero.
+ } else { // Signed shift right.
+ if (SimplifyDemandedBits(I->getOperand(0), DemandedMask << ShAmt,
+ KnownZero, KnownOne, Depth+1))
+ return true;
+ assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
+ KnownZero >>= SA->getValue();
+ KnownOne >>= SA->getValue();
+
+ // Handle the sign bits.
+ uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
+ SignBit >>= SA->getValue(); // Adjust to where it is now in the mask.
+
+ // If the input sign bit is known to be zero, or if none of the top bits
+ // are demanded, turn this into an unsigned shift right.
+ if ((KnownZero & SignBit) || (HighBits & ~DemandedMask) == HighBits) {
+ // Convert the input to unsigned.
+ Instruction *NewVal;
+ NewVal = new CastInst(I->getOperand(0),
+ I->getType()->getUnsignedVersion(),
+ I->getOperand(0)->getName());
+ InsertNewInstBefore(NewVal, *I);
+ // Perform the unsigned shift right.
+ NewVal = new ShiftInst(Instruction::Shr, NewVal, SA, I->getName());
+ InsertNewInstBefore(NewVal, *I);
+ // Then cast that to the destination type.
+ NewVal = new CastInst(NewVal, I->getType(), I->getName());
+ InsertNewInstBefore(NewVal, *I);
+ return UpdateValueUsesWith(I, NewVal);
+ } else if (KnownOne & SignBit) { // New bits are known one.
+ KnownOne |= HighBits;
+ }
}
- // FIXME: handle signed shr, demanding the appropriate bits. If the top
- // bits aren't demanded, strength reduce to a logical SHR instead.
+ }
break;
}
+
+ // If the client is only demanding bits that we know, return the known
+ // constant.
+ if ((DemandedMask & (KnownZero|KnownOne)) == DemandedMask)
+ return UpdateValueUsesWith(I, GetConstantInType(I->getType(), KnownOne));
return false;
}
@@ -2021,7 +2230,9 @@
// See if we can simplify any instructions used by the LHS whose sole
// purpose is to compute bits we don't care about.
- if (SimplifyDemandedBits(&I, I.getType()->getIntegralTypeMask()))
+ uint64_t KnownZero, KnownOne;
+ if (SimplifyDemandedBits(&I, I.getType()->getIntegralTypeMask(),
+ KnownZero, KnownOne))
return &I;
if (ConstantIntegral *AndRHS = dyn_cast<ConstantIntegral>(Op1)) {
@@ -4378,9 +4589,12 @@
// See if we can simplify any instructions used by the LHS whose sole
// purpose is to compute bits we don't care about.
- if (CI.getType()->isInteger() && CI.getOperand(0)->getType()->isIntegral() &&
- SimplifyDemandedBits(&CI, CI.getType()->getIntegralTypeMask()))
- return &CI;
+ if (CI.getType()->isInteger() && CI.getOperand(0)->getType()->isIntegral()) {
+ uint64_t KnownZero, KnownOne;
+ if (SimplifyDemandedBits(&CI, CI.getType()->getIntegralTypeMask(),
+ KnownZero, KnownOne))
+ return &CI;
+ }
// If casting the result of a getelementptr instruction with no offset, turn
// this into a cast of the original pointer!
More information about the llvm-commits
mailing list