[llvm-commits] [llvm] r48631 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/add.ll
Chris Lattner
sabre at nondot.org
Thu Mar 20 22:19:59 PDT 2008
Author: lattner
Date: Fri Mar 21 00:19:58 2008
New Revision: 48631
URL: http://llvm.org/viewvc/llvm-project?rev=48631&view=rev
Log:
Teach masked value is zero about add and sub, and use MVIZ to
simplify things like (X & 4) >> 1 == 2 --> (X & 4) == 4.
since it is obvious that the shift doesn't remove any bits.
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/add.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=48631&r1=48630&r2=48631&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Mar 21 00:19:58 2008
@@ -833,6 +833,49 @@
return;
}
break;
+ case Instruction::Add:
+ // If either the LHS or the RHS are Zero, the result is zero.
+ 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 low clear bits
+ // common to both LHS & RHS. For example, 8+(X<<3) is known to have the
+ // low 3 bits clear.
+ unsigned KnownZeroOut = std::min(KnownZero.countTrailingOnes(),
+ KnownZero2.countTrailingOnes());
+
+ KnownZero = APInt::getLowBitsSet(BitWidth, KnownZeroOut);
+ KnownOne = APInt(BitWidth, 0);
+ return;
+ case Instruction::Sub: {
+ ConstantInt *CLHS = dyn_cast<ConstantInt>(I->getOperand(0));
+ if (!CLHS) break;
+
+ // We know that the top bits of C-X are clear if X contains less bits
+ // than C (i.e. no wrap-around can happen). For example, 20-X is
+ // positive if we can prove that X is >= 0 and < 16.
+ if (CLHS->getValue().isNegative())
+ break;
+
+ unsigned NLZ = (CLHS->getValue()+1).countLeadingZeros();
+ // NLZ can't be BitWidth with no sign bit
+ APInt MaskV = APInt::getHighBitsSet(BitWidth, NLZ+1);
+ ComputeMaskedBits(I->getOperand(1), MaskV, KnownZero, KnownOne, Depth+1);
+
+ // If all of the MaskV bits are known to be zero, then we know the output
+ // top bits are zero, because we now know that the output is from [0-C].
+ if ((KnownZero & MaskV) == MaskV) {
+ unsigned NLZ2 = CLHS->getValue().countLeadingZeros();
+ // Top bits known zero.
+ KnownZero = APInt::getHighBitsSet(BitWidth, NLZ2) & Mask;
+ KnownOne = APInt(BitWidth, 0); // No one bits known.
+ } else {
+ KnownZero = KnownOne = APInt(BitWidth, 0); // Otherwise, nothing known.
+ }
+ return;
+ }
case Instruction::SRem:
if (ConstantInt *Rem = dyn_cast<ConstantInt>(I->getOperand(1))) {
APInt RA = Rem->getValue();
@@ -869,7 +912,8 @@
// Since the result is less than or equal to RHS, any leading zero bits
// in RHS must also exist in the result.
APInt AllOnes = APInt::getAllOnesValue(BitWidth);
- ComputeMaskedBits(I->getOperand(1), AllOnes, KnownZero2, KnownOne2, Depth+1);
+ ComputeMaskedBits(I->getOperand(1), AllOnes, KnownZero2, KnownOne2,
+ Depth+1);
uint32_t Leaders = KnownZero2.countLeadingOnes();
KnownZero |= APInt::getHighBitsSet(BitWidth, Leaders) & Mask;
@@ -5701,44 +5745,53 @@
case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI)
case Instruction::AShr: {
+ // Only handle equality comparisons of shift-by-constant.
ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1));
- if (!ShAmt) break;
+ if (!ShAmt || !ICI.isEquality()) break;
- if (ICI.isEquality()) {
- // Check that the shift amount is in range. If not, don't perform
- // undefined shifts. When the shift is visited it will be
- // simplified.
- uint32_t TypeBits = RHSV.getBitWidth();
- if (ShAmt->uge(TypeBits))
- break;
- uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits);
-
- // If we are comparing against bits always shifted out, the
- // comparison cannot succeed.
- APInt Comp = RHSV << ShAmtVal;
- if (LHSI->getOpcode() == Instruction::LShr)
- Comp = Comp.lshr(ShAmtVal);
- else
- Comp = Comp.ashr(ShAmtVal);
+ // Check that the shift amount is in range. If not, don't perform
+ // undefined shifts. When the shift is visited it will be
+ // simplified.
+ uint32_t TypeBits = RHSV.getBitWidth();
+ if (ShAmt->uge(TypeBits))
+ break;
+
+ uint32_t ShAmtVal = (uint32_t)ShAmt->getLimitedValue(TypeBits);
- if (Comp != RHSV) { // Comparing against a bit that we know is zero.
- bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE;
- Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE);
- return ReplaceInstUsesWith(ICI, Cst);
- }
+ // If we are comparing against bits always shifted out, the
+ // comparison cannot succeed.
+ APInt Comp = RHSV << ShAmtVal;
+ if (LHSI->getOpcode() == Instruction::LShr)
+ Comp = Comp.lshr(ShAmtVal);
+ else
+ Comp = Comp.ashr(ShAmtVal);
+
+ if (Comp != RHSV) { // Comparing against a bit that we know is zero.
+ bool IsICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE;
+ Constant *Cst = ConstantInt::get(Type::Int1Ty, IsICMP_NE);
+ return ReplaceInstUsesWith(ICI, Cst);
+ }
+
+ // Otherwise, check to see if the bits shifted out are known to be zero.
+ // If so, we can compare against the unshifted value:
+ // (X & 4) >> 1 == 2 --> (X & 4) == 4.
+ if (MaskedValueIsZero(LHSI->getOperand(0),
+ APInt::getLowBitsSet(Comp.getBitWidth(), ShAmtVal))) {
+ return new ICmpInst(ICI.getPredicate(), LHSI->getOperand(0),
+ ConstantExpr::getShl(RHS, ShAmt));
+ }
+
+ if (LHSI->hasOneUse() || RHSV == 0) {
+ // Otherwise strength reduce the shift into an and.
+ APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal));
+ Constant *Mask = ConstantInt::get(Val);
- if (LHSI->hasOneUse() || RHSV == 0) {
- // Otherwise strength reduce the shift into an and.
- APInt Val(APInt::getHighBitsSet(TypeBits, TypeBits - ShAmtVal));
- Constant *Mask = ConstantInt::get(Val);
-
- Instruction *AndI =
- BinaryOperator::createAnd(LHSI->getOperand(0),
- Mask, LHSI->getName()+".mask");
- Value *And = InsertNewInstBefore(AndI, ICI);
- return new ICmpInst(ICI.getPredicate(), And,
- ConstantExpr::getShl(RHS, ShAmt));
- }
+ Instruction *AndI =
+ BinaryOperator::createAnd(LHSI->getOperand(0),
+ Mask, LHSI->getName()+".mask");
+ Value *And = InsertNewInstBefore(AndI, ICI);
+ return new ICmpInst(ICI.getPredicate(), And,
+ ConstantExpr::getShl(RHS, ShAmt));
}
break;
}
Modified: llvm/trunk/test/Transforms/InstCombine/add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/add.ll?rev=48631&r1=48630&r2=48631&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/add.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/add.ll Fri Mar 21 00:19:58 2008
@@ -268,3 +268,10 @@
ret i32 %tmp2
}
+define i32 @test36(i32 %a) {
+ %x = and i32 %a, -2
+ %y = and i32 %a, -126
+ %z = add i32 %x, %y
+ %q = and i32 %z, 1 ; always zero
+ ret i32 %q
+}
More information about the llvm-commits
mailing list