[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Sep 24 08:21:47 PDT 2004
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.248 -> 1.249
---
Log message:
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.
---
Diffs of the changes: (+44 -7)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.248 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.249
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.248 Thu Sep 23 16:52:49 2004
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Fri Sep 24 10:21:34 2004
@@ -146,6 +146,17 @@
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 @@
// 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 @@
//
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 @@
}
}
break;
+
case Instruction::Div:
if (0 && isa<ConstantInt>(LHSI->getOperand(1))) {
std::cerr << "COULD FOLD: " << *LHSI;
More information about the llvm-commits
mailing list