[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sun Aug 7 00:03:21 PDT 2005
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.363 -> 1.364
---
Log message:
Add some simple folds that occur in bitfield cases. Fix a minor bug in
isHighOnes, where it would consider 0 to have high ones.
---
Diffs of the changes: (+32 -0)
InstructionCombining.cpp | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.363 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.364
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.363 Thu Aug 4 20:04:30 2005
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Aug 7 02:03:10 2005
@@ -1215,6 +1215,7 @@
// This is the same as lowones(~X).
static bool isHighOnes(const ConstantInt *CI) {
uint64_t V = ~CI->getRawValue();
+ if (~V == 0) return false; // 0's does not match "1+"
// There won't be bits set in parts that the type doesn't contain.
V &= ConstantInt::getAllOnesValue(CI->getType())->getRawValue();
@@ -1636,6 +1637,37 @@
} else if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
const Type *SrcTy = CI->getOperand(0)->getType();
+ // If this is an integer truncation or change from signed-to-unsigned, and
+ // if the source is an and/or with immediate, transform it. This
+ // frequently occurs for bitfield accesses.
+ if (Instruction *CastOp = dyn_cast<Instruction>(CI->getOperand(0))) {
+ if (SrcTy->getPrimitiveSizeInBits() >=
+ I.getType()->getPrimitiveSizeInBits() &&
+ CastOp->getNumOperands() == 2)
+ if (ConstantInt *AndCI =dyn_cast<ConstantInt>(CastOp->getOperand(1)))
+ if (CastOp->getOpcode() == Instruction::And) {
+ // Change: and (cast (and X, C1) to T), C2
+ // into : and (cast X to T), trunc(C1)&C2
+ // This will folds the two ands together, which may allow other
+ // simplifications.
+ Instruction *NewCast =
+ new CastInst(CastOp->getOperand(0), I.getType(),
+ CastOp->getName()+".shrunk");
+ NewCast = InsertNewInstBefore(NewCast, I);
+
+ Constant *C3=ConstantExpr::getCast(AndCI, I.getType());//trunc(C1)
+ C3 = ConstantExpr::getAnd(C3, AndRHS); // trunc(C1)&C2
+ return BinaryOperator::createAnd(NewCast, C3);
+ } else if (CastOp->getOpcode() == Instruction::Or) {
+ // Change: and (cast (or X, C1) to T), C2
+ // into : trunc(C1)&C2 iff trunc(C1)&C2 == C2
+ Constant *C3=ConstantExpr::getCast(AndCI, I.getType());//trunc(C1)
+ if (ConstantExpr::getAnd(C3, AndRHS) == AndRHS) // trunc(C1)&C2
+ return ReplaceInstUsesWith(I, AndRHS);
+ }
+ }
+
+
// If this is an integer sign or zero extension instruction.
if (SrcTy->isIntegral() &&
SrcTy->getPrimitiveSizeInBits() <
More information about the llvm-commits
mailing list