Add sub/mul overflow intrinsics. This currently doesn't have a
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGBuild.cpp
index dc99879490120fd2e131b0f412cfa18be2576f02..5d81d224c88506d898e8ed901e9b9f9daf5faa4f 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/Instructions.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
 #include "llvm/CodeGen/FastISel.h"
 #include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/GCMetadata.h"
@@ -34,6 +35,7 @@
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetData.h"
@@ -390,14 +392,17 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
         ValueVT : MVT::getIntegerVT(RoundBits);
       SDValue Lo, Hi;
 
+      MVT HalfVT = ValueVT.isInteger() ?
+        MVT::getIntegerVT(RoundBits/2) :
+        MVT::getFloatingPointVT(RoundBits/2);
+
       if (RoundParts > 2) {
-        MVT HalfVT = MVT::getIntegerVT(RoundBits/2);
         Lo = getCopyFromParts(DAG, Parts, RoundParts/2, PartVT, HalfVT);
         Hi = getCopyFromParts(DAG, Parts+RoundParts/2, RoundParts/2,
                               PartVT, HalfVT);
       } else {
-        Lo = Parts[0];
-        Hi = Parts[1];
+        Lo = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[0]);
+        Hi = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[1]);
       }
       if (TLI.isBigEndian())
         std::swap(Lo, Hi);
@@ -512,11 +517,8 @@ static SDValue getCopyFromParts(SelectionDAG &DAG,
 /// getCopyToParts - Create a series of nodes that contain the specified value
 /// split into legal parts.  If the parts contain more bits than Val, then, for
 /// integers, ExtendKind can be used to specify how to generate the extra bits.
-static void getCopyToParts(SelectionDAG &DAG,
-                           SDValue Val,
-                           SDValue *Parts,
-                           unsigned NumParts,
-                           MVT PartVT,
+static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
+                           SDValue *Parts, unsigned NumParts, MVT PartVT,
                            ISD::NodeType ExtendKind = ISD::ANY_EXTEND) {
   TargetLowering &TLI = DAG.getTargetLoweringInfo();
   MVT PtrVT = TLI.getPointerTy();
@@ -905,11 +907,13 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
   SmallVector<SDValue, 8> NewValues;
   NewValues.push_back(getControlRoot());
   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {  
-    SDValue RetOp = getValue(I.getOperand(i));
-
     SmallVector<MVT, 4> ValueVTs;
     ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs);
-    for (unsigned j = 0, f = ValueVTs.size(); j != f; ++j) {
+    unsigned NumValues = ValueVTs.size();
+    if (NumValues == 0) continue;
+
+    SDValue RetOp = getValue(I.getOperand(i));
+    for (unsigned j = 0, f = NumValues; j != f; ++j) {
       MVT VT = ValueVTs[j];
 
       // FIXME: C calling convention requires the return type to be promoted to
@@ -1051,32 +1055,26 @@ static ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred) {
   }
 }
 
-/// FindMergedConditions - If Cond is an expression like 
-void SelectionDAGLowering::FindMergedConditions(Value *Cond,
-                                                MachineBasicBlock *TBB,
-                                                MachineBasicBlock *FBB,
-                                                MachineBasicBlock *CurBB,
-                                                unsigned Opc) {
-  // If this node is not part of the or/and tree, emit it as a branch.
-  Instruction *BOp = dyn_cast<Instruction>(Cond);
-
-  if (!BOp || !(isa<BinaryOperator>(BOp) || isa<CmpInst>(BOp)) || 
-      (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
-      BOp->getParent() != CurBB->getBasicBlock() ||
-      !InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) ||
-      !InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) {
-    const BasicBlock *BB = CurBB->getBasicBlock();
-    
-    // If the leaf of the tree is a comparison, merge the condition into 
-    // the caseblock.
-    if (isa<CmpInst>(Cond) &&
-        // The operands of the cmp have to be in this block.  We don't know
-        // how to export them from some other block.  If this is the first block
-        // of the sequence, no exporting is needed.
-        (CurBB == CurMBB ||
-         (isExportableFromCurrentBlock(BOp->getOperand(0), BB) &&
-          isExportableFromCurrentBlock(BOp->getOperand(1), BB)))) {
-      BOp = cast<Instruction>(Cond);
+/// EmitBranchForMergedCondition - Helper method for FindMergedConditions.
+/// This function emits a branch and is used at the leaves of an OR or an
+/// AND operator tree.
+///
+void
+SelectionDAGLowering::EmitBranchForMergedCondition(Value *Cond,
+                                                   MachineBasicBlock *TBB,
+                                                   MachineBasicBlock *FBB,
+                                                   MachineBasicBlock *CurBB) {
+  const BasicBlock *BB = CurBB->getBasicBlock();
+
+  // If the leaf of the tree is a comparison, merge the condition into
+  // the caseblock.
+  if (CmpInst *BOp = dyn_cast<CmpInst>(Cond)) {
+    // The operands of the cmp have to be in this block.  We don't know
+    // how to export them from some other block.  If this is the first block
+    // of the sequence, no exporting is needed.
+    if (CurBB == CurMBB ||
+        (isExportableFromCurrentBlock(BOp->getOperand(0), BB) &&
+         isExportableFromCurrentBlock(BOp->getOperand(1), BB))) {
       ISD::CondCode Condition;
       if (ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
         Condition = getICmpCondCode(IC->getPredicate());
@@ -1086,21 +1084,37 @@ void SelectionDAGLowering::FindMergedConditions(Value *Cond,
         Condition = ISD::SETEQ; // silence warning.
         assert(0 && "Unknown compare instruction");
       }
-      
-      CaseBlock CB(Condition, BOp->getOperand(0), 
+
+      CaseBlock CB(Condition, BOp->getOperand(0),
                    BOp->getOperand(1), NULL, TBB, FBB, CurBB);
       SwitchCases.push_back(CB);
       return;
     }
-    
-    // Create a CaseBlock record representing this branch.
-    CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(),
-                 NULL, TBB, FBB, CurBB);
-    SwitchCases.push_back(CB);
+  }
+
+  // Create a CaseBlock record representing this branch.
+  CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(),
+               NULL, TBB, FBB, CurBB);
+  SwitchCases.push_back(CB);
+}
+
+/// FindMergedConditions - If Cond is an expression like 
+void SelectionDAGLowering::FindMergedConditions(Value *Cond,
+                                                MachineBasicBlock *TBB,
+                                                MachineBasicBlock *FBB,
+                                                MachineBasicBlock *CurBB,
+                                                unsigned Opc) {
+  // If this node is not part of the or/and tree, emit it as a branch.
+  Instruction *BOp = dyn_cast<Instruction>(Cond);
+  if (!BOp || !(isa<BinaryOperator>(BOp) || isa<CmpInst>(BOp)) || 
+      (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
+      BOp->getParent() != CurBB->getBasicBlock() ||
+      !InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) ||
+      !InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) {
+    EmitBranchForMergedCondition(Cond, TBB, FBB, CurBB);
     return;
   }
   
-  
   //  Create TmpBB after CurBB.
   MachineFunction::iterator BBI = CurBB;
   MachineFunction &MF = DAG.getMachineFunction();
@@ -2130,11 +2144,24 @@ void SelectionDAGLowering::visitVFCmp(User &I) {
 }
 
 void SelectionDAGLowering::visitSelect(User &I) {
-  SDValue Cond     = getValue(I.getOperand(0));
-  SDValue TrueVal  = getValue(I.getOperand(1));
-  SDValue FalseVal = getValue(I.getOperand(2));
-  setValue(&I, DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond,
-                           TrueVal, FalseVal));
+  SmallVector<MVT, 4> ValueVTs;
+  ComputeValueVTs(TLI, I.getType(), ValueVTs);
+  unsigned NumValues = ValueVTs.size();
+  if (NumValues != 0) {
+    SmallVector<SDValue, 4> Values(NumValues);
+    SDValue Cond     = getValue(I.getOperand(0));
+    SDValue TrueVal  = getValue(I.getOperand(1));
+    SDValue FalseVal = getValue(I.getOperand(2));
+
+    for (unsigned i = 0; i != NumValues; ++i)
+      Values[i] = DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond,
+                              SDValue(TrueVal.getNode(), TrueVal.getResNo() + i),
+                              SDValue(FalseVal.getNode(), FalseVal.getResNo() + i));
+
+    setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                             DAG.getVTList(&ValueVTs[0], NumValues),
+                             &Values[0], NumValues));
+  }
 }
 
 
@@ -2197,7 +2224,7 @@ void SelectionDAGLowering::visitUIToFP(User &I) {
 }
 
 void SelectionDAGLowering::visitSIToFP(User &I){ 
-  // UIToFP is never a no-op cast, no need to check
+  // SIToFP is never a no-op cast, no need to check
   SDValue N = getValue(I.getOperand(0));
   MVT DestVT = TLI.getValueType(I.getType());
   setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N));
@@ -2262,14 +2289,208 @@ void SelectionDAGLowering::visitExtractElement(User &I) {
                            TLI.getValueType(I.getType()), InVec, InIdx));
 }
 
+
+// Utility for visitShuffleVector - Returns true if the mask is mask starting
+// from SIndx and increasing to the element length (undefs are allowed).
+static bool SequentialMask(SDValue Mask, unsigned SIndx) {
+  unsigned MaskNumElts = Mask.getNumOperands();
+  for (unsigned i = 0; i != MaskNumElts; ++i) {
+    if (Mask.getOperand(i).getOpcode() != ISD::UNDEF) {
+      unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getZExtValue();
+      if (Idx != i + SIndx)
+        return false;
+    }
+  }
+  return true;
+}
+
 void SelectionDAGLowering::visitShuffleVector(User &I) {
-  SDValue V1   = getValue(I.getOperand(0));
-  SDValue V2   = getValue(I.getOperand(1));
+  SDValue Src1 = getValue(I.getOperand(0));
+  SDValue Src2 = getValue(I.getOperand(1));
   SDValue Mask = getValue(I.getOperand(2));
 
-  setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE,
-                           TLI.getValueType(I.getType()),
-                           V1, V2, Mask));
+  MVT VT = TLI.getValueType(I.getType());
+  MVT SrcVT = Src1.getValueType();
+  int MaskNumElts = Mask.getNumOperands();
+  int SrcNumElts = SrcVT.getVectorNumElements();
+
+  if (SrcNumElts == MaskNumElts) {
+    setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
+    return;
+  }
+
+  // Normalize the shuffle vector since mask and vector length don't match.
+  MVT MaskEltVT = Mask.getValueType().getVectorElementType();
+
+  if (SrcNumElts < MaskNumElts && MaskNumElts % SrcNumElts == 0) {
+    // Mask is longer than the source vectors and is a multiple of the source
+    // vectors.  We can use concatenate vector to make the mask and vectors
+    // lengths match.
+    if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) {
+      // The shuffle is concatenating two vectors together.
+      setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Src1, Src2));
+      return;
+    }
+
+    // Pad both vectors with undefs to make them the same length as the mask.
+    unsigned NumConcat = MaskNumElts / SrcNumElts;
+    SDValue UndefVal = DAG.getNode(ISD::UNDEF, SrcVT);
+
+    SDValue* MOps1 = new SDValue[NumConcat];
+    SDValue* MOps2 = new SDValue[NumConcat];
+    MOps1[0] = Src1;
+    MOps2[0] = Src2;
+    for (unsigned i = 1; i != NumConcat; ++i) {
+      MOps1[i] = UndefVal;
+      MOps2[i] = UndefVal;
+    }
+    Src1 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps1, NumConcat);
+    Src2 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps2, NumConcat);
+
+    delete [] MOps1;
+    delete [] MOps2;
+
+    // Readjust mask for new input vector length.
+    SmallVector<SDValue, 8> MappedOps;
+    for (int i = 0; i != MaskNumElts; ++i) {
+      if (Mask.getOperand(i).getOpcode() == ISD::UNDEF) {
+        MappedOps.push_back(Mask.getOperand(i));
+      } else {
+        int Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getZExtValue();
+        if (Idx < SrcNumElts)
+          MappedOps.push_back(DAG.getConstant(Idx, MaskEltVT));
+        else
+          MappedOps.push_back(DAG.getConstant(Idx + MaskNumElts - SrcNumElts,
+                                              MaskEltVT));
+      }
+    }
+    Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
+                       &MappedOps[0], MappedOps.size());
+
+    setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
+    return;
+  }
+
+  if (SrcNumElts > MaskNumElts) {
+    // Resulting vector is shorter than the incoming vector.
+    if (SrcNumElts == MaskNumElts && SequentialMask(Mask,0)) {
+      // Shuffle extracts 1st vector.
+      setValue(&I, Src1);
+      return;
+    }
+
+    if (SrcNumElts == MaskNumElts && SequentialMask(Mask,MaskNumElts)) {
+      // Shuffle extracts 2nd vector.
+      setValue(&I, Src2);
+      return;
+    }
+
+    // Analyze the access pattern of the vector to see if we can extract
+    // two subvectors and do the shuffle. The analysis is done by calculating
+    // the range of elements the mask access on both vectors.
+    int MinRange[2] = { SrcNumElts+1, SrcNumElts+1};
+    int MaxRange[2] = {-1, -1};
+
+    for (int i = 0; i != MaskNumElts; ++i) {
+      SDValue Arg = Mask.getOperand(i);
+      if (Arg.getOpcode() != ISD::UNDEF) {
+        assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
+        int Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
+        int Input = 0;
+        if (Idx >= SrcNumElts) {
+          Input = 1;
+          Idx -= SrcNumElts;
+        }
+        if (Idx > MaxRange[Input])
+          MaxRange[Input] = Idx;
+        if (Idx < MinRange[Input])
+          MinRange[Input] = Idx;
+      }
+    }
+
+    // Check if the access is smaller than the vector size and can we find
+    // a reasonable extract index.
+    int RangeUse[2] = { 2, 2 };  // 0 = Unused, 1 = Extract, 2 = Can not Extract.
+    int StartIdx[2];  // StartIdx to extract from
+    for (int Input=0; Input < 2; ++Input) {
+      if (MinRange[Input] == SrcNumElts+1 && MaxRange[Input] == -1) {
+        RangeUse[Input] = 0; // Unused
+        StartIdx[Input] = 0;
+      } else if (MaxRange[Input] - MinRange[Input] < MaskNumElts) {
+        // Fits within range but we should see if we can find a good
+        // start index that is a multiple of the mask length.
+        if (MaxRange[Input] < MaskNumElts) {
+          RangeUse[Input] = 1; // Extract from beginning of the vector
+          StartIdx[Input] = 0;
+        } else {
+          StartIdx[Input] = (MinRange[Input]/MaskNumElts)*MaskNumElts;
+          if (MaxRange[Input] - StartIdx[Input] < MaskNumElts &&
+              StartIdx[Input] + MaskNumElts < SrcNumElts) 
+            RangeUse[Input] = 1; // Extract from a multiple of the mask length.
+        }
+      }
+    }
+
+    if (RangeUse[0] == 0 && RangeUse[0] == 0) {
+      setValue(&I, DAG.getNode(ISD::UNDEF, VT));  // Vectors are not used.
+      return;
+    }
+    else if (RangeUse[0] < 2 && RangeUse[1] < 2) {
+      // Extract appropriate subvector and generate a vector shuffle
+      for (int Input=0; Input < 2; ++Input) {
+        SDValue& Src = Input == 0 ? Src1 : Src2;
+        if (RangeUse[Input] == 0) {
+          Src = DAG.getNode(ISD::UNDEF, VT);
+        } else {
+          Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, Src,
+                            DAG.getIntPtrConstant(StartIdx[Input]));
+        }
+      }
+      // Calculate new mask.
+      SmallVector<SDValue, 8> MappedOps;
+      for (int i = 0; i != MaskNumElts; ++i) {
+        SDValue Arg = Mask.getOperand(i);
+        if (Arg.getOpcode() == ISD::UNDEF) {
+          MappedOps.push_back(Arg);
+        } else {
+          int Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
+          if (Idx < SrcNumElts)
+            MappedOps.push_back(DAG.getConstant(Idx - StartIdx[0], MaskEltVT));
+          else {
+            Idx = Idx - SrcNumElts - StartIdx[1] + MaskNumElts;
+            MappedOps.push_back(DAG.getConstant(Idx, MaskEltVT));
+          } 
+        }
+      }
+      Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
+                         &MappedOps[0], MappedOps.size());
+      setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
+      return;
+    }
+  }
+
+  // We can't use either concat vectors or extract subvectors so fall back to
+  // replacing the shuffle with extract and build vector.
+  // to insert and build vector.
+  MVT EltVT = VT.getVectorElementType();
+  MVT PtrVT = TLI.getPointerTy();
+  SmallVector<SDValue,8> Ops;
+  for (int i = 0; i != MaskNumElts; ++i) {
+    SDValue Arg = Mask.getOperand(i);
+    if (Arg.getOpcode() == ISD::UNDEF) {
+      Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+    } else {
+      assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
+      int Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
+      if (Idx < SrcNumElts)
+        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src1,
+                                  DAG.getConstant(Idx, PtrVT)));
+      else
+        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src2,
+                                  DAG.getConstant(Idx - SrcNumElts, PtrVT)));
+    }
+  }
+  setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()));
 }
 
 void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
@@ -2308,8 +2529,9 @@ void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
     Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
                 SDValue(Agg.getNode(), Agg.getResNo() + i);
 
-  setValue(&I, DAG.getMergeValues(DAG.getVTList(&AggValueVTs[0], NumAggValues),
-                                  &Values[0], NumAggValues));
+  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                           DAG.getVTList(&AggValueVTs[0], NumAggValues),
+                           &Values[0], NumAggValues));
 }
 
 void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
@@ -2331,11 +2553,14 @@ void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
   // Copy out the selected value(s).
   for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
     Values[i - LinearIndex] =
-      OutOfUndef ? DAG.getNode(ISD::UNDEF, Agg.getNode()->getValueType(Agg.getResNo() + i)) :
-                   SDValue(Agg.getNode(), Agg.getResNo() + i);
-
-  setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValValueVTs[0], NumValValues),
-                                  &Values[0], NumValValues));
+      OutOfUndef ?
+        DAG.getNode(ISD::UNDEF,
+                    Agg.getNode()->getValueType(Agg.getResNo() + i)) :
+        SDValue(Agg.getNode(), Agg.getResNo() + i);
+
+  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                           DAG.getVTList(&ValValueVTs[0], NumValValues),
+                           &Values[0], NumValValues));
 }
 
 
@@ -2499,8 +2724,9 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
       PendingLoads.push_back(Chain);
   }
 
-  setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], NumValues),
-                                  &Values[0], NumValues));
+  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
+                           DAG.getVTList(&ValueVTs[0], NumValues),
+                           &Values[0], NumValues));
 }
 
 
@@ -2553,9 +2779,14 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
       Ops.push_back(getRoot());
     }
   }
-  
-  // Add the intrinsic ID as an integer operand.
-  Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy()));
+
+  // Info is set by getTgtMemInstrinsic
+  TargetLowering::IntrinsicInfo Info;
+  bool IsTgtIntrinsic = TLI.getTgtMemIntrinsic(Info, I, Intrinsic);
+
+  // Add the intrinsic ID as an integer operand if it's not a target intrinsic.  
+  if (!IsTgtIntrinsic)
+    Ops.push_back(DAG.getConstant(Intrinsic, TLI.getPointerTy()));
 
   // Add all operands of the call to the operand list.
   for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
@@ -2586,7 +2817,15 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
 
   // Create the node.
   SDValue Result;
-  if (!HasChain)
+  if (IsTgtIntrinsic) {
+    // This is target intrinsic that touches memory
+    Result = DAG.getMemIntrinsicNode(Info.opc, VTList, VTs.size(),
+                                     &Ops[0], Ops.size(),
+                                     Info.memVT, Info.ptrVal, Info.offset,
+                                     Info.align, Info.vol,
+                                     Info.readMem, Info.writeMem);
+  }
+  else if (!HasChain)
     Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VTList, VTs.size(),
                          &Ops[0], Ops.size());
   else if (I.getType() != Type::VoidTy)
@@ -2729,6 +2968,23 @@ SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
   return 0;
 }
 
+// implVisitAluOverflow - Lower an overflow instrinsics
+const char *
+SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
+    SDValue Op1 = getValue(I.getOperand(1));
+    SDValue Op2 = getValue(I.getOperand(2));
+
+    MVT ValueVTs[] = { Op1.getValueType(), MVT::i1 };
+    SDValue Ops[] = { Op1, Op2 };
+
+    SDValue Result =
+      DAG.getNode(Op,
+                  DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
+
+    setValue(&I, Result);
+    return 0;
+  }
+
 /// visitExp - Lower an exp intrinsic. Handles the special sequences for
 /// limited-precision mode.
 void
@@ -3069,6 +3325,7 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
 void
 SelectionDAGLowering::visitLog10(CallInst &I) {
   SDValue result;
+
   if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
       LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
     SDValue Op = getValue(I.getOperand(1));
@@ -3428,8 +3685,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
   case Intrinsic::longjmp:
     return "_longjmp"+!TLI.usesUnderscoreLongJmp();
     break;
-  case Intrinsic::memcpy_i32:
-  case Intrinsic::memcpy_i64: {
+  case Intrinsic::memcpy: {
     SDValue Op1 = getValue(I.getOperand(1));
     SDValue Op2 = getValue(I.getOperand(2));
     SDValue Op3 = getValue(I.getOperand(3));
@@ -3438,8 +3694,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
                               I.getOperand(1), 0, I.getOperand(2), 0));
     return 0;
   }
-  case Intrinsic::memset_i32:
-  case Intrinsic::memset_i64: {
+  case Intrinsic::memset: {
     SDValue Op1 = getValue(I.getOperand(1));
     SDValue Op2 = getValue(I.getOperand(2));
     SDValue Op3 = getValue(I.getOperand(3));
@@ -3448,8 +3703,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
                               I.getOperand(1), 0));
     return 0;
   }
-  case Intrinsic::memmove_i32:
-  case Intrinsic::memmove_i64: {
+  case Intrinsic::memmove: {
     SDValue Op1 = getValue(I.getOperand(1));
     SDValue Op2 = getValue(I.getOperand(2));
     SDValue Op3 = getValue(I.getOperand(3));
@@ -3518,9 +3772,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
       SubprogramDesc *Subprogram = cast<SubprogramDesc>(DD);
       const CompileUnitDesc *CompileUnit = Subprogram->getFile();
       unsigned SrcFile = MMI->RecordSource(CompileUnit);
-      // Record the source line but does create a label. It will be emitted
-      // at asm emission time.
-      MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile);
+      // Record the source line but does not create a label for the normal
+      // function start. It will be emitted at asm emission time. However,
+      // create a label if this is a beginning of inlined function.
+      unsigned LabelID = MMI->RecordSourceLine(Subprogram->getLine(), 0, SrcFile);
+      if (MMI->getSourceLines().size() != 1)
+        DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
     }
 
     return 0;
@@ -3650,6 +3907,38 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     return 0;
   }
 
+  case Intrinsic::convertff:
+  case Intrinsic::convertfsi:
+  case Intrinsic::convertfui:
+  case Intrinsic::convertsif:
+  case Intrinsic::convertuif:
+  case Intrinsic::convertss:
+  case Intrinsic::convertsu:
+  case Intrinsic::convertus:
+  case Intrinsic::convertuu: {
+    ISD::CvtCode Code = ISD::CVT_INVALID;
+    switch (Intrinsic) {
+    case Intrinsic::convertff:  Code = ISD::CVT_FF; break;
+    case Intrinsic::convertfsi: Code = ISD::CVT_FS; break;
+    case Intrinsic::convertfui: Code = ISD::CVT_FU; break;
+    case Intrinsic::convertsif: Code = ISD::CVT_SF; break;
+    case Intrinsic::convertuif: Code = ISD::CVT_UF; break;
+    case Intrinsic::convertss:  Code = ISD::CVT_SS; break;
+    case Intrinsic::convertsu:  Code = ISD::CVT_SU; break;
+    case Intrinsic::convertus:  Code = ISD::CVT_US; break;
+    case Intrinsic::convertuu:  Code = ISD::CVT_UU; break;
+    }
+    MVT DestVT = TLI.getValueType(I.getType());
+    Value* Op1 = I.getOperand(1);
+    setValue(&I, DAG.getConvertRndSat(DestVT, getValue(Op1),
+                                DAG.getValueType(DestVT),
+                                DAG.getValueType(getValue(Op1).getValueType()),
+                                getValue(I.getOperand(2)),
+                                getValue(I.getOperand(3)),
+                                Code));
+    return 0;
+  }
+
   case Intrinsic::sqrt:
     setValue(&I, DAG.getNode(ISD::FSQRT,
                              getValue(I.getOperand(1)).getValueType(),
@@ -3752,6 +4041,28 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, MVT::Other, getRoot(), Tmp));
     return 0;
   }
+  case Intrinsic::stackprotector: {
+    // Emit code into the DAG to store the stack guard onto the stack.
+    MachineFunction &MF = DAG.getMachineFunction();
+    MachineFrameInfo *MFI = MF.getFrameInfo();
+    MVT PtrTy = TLI.getPointerTy();
+
+    SDValue Src = getValue(I.getOperand(1));   // The guard's value.
+    AllocaInst *Slot = cast<AllocaInst>(I.getOperand(2));
+
+    int FI = FuncInfo.StaticAllocaMap[Slot];
+    MFI->setStackProtectorIndex(FI);
+
+    SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
+
+    // Store the stack protector onto the stack.
+    SDValue Result = DAG.getStore(getRoot(), Src, FIN,
+                                  PseudoSourceValue::getFixedStack(FI),
+                                  0, true);
+    setValue(&I, Result);
+    DAG.setRoot(Result);
+    return 0;
+  }
   case Intrinsic::var_annotation:
     // Discard annotate attributes
     return 0;
@@ -3801,6 +4112,20 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
     DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot()));
     return 0;
   }
+
+  case Intrinsic::uadd_with_overflow:
+    return implVisitAluOverflow(I, ISD::UADDO);
+  case Intrinsic::sadd_with_overflow:
+    return implVisitAluOverflow(I, ISD::SADDO);
+  case Intrinsic::usub_with_overflow:
+    return implVisitAluOverflow(I, ISD::USUBO);
+  case Intrinsic::ssub_with_overflow:
+    return implVisitAluOverflow(I, ISD::SSUBO);
+  case Intrinsic::umul_with_overflow:
+    return implVisitAluOverflow(I, ISD::UMULO);
+  case Intrinsic::smul_with_overflow:
+    return implVisitAluOverflow(I, ISD::SMULO);
+
   case Intrinsic::prefetch: {
     SDValue Ops[4];
     Ops[0] = getRoot();
@@ -4211,13 +4536,13 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
           else if (NumZeroBits >= RegSize-9)
             isSExt = false, FromVT = MVT::i8;  // ASSERT ZEXT 8
           else if (NumSignBits > RegSize-16)
-            isSExt = true, FromVT = MVT::i16;   // ASSERT SEXT 16
+            isSExt = true, FromVT = MVT::i16;  // ASSERT SEXT 16
           else if (NumZeroBits >= RegSize-17)
-            isSExt = false, FromVT = MVT::i16;  // ASSERT ZEXT 16
+            isSExt = false, FromVT = MVT::i16; // ASSERT ZEXT 16
           else if (NumSignBits > RegSize-32)
-            isSExt = true, FromVT = MVT::i32;   // ASSERT SEXT 32
+            isSExt = true, FromVT = MVT::i32;  // ASSERT SEXT 32
           else if (NumZeroBits >= RegSize-33)
-            isSExt = false, FromVT = MVT::i32;  // ASSERT ZEXT 32
+            isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32
           
           if (FromVT != MVT::Other) {
             P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext,
@@ -4236,8 +4561,9 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
     Parts.clear();
   }
 
-  return DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
-                            &Values[0], ValueVTs.size());
+  return DAG.getNode(ISD::MERGE_VALUES,
+                     DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
+                     &Values[0], ValueVTs.size());
 }
 
 /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
@@ -4486,11 +4812,37 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
                                      OpInfo.ConstraintVT);
 
   unsigned NumRegs = 1;
-  if (OpInfo.ConstraintVT != MVT::Other)
+  if (OpInfo.ConstraintVT != MVT::Other) {
+    // If this is a FP input in an integer register (or visa versa) insert a bit
+    // cast of the input value.  More generally, handle any case where the input
+    // value disagrees with the register class we plan to stick this in.
+    if (OpInfo.Type == InlineAsm::isInput &&
+        PhysReg.second && !PhysReg.second->hasType(OpInfo.ConstraintVT)) {
+      // Try to convert to the first MVT that the reg class contains.  If the
+      // types are identical size, use a bitcast to convert (e.g. two differing
+      // vector types).
+      MVT RegVT = *PhysReg.second->vt_begin();
+      if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
+        OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, RegVT,
+                                         OpInfo.CallOperand);
+        OpInfo.ConstraintVT = RegVT;
+      } else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
+        // If the input is a FP value and we want it in FP registers, do a
+        // bitcast to the corresponding integer type.  This turns an f64 value
+        // into i64, which can be passed with two i32 values on a 32-bit
+        // machine.
+        RegVT = MVT::getIntegerVT(OpInfo.ConstraintVT.getSizeInBits());
+        OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, RegVT,
+                                         OpInfo.CallOperand);
+        OpInfo.ConstraintVT = RegVT;
+      }
+    }
+    
     NumRegs = TLI.getNumRegisters(OpInfo.ConstraintVT);
+  }
+  
   MVT RegVT;
   MVT ValueVT = OpInfo.ConstraintVT;
-  
 
   // If this is a constraint for a specific physical register, like {r17},
   // assign it now.
@@ -4963,26 +5315,30 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
   // and set it as the value of the call.
   if (!RetValRegs.Regs.empty()) {
     SDValue Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
-    MVT ResultType = TLI.getValueType(CS.getType());
     
-    // If any of the results of the inline asm is a vector, it may have the
-    // wrong width/num elts.  This can happen for register classes that can
-    // contain multiple different value types.  The preg or vreg allocated may
-    // not have the same VT as was expected.  Convert it to the right type
-    // with bit_convert.
-    // FIXME: Is this sufficient for inline asms with MRVs?
-    if (ResultType != Val.getValueType() && Val.getValueType().isVector()) {
-      Val = DAG.getNode(ISD::BIT_CONVERT, ResultType, Val);
-
-    } else if (ResultType != Val.getValueType() && 
-               ResultType.isInteger() && Val.getValueType().isInteger()) {
-      // If a result value was tied to an input value, the computed result may
-      // have a wider width than the expected result.  Extract the relevant
-      // portion.
-      Val = DAG.getNode(ISD::TRUNCATE, ResultType, Val);
-    }
+    // FIXME: Why don't we do this for inline asms with MRVs?
+    if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) {
+      MVT ResultType = TLI.getValueType(CS.getType());
     
-    assert(ResultType == Val.getValueType() && "Asm result value mismatch!");
+      // If any of the results of the inline asm is a vector, it may have the
+      // wrong width/num elts.  This can happen for register classes that can
+      // contain multiple different value types.  The preg or vreg allocated may
+      // not have the same VT as was expected.  Convert it to the right type
+      // with bit_convert.
+      if (ResultType != Val.getValueType() && Val.getValueType().isVector()) {
+        Val = DAG.getNode(ISD::BIT_CONVERT, ResultType, Val);
+
+      } else if (ResultType != Val.getValueType() && 
+                 ResultType.isInteger() && Val.getValueType().isInteger()) {
+        // If a result value was tied to an input value, the computed result may
+        // have a wider width than the expected result.  Extract the relevant
+        // portion.
+        Val = DAG.getNode(ISD::TRUNCATE, ResultType, Val);
+      }
+    
+      assert(ResultType == Val.getValueType() && "Asm result value mismatch!");
+    }
+
     setValue(CS.getInstruction(), Val);
   }
   
@@ -5342,8 +5698,9 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
                          AssertOp);
       ReturnValues.push_back(ReturnValue);
     }
-    Res = DAG.getMergeValues(DAG.getVTList(&RetTys[0], RetTys.size()),
-                             &ReturnValues[0], ReturnValues.size());
+    Res = DAG.getNode(ISD::MERGE_VALUES,
+                      DAG.getVTList(&RetTys[0], RetTys.size()),
+                      &ReturnValues[0], ReturnValues.size());
   }
 
   return std::make_pair(Res, Chain);