Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.738 -> 1.739 --- Log message: fix a miscompilation of: define i32 @test(i32 %X) { entry: %Y = and i32 %X, 4 ; <i32> [#uses=1] icmp eq i32 %Y, 0 ; <i1>:0 [#uses=1] sext i1 %0 to i32 ; <i32>:1 [#uses=1] ret i32 %1 } by moving code out of commonIntCastTransforms into visitZExt. Simplify the APInt gymnastics in it etc. --- Diffs of the changes: (+59 -63) InstructionCombining.cpp | 122 ++++++++++++++++++++++------------------------- 1 files changed, 59 insertions(+), 63 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.738 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.739 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.738 Mon Apr 9 18:52:13 2007 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Wed Apr 11 00:45:39 2007 @@ -6457,69 +6457,6 @@ } } break; - - case Instruction::ICmp: - // If we are just checking for a icmp eq of a single bit and casting it - // to an integer, then shift the bit to the appropriate place and then - // cast to integer to avoid the comparison. - if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { - const APInt& Op1CV = Op1C->getValue(); - // 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 || Op1CV.isPowerOf2()) { - // If Op1C some other power of two, convert: - uint32_t BitWidth = Op1C->getType()->getBitWidth(); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - APInt TypeMask(APInt::getAllOnesValue(BitWidth)); - ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne); - - // This only works for EQ and NE - ICmpInst::Predicate pred = cast<ICmpInst>(SrcI)->getPredicate(); - if (pred != ICmpInst::ICMP_NE && pred != ICmpInst::ICMP_EQ) - break; - - APInt KnownZeroMask(KnownZero ^ TypeMask); - if (KnownZeroMask.isPowerOf2()) { // Exactly 1 possible 1? - bool isNE = pred == ICmpInst::ICMP_NE; - if (Op1CV != 0 && (Op1CV != KnownZeroMask)) { - // (X&4) == 2 --> false - // (X&4) != 2 --> true - Constant *Res = ConstantInt::get(Type::Int1Ty, isNE); - Res = ConstantExpr::getZExt(Res, CI.getType()); - return ReplaceInstUsesWith(CI, Res); - } - - uint32_t ShiftAmt = KnownZeroMask.logBase2(); - Value *In = Op0; - if (ShiftAmt) { - // Perform a logical shr by shiftamt. - // Insert the shift to put the result in the low bit. - In = InsertNewInstBefore( - BinaryOperator::createLShr(In, - ConstantInt::get(In->getType(), ShiftAmt), - In->getName()+".lobit"), CI); - } - - if ((Op1CV != 0) == isNE) { // 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 CastInst::createIntegerCast(In, CI.getType(), false/*ZExt*/); - } - } - } - break; } return 0; } @@ -6617,6 +6554,65 @@ } } + if (ICmpInst *ICI = dyn_cast<ICmpInst>(Src)) { + // If we are just checking for a icmp eq of a single bit and zext'ing it + // to an integer, then shift the bit to the appropriate place and then + // cast to integer to avoid the comparison. + if (ConstantInt *Op1C = dyn_cast<ConstantInt>(ICI->getOperand(1))) { + const APInt& Op1CV = Op1C->getValue(); + // 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 || Op1CV.isPowerOf2()) && + // This only works for EQ and NE + ICI->isEquality()) { + // If Op1C some other power of two, convert: + uint32_t BitWidth = Op1C->getType()->getBitWidth(); + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); + APInt TypeMask(APInt::getAllOnesValue(BitWidth)); + ComputeMaskedBits(ICI->getOperand(0), TypeMask, KnownZero, KnownOne); + + APInt KnownZeroMask(~KnownZero); + if (KnownZeroMask.isPowerOf2()) { // Exactly 1 possible 1? + bool isNE = ICI->getPredicate() == ICmpInst::ICMP_NE; + if (Op1CV != 0 && (Op1CV != KnownZeroMask)) { + // (X&4) == 2 --> false + // (X&4) != 2 --> true + Constant *Res = ConstantInt::get(Type::Int1Ty, isNE); + Res = ConstantExpr::getZExt(Res, CI.getType()); + return ReplaceInstUsesWith(CI, Res); + } + + uint32_t ShiftAmt = KnownZeroMask.logBase2(); + Value *In = ICI->getOperand(0); + if (ShiftAmt) { + // Perform a logical shr by shiftamt. + // Insert the shift to put the result in the low bit. + In = InsertNewInstBefore( + BinaryOperator::createLShr(In, + ConstantInt::get(In->getType(), ShiftAmt), + In->getName()+".lobit"), CI); + } + + if ((Op1CV != 0) == isNE) { // 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 CastInst::createIntegerCast(In, CI.getType(), false/*ZExt*/); + } + } + } + } return 0; } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits