Can't fold the bit_convert is the store is a truncating store.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / TargetLowering.cpp
index 51d8187aa17629f2c7dad436e304ef556090f3cd..1a8a4bc349feea77e975f9719289fc86c00ee47d 100644 (file)
@@ -303,12 +303,9 @@ unsigned TargetLowering::getVectorTypeBreakdown(const VectorType *PTy,
     NumVectorRegs <<= 1;
   }
   
-  MVT::ValueType VT;
-  if (NumElts == 1) {
+  MVT::ValueType VT = getVectorType(EltTy, NumElts);
+  if (!isTypeLegal(VT))
     VT = EltTy;
-  } else {
-    VT = getVectorType(EltTy, NumElts); 
-  }
   PTyElementVT = VT;
 
   MVT::ValueType DestVT = getTypeToTransformTo(VT);
@@ -566,7 +563,32 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
     break;
   case ISD::SHL:
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
-      if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask >> SA->getValue(),
+      unsigned ShAmt = SA->getValue();
+      SDOperand InOp = Op.getOperand(0);
+
+      // If this is ((X >>u C1) << ShAmt), see if we can simplify this into a
+      // single shift.  We can do this if the bottom bits (which are shifted
+      // out) are never demanded.
+      if (InOp.getOpcode() == ISD::SRL &&
+          isa<ConstantSDNode>(InOp.getOperand(1))) {
+        if (ShAmt && (DemandedMask & ((1ULL << ShAmt)-1)) == 0) {
+          unsigned C1 = cast<ConstantSDNode>(InOp.getOperand(1))->getValue();
+          unsigned Opc = ISD::SHL;
+          int Diff = ShAmt-C1;
+          if (Diff < 0) {
+            Diff = -Diff;
+            Opc = ISD::SRL;
+          }          
+          
+          SDOperand NewSA = 
+            TLO.DAG.getConstant(ShAmt-C1, Op.getOperand(1).getValueType());
+          MVT::ValueType VT = Op.getValueType();
+          return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT,
+                                                   InOp.getOperand(0), NewSA));
+        }
+      }      
+      
+      if (SimplifyDemandedBits(Op.getOperand(0), DemandedMask >> ShAmt,
                                KnownZero, KnownOne, TLO, Depth+1))
         return true;
       KnownZero <<= SA->getValue();
@@ -578,11 +600,33 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
       MVT::ValueType VT = Op.getValueType();
       unsigned ShAmt = SA->getValue();
+      uint64_t TypeMask = MVT::getIntVTBitMask(VT);
+      unsigned VTSize = MVT::getSizeInBits(VT);
+      SDOperand InOp = Op.getOperand(0);
+      
+      // If this is ((X << C1) >>u ShAmt), see if we can simplify this into a
+      // single shift.  We can do this if the top bits (which are shifted out)
+      // are never demanded.
+      if (InOp.getOpcode() == ISD::SHL &&
+          isa<ConstantSDNode>(InOp.getOperand(1))) {
+        if (ShAmt && (DemandedMask & (~0ULL << (VTSize-ShAmt))) == 0) {
+          unsigned C1 = cast<ConstantSDNode>(InOp.getOperand(1))->getValue();
+          unsigned Opc = ISD::SRL;
+          int Diff = ShAmt-C1;
+          if (Diff < 0) {
+            Diff = -Diff;
+            Opc = ISD::SHL;
+          }          
+          
+          SDOperand NewSA =
+            TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType());
+          return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT,
+                                                   InOp.getOperand(0), NewSA));
+        }
+      }      
       
       // Compute the new bits that are at the top now.
-      uint64_t TypeMask = MVT::getIntVTBitMask(VT);
-      if (SimplifyDemandedBits(Op.getOperand(0), 
-                               (DemandedMask << ShAmt) & TypeMask,
+      if (SimplifyDemandedBits(InOp, (DemandedMask << ShAmt) & TypeMask,
                                KnownZero, KnownOne, TLO, Depth+1))
         return true;
       assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); 
@@ -592,7 +636,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
       KnownOne  >>= ShAmt;
 
       uint64_t HighBits = (1ULL << ShAmt)-1;
-      HighBits <<= MVT::getSizeInBits(VT) - ShAmt;
+      HighBits <<= VTSize - ShAmt;
       KnownZero |= HighBits;  // High bits known zero.
     }
     break;
@@ -1871,22 +1915,43 @@ SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op,
   case 'i':    // Simple Integer or Relocatable Constant
   case 'n':    // Simple Integer
   case 's':    // Relocatable Constant
-  case 'X':    // Allows any operand.
-    // These are okay if the operand is either a global variable address or a
-    // simple immediate value.  If we have one of these, map to the TargetXXX
-    // version so that the value itself doesn't get selected.
-    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
+  case 'X': {  // Allows any operand.
+    // These operands are interested in values of the form (GV+C), where C may
+    // be folded in as an offset of GV, or it may be explicitly added.  Also, it
+    // is possible and fine if either GV or C are missing.
+    ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op);
+    GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op);
+    
+    // If we have "(add GV, C)", pull out GV/C
+    if (Op.getOpcode() == ISD::ADD) {
+      C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+      GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
+      if (C == 0 || GA == 0) {
+        C = dyn_cast<ConstantSDNode>(Op.getOperand(0));
+        GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(1));
+      }
+      if (C == 0 || GA == 0)
+        C = 0, GA = 0;
+    }
+    
+    // If we find a valid operand, map to the TargetXXX version so that the
+    // value itself doesn't get selected.
+    if (GA) {   // Either &GV   or   &GV+C
+      if (ConstraintLetter != 'n') {
+        int64_t Offs = GA->getOffset();
+        if (C) Offs += C->getValue();
+        return DAG.getTargetGlobalAddress(GA->getGlobal(), Op.getValueType(),
+                                          Offs);
+      }
+    }
+    if (C) {   // just C, no GV.
       // Simple constants are not allowed for 's'.
       if (ConstraintLetter != 's')
         return DAG.getTargetConstant(C->getValue(), Op.getValueType());
     }
-    if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) {
-      if (ConstraintLetter != 'n')
-        return DAG.getTargetGlobalAddress(GA->getGlobal(), Op.getValueType(),
-                                          GA->getOffset());
-    }
     break;
   }
+  }
   return SDOperand(0,0);
 }
 
@@ -1974,25 +2039,6 @@ bool TargetLowering::isLegalAddressingMode(const AddrMode &AM,
   return true;
 }
 
-/// isLegalAddressImmediate - Return true if the integer value can be used as
-/// the offset of the target addressing mode for load / store of the given
-/// type.
-bool TargetLowering::isLegalAddressImmediate(int64_t V, const Type *Ty) const {
-  return false;
-}
-
-/// isLegalAddressImmediate - Return true if the GlobalValue can be used as
-/// the offset of the target addressing mode.
-bool TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const {
-  return false;
-}
-
-/// isLegalAddressScale - Return true if the integer value can be used as the
-/// scale of the target addressing mode for load / store of the given type.
-bool TargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const {
-  return false;
-}
-
 // Magic for divide replacement
 
 struct ms {
@@ -2172,7 +2218,7 @@ static mu magicu64(uint64_t d)
 /// multiplying by a magic number.  See:
 /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
 SDOperand TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, 
-                                   std::vector<SDNode*>* Created) const {
+                                    std::vector<SDNode*>* Created) const {
   MVT::ValueType VT = N->getValueType(0);
   
   // Check to see if we can do this.
@@ -2220,7 +2266,7 @@ SDOperand TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
 /// multiplying by a magic number.  See:
 /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
 SDOperand TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
-                                   std::vector<SDNode*>* Created) const {
+                                    std::vector<SDNode*>* Created) const {
   MVT::ValueType VT = N->getValueType(0);
   
   // Check to see if we can do this.