diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-27 02:38:23 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-27 02:38:23 +0000 |
commit | 3e88a4d700d912e9a5d91f22f4f9026783aec709 (patch) | |
tree | 76086007d6c50186323a7dc61e81e26ab49ae308 | |
parent | f76f5da19b339b25e8f8f6cdd361dbe4ff4f197b (diff) | |
download | llvm-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.cpp | 88 |
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()); } } } |