From: Chris Lattner Date: Fri, 24 Sep 2004 15:21:34 +0000 (+0000) Subject: Implement shift-and combinations, implementing InstCombine/and.ll:test19-21 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=0c96766c90733e9f263334b6b079d58ce2e33791;p=oota-llvm.git Implement shift-and combinations, implementing InstCombine/and.ll:test19-21 These combinations trigger 4 times in povray, 7x in gcc, 4x in gap, and 2x in bzip2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16508 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 7a90c76d3cb..e579cf1a7bc 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -146,6 +146,17 @@ namespace { return New; } + /// InsertCastBefore - Insert a cast of V to TY before the instruction POS. + /// This also adds the cast to the worklist. Finally, this returns the + /// cast. + Value *InsertCastBefore(Value *V, const Type *Ty, Instruction &Pos) { + if (V->getType() == Ty) return V; + + Instruction *C = new CastInst(V, Ty, V->getName(), &Pos); + WorkList.push_back(C); + return C; + } + // ReplaceInstUsesWith - This method is to be used when an instruction is // found to be dead, replacable with another preexisting expression. Here // we add all uses of I to the worklist, replace all uses of I with the new @@ -1088,9 +1099,12 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op, // the anded constant includes them, clear them now! // Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType()); - Constant *CI = ConstantExpr::getAnd(AndRHS, - ConstantExpr::getShl(AllOne, OpRHS)); - if (CI != AndRHS) { + Constant *ShlMask = ConstantExpr::getShl(AllOne, OpRHS); + Constant *CI = ConstantExpr::getAnd(AndRHS, ShlMask); + + if (CI == ShlMask) { // Masking out bits that the shift already masks + return ReplaceInstUsesWith(TheAnd, Op); // No need for the and. + } else if (CI != AndRHS) { // Reducing bits set in and. TheAnd.setOperand(1, CI); return &TheAnd; } @@ -1103,12 +1117,34 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op, // if (AndRHS->getType()->isUnsigned()) { Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType()); - Constant *CI = ConstantExpr::getAnd(AndRHS, - ConstantExpr::getShr(AllOne, OpRHS)); - if (CI != AndRHS) { - TheAnd.setOperand(1, CI); + Constant *ShrMask = ConstantExpr::getShr(AllOne, OpRHS); + Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask); + + if (CI == ShrMask) { // Masking out bits that the shift already masks. + return ReplaceInstUsesWith(TheAnd, Op); + } else if (CI != AndRHS) { + TheAnd.setOperand(1, CI); // Reduce bits set in and cst. return &TheAnd; } + } else { // Signed shr. + // See if this is shifting in some sign extension, then masking it out + // with an and. + if (Op->hasOneUse()) { + Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType()); + Constant *ShrMask = ConstantExpr::getUShr(AllOne, OpRHS); + Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask); + if (CI == ShrMask) { // Masking out bits shifted in. + // Make the argument unsigned. + Value *ShVal = Op->getOperand(0); + ShVal = InsertCastBefore(ShVal, + ShVal->getType()->getUnsignedVersion(), + TheAnd); + ShVal = InsertNewInstBefore(new ShiftInst(Instruction::Shr, ShVal, + OpRHS, Op->getName()), + TheAnd); + return new CastInst(ShVal, Op->getType()); + } + } } break; } @@ -1509,6 +1545,7 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { } } break; + case Instruction::Div: if (0 && isa(LHSI->getOperand(1))) { std::cerr << "COULD FOLD: " << *LHSI;