Implement InstCombine/cast.ll:test29
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index 79d79011f4b1c53a0a727a717b880fdc88421019..2c8f6eda4955a2582e9ff7b05da2bec90eff7475 100644 (file)
@@ -456,6 +456,8 @@ static void ComputeMaskedBits(Value *V, uint64_t Mask, uint64_t &KnownZero,
   Instruction *I = dyn_cast<Instruction>(V);
   if (!I) return;
 
+  Mask &= V->getType()->getIntegralTypeMask();
+  
   switch (I->getOpcode()) {
   case Instruction::And:
     // If either the LHS or the RHS are Zero, the result is zero.
@@ -713,6 +715,8 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask,
   Instruction *I = dyn_cast<Instruction>(V);
   if (!I) return false;        // Only analyze instructions.
 
+  DemandedMask &= V->getType()->getIntegralTypeMask();
+  
   uint64_t KnownZero2, KnownOne2;
   switch (I->getOpcode()) {
   default: break;
@@ -2636,6 +2640,19 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
         }
   }
 
+  // fold (and (cast A), (cast B)) -> (cast (and A, B))
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
+    if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
+      if (Op0C->getOperand(0)->getType() == Op1C->getOperand(0)->getType() &&
+          Op0C->getOperand(0)->getType()->isIntegral()) {
+        Instruction *NewOp = BinaryOperator::createAnd(Op0C->getOperand(0),
+                                                       Op1C->getOperand(0),
+                                                       I.getName());
+        InsertNewInstBefore(NewOp, I);
+        return new CastInst(NewOp, I.getType());
+      }
+  }
+
   return Changed ? &I : 0;
 }
 
@@ -2861,6 +2878,20 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
           }
         }
   }
+    
+  // fold (or (cast A), (cast B)) -> (cast (or A, B))
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
+    if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
+      if (Op0C->getOperand(0)->getType() == Op1C->getOperand(0)->getType() &&
+          Op0C->getOperand(0)->getType()->isIntegral()) {
+        Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
+                                                      Op1C->getOperand(0),
+                                                      I.getName());
+        InsertNewInstBefore(NewOp, I);
+        return new CastInst(NewOp, I.getType());
+      }
+  }
+      
 
   return Changed ? &I : 0;
 }
@@ -3026,6 +3057,19 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
     if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
       return R;
 
+  // fold (xor (cast A), (cast B)) -> (cast (xor A, B))
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
+    if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
+      if (Op0C->getOperand(0)->getType() == Op1C->getOperand(0)->getType() &&
+          Op0C->getOperand(0)->getType()->isIntegral()) {
+        Instruction *NewOp = BinaryOperator::createXor(Op0C->getOperand(0),
+                                                       Op1C->getOperand(0),
+                                                       I.getName());
+        InsertNewInstBefore(NewOp, I);
+        return new CastInst(NewOp, I.getType());
+      }
+  }
+    
   return Changed ? &I : 0;
 }
 
@@ -4435,7 +4479,7 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1,
       // this case, C1 == C2 and C1 is 8, 16, or 32.
       if (ShiftAmt1 == ShiftAmt2) {
         const Type *SExtType = 0;
-        switch (ShiftAmt1) {
+        switch (Op0->getType()->getPrimitiveSizeInBits() - ShiftAmt1) {
         case 8 : SExtType = Type::SByteTy; break;
         case 16: SExtType = Type::ShortTy; break;
         case 32: SExtType = Type::IntTy; break;
@@ -5683,7 +5727,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
     if (Callee->isExternal() &&
         !(OldRetTy->isLosslesslyConvertibleTo(FT->getReturnType()) ||
           (isa<PointerType>(FT->getReturnType()) && 
-           OldRetTy->isLosslesslyConvertibleTo(TD->getIntPtrType())))
+           TD->getIntPtrType()->isLosslesslyConvertibleTo(OldRetTy)))
         && !Caller->use_empty())
       return false;   // Cannot transform this return value...
 
@@ -6959,12 +7003,23 @@ static bool CollectSingleShuffleElements(Value *V, Value *LHS, Value *RHS,
     Value *ScalarOp = IEI->getOperand(1);
     Value *IdxOp    = IEI->getOperand(2);
     
-    if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)) {
-      if (isa<ConstantInt>(EI->getOperand(1)) && isa<ConstantInt>(IdxOp) &&
+    if (!isa<ConstantInt>(IdxOp))
+      return false;
+    unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getRawValue();
+    
+    if (isa<UndefValue>(ScalarOp)) {  // inserting undef into vector.
+      // Okay, we can handle this if the vector we are insertinting into is
+      // transitively ok.
+      if (CollectSingleShuffleElements(VecOp, LHS, RHS, Mask)) {
+        // If so, update the mask to reflect the inserted undef.
+        Mask[InsertedIdx] = UndefValue::get(Type::UIntTy);
+        return true;
+      }      
+    } else if (ExtractElementInst *EI = dyn_cast<ExtractElementInst>(ScalarOp)){
+      if (isa<ConstantInt>(EI->getOperand(1)) &&
           EI->getOperand(0)->getType() == V->getType()) {
         unsigned ExtractedIdx =
           cast<ConstantInt>(EI->getOperand(1))->getRawValue();
-        unsigned InsertedIdx = cast<ConstantInt>(IdxOp)->getRawValue();
         
         // This must be extracting from either LHS or RHS.
         if (EI->getOperand(0) == LHS || EI->getOperand(0) == RHS) {