Can't fold the bit_convert is the store is a truncating store.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / TargetLowering.cpp
index faa50295690f4321737cfdfc3e3efff7f881590e..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;
@@ -1828,28 +1872,36 @@ PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
 //===----------------------------------------------------------------------===//
 
 TargetLowering::ConstraintType
-TargetLowering::getConstraintType(char ConstraintLetter) const {
+TargetLowering::getConstraintType(const std::string &Constraint) const {
   // FIXME: lots more standard ones to handle.
-  switch (ConstraintLetter) {
-  default: return C_Unknown;
-  case 'r': return C_RegisterClass;
-  case 'm':    // memory
-  case 'o':    // offsetable
-  case 'V':    // not offsetable
-    return C_Memory;
-  case 'i':    // Simple Integer or Relocatable Constant
-  case 'n':    // Simple Integer
-  case 's':    // Relocatable Constant
-  case 'I':    // Target registers.
-  case 'J':
-  case 'K':
-  case 'L':
-  case 'M':
-  case 'N':
-  case 'O':
-  case 'P':
-    return C_Other;
+  if (Constraint.size() == 1) {
+    switch (Constraint[0]) {
+    default: break;
+    case 'r': return C_RegisterClass;
+    case 'm':    // memory
+    case 'o':    // offsetable
+    case 'V':    // not offsetable
+      return C_Memory;
+    case 'i':    // Simple Integer or Relocatable Constant
+    case 'n':    // Simple Integer
+    case 's':    // Relocatable Constant
+    case 'X':    // Allow ANY value.
+    case 'I':    // Target registers.
+    case 'J':
+    case 'K':
+    case 'L':
+    case 'M':
+    case 'N':
+    case 'O':
+    case 'P':
+      return C_Other;
+    }
   }
+  
+  if (Constraint.size() > 1 && Constraint[0] == '{' && 
+      Constraint[Constraint.size()-1] == '}')
+    return C_Register;
+  return C_Unknown;
 }
 
 /// isOperandValidForConstraint - Return the specified operand (possibly
@@ -1863,21 +1915,43 @@ SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op,
   case 'i':    // Simple Integer or Relocatable Constant
   case 'n':    // Simple Integer
   case 's':    // Relocatable Constant
-    // 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);
 }
 
@@ -1931,26 +2005,40 @@ getRegForInlineAsmConstraint(const std::string &Constraint,
 //  Loop Strength Reduction hooks
 //===----------------------------------------------------------------------===//
 
-/// 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;
-}
+/// isLegalAddressingMode - Return true if the addressing mode represented
+/// by AM is legal for this target, for a load/store of the specified type.
+bool TargetLowering::isLegalAddressingMode(const AddrMode &AM, 
+                                           const Type *Ty) const {
+  // The default implementation of this implements a conservative RISCy, r+r and
+  // r+i addr mode.
 
-/// 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;
+  // Allows a sign-extended 16-bit immediate field.
+  if (AM.BaseOffs <= -(1LL << 16) || AM.BaseOffs >= (1LL << 16)-1)
+    return false;
+  
+  // No global is ever allowed as a base.
+  if (AM.BaseGV)
+    return false;
+  
+  // Only support r+r, 
+  switch (AM.Scale) {
+  case 0:  // "r+i" or just "i", depending on HasBaseReg.
+    break;
+  case 1:
+    if (AM.HasBaseReg && AM.BaseOffs)  // "r+r+i" is not allowed.
+      return false;
+    // Otherwise we have r+r or r+i.
+    break;
+  case 2:
+    if (AM.HasBaseReg || AM.BaseOffs)  // 2*r+r  or  2*r+i is not allowed.
+      return false;
+    // Allow 2*r as r+r.
+    break;
+  }
+  
+  return true;
 }
 
-
 // Magic for divide replacement
 
 struct ms {
@@ -2130,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.
@@ -2178,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.
@@ -2214,25 +2302,3 @@ SDOperand TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
                        DAG.getConstant(magics.s-1, getShiftAmountTy()));
   }
 }
-
-MVT::ValueType TargetLowering::getValueType(const Type *Ty) const {
-  switch (Ty->getTypeID()) {
-  default: assert(0 && "Unknown type!");
-  case Type::VoidTyID:    return MVT::isVoid;
-  case Type::IntegerTyID:
-    switch (cast<IntegerType>(Ty)->getBitWidth()) {
-      default: assert(0 && "Invalid width for value type");
-      case 1:    return MVT::i1;
-      case 8:    return MVT::i8;
-      case 16:   return MVT::i16;
-      case 32:   return MVT::i32;
-      case 64:   return MVT::i64;
-      case 128:  return MVT::i128;
-    }
-    break;
-  case Type::FloatTyID:   return MVT::f32;
-  case Type::DoubleTyID:  return MVT::f64;
-  case Type::PointerTyID: return PointerTy;
-  case Type::VectorTyID:  return MVT::Vector;
-  }
-}