[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