summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-02-27 02:38:23 +0000
committerChris Lattner <sabre@nondot.org>2006-02-27 02:38:23 +0000
commit3e88a4d700d912e9a5d91f22f4f9026783aec709 (patch)
tree76086007d6c50186323a7dc61e81e26ab49ae308
parentf76f5da19b339b25e8f8f6cdd361dbe4ff4f197b (diff)
downloadllvm-3e88a4d700d912e9a5d91f22f4f9026783aec709.tar.gz
llvm-3e88a4d700d912e9a5d91f22f4f9026783aec709.tar.bz2
llvm-3e88a4d700d912e9a5d91f22f4f9026783aec709.tar.xz
Merge two almost-identical pieces of code.
Make this code more powerful by using ComputeMaskedBits instead of looking for an AND operand. This lets us fold this: int %test23(int %a) { %tmp.1 = and int %a, 1 %tmp.2 = seteq int %tmp.1, 0 %tmp.3 = cast bool %tmp.2 to int ;; xor tmp1, 1 ret int %tmp.3 } into: xor (and a, 1), 1 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26396 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp88
1 files changed, 42 insertions, 46 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 38a84cd8a4..58ba380053 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -4777,63 +4777,59 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
}
break;
+ case Instruction::SetEQ:
case Instruction::SetNE:
+ // We if we are just checking for a seteq of a single bit and casting it
+ // to an integer. If so, shift the bit to the appropriate place then
+ // cast to integer to avoid the comparison.
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
- if (Op1C->getRawValue() == 0) {
- // If the input only has the low bit set, simplify directly.
- 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)->getZExtValue())) {
- if (CI.getType() == Op0->getType())
- return ReplaceInstUsesWith(CI, Op0);
- else
- return new CastInst(Op0, CI.getType());
- }
-
- // If the input is an and with a single bit, shift then simplify.
- ConstantInt *AndRHS;
- if (match(Op0, m_And(m_Value(), m_ConstantInt(AndRHS))))
- if (AndRHS->getRawValue() &&
- (AndRHS->getRawValue() & (AndRHS->getRawValue()-1)) == 0) {
- unsigned ShiftAmt = Log2_64(AndRHS->getRawValue());
+ uint64_t Op1CV = Op1C->getZExtValue();
+ // cast (X == 0) to int --> X^1 iff X has only the low bit set.
+ // cast (X == 0) to int --> (X>>1)^1 iff X has only the 2nd bit set.
+ // cast (X == 1) to int --> X iff X has only the low bit set.
+ // cast (X == 2) to int --> X>>1 iff X has only the 2nd bit set.
+ // cast (X != 0) to int --> X iff X has only the low bit set.
+ // cast (X != 0) to int --> X>>1 iff X has only the 2nd bit set.
+ // cast (X != 1) to int --> X^1 iff X has only the low bit set.
+ // cast (X != 2) to int --> (X>>1)^1 iff X has only the 2nd bit set.
+ if (Op1CV == 0 || isPowerOf2_64(Op1CV)) {
+ // If Op1C some other power of two, convert:
+ uint64_t KnownZero, KnownOne;
+ uint64_t TypeMask = Op1->getType()->getIntegralTypeMask();
+ ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne);
+
+ if (isPowerOf2_64(KnownZero^TypeMask)) { // Exactly one possible 1?
+ bool isSetNE = SrcI->getOpcode() == Instruction::SetNE;
+ if (Op1CV && (Op1CV != (KnownZero^TypeMask))) {
+ // (X&4) == 2 --> false
+ // (X&4) != 2 --> true
+ return ReplaceInstUsesWith(CI, ConstantBool::get(isSetNE));
+ }
+
+ unsigned ShiftAmt = Log2_64(KnownZero^TypeMask);
+ Value *In = Op0;
+ if (ShiftAmt) {
// Perform an unsigned shr by shiftamt. Convert input to
// unsigned if it is signed.
- Value *In = Op0;
if (In->getType()->isSigned())
In = InsertNewInstBefore(new CastInst(In,
In->getType()->getUnsignedVersion(), In->getName()),CI);
// Insert the shift to put the result in the low bit.
In = InsertNewInstBefore(new ShiftInst(Instruction::Shr, In,
- ConstantInt::get(Type::UByteTy, ShiftAmt),
- In->getName()+".lobit"), CI);
- if (CI.getType() == In->getType())
- return ReplaceInstUsesWith(CI, In);
- else
- return new CastInst(In, CI.getType());
+ ConstantInt::get(Type::UByteTy, ShiftAmt),
+ In->getName()+".lobit"), CI);
}
- }
- }
- break;
- case Instruction::SetEQ:
- // We if we are just checking for a seteq of a single bit and casting it
- // to an integer. If so, shift the bit to the appropriate place then
- // cast to integer to avoid the comparison.
- if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
- // Is Op1C a power of two or zero?
- if ((Op1C->getRawValue() & Op1C->getRawValue()-1) == 0) {
- // cast (X == 1) to int -> X iff X has only the low bit set.
- if (Op1C->getRawValue() == 1) {
- Constant *Not1 =
- ConstantExpr::getNot(ConstantInt::get(Op0->getType(), 1));
- if (MaskedValueIsZero(Op0,
- cast<ConstantIntegral>(Not1)->getZExtValue())) {
- if (CI.getType() == Op0->getType())
- return ReplaceInstUsesWith(CI, Op0);
- else
- return new CastInst(Op0, CI.getType());
+
+ if ((Op1CV != 0) == isSetNE) { // Toggle the low bit.
+ Constant *One = ConstantInt::get(In->getType(), 1);
+ In = BinaryOperator::createXor(In, One, "tmp");
+ InsertNewInstBefore(cast<Instruction>(In), CI);
}
+
+ if (CI.getType() == In->getType())
+ return ReplaceInstUsesWith(CI, In);
+ else
+ return new CastInst(In, CI.getType());
}
}
}