* Introduce a new SelectionDAG::getIntPtrConstant method
  and switch various codegen pieces and the X86 backend over
  to using it.

* Add some comments to SelectionDAGNodes.h

* Introduce a second argument to FP_ROUND, which indicates
  whether the FP_ROUND changes the value of its input. If
  not it is safe to xform things like fp_extend(fp_round(x)) -> x.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46125 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 80ba27f..ad176d4 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -135,6 +135,7 @@
       SDOperand To[] = { Res0, Res1 };
       return CombineTo(N, To, 2, AddTo);
     }
+    
   private:    
     
     /// SimplifyDemandedBits - Check the specified integer node value to see if
@@ -460,10 +461,13 @@
                        GetNegatedExpression(Op.getOperand(1), DAG, Depth+1));
     
   case ISD::FP_EXTEND:
-  case ISD::FP_ROUND:
   case ISD::FSIN:
     return DAG.getNode(Op.getOpcode(), Op.getValueType(),
                        GetNegatedExpression(Op.getOperand(0), DAG, Depth+1));
+  case ISD::FP_ROUND:
+      return DAG.getNode(ISD::FP_ROUND, Op.getValueType(),
+                         GetNegatedExpression(Op.getOperand(0), DAG, Depth+1),
+                         Op.getOperand(1));
   }
 }
 
@@ -3632,12 +3636,13 @@
 
 SDOperand DAGCombiner::visitFP_ROUND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
+  SDOperand N1 = N->getOperand(1);
   ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
   
   // fold (fp_round c1fp) -> c1fp
   if (N0CFP && N0.getValueType() != MVT::ppcf128)
-    return DAG.getNode(ISD::FP_ROUND, VT, N0);
+    return DAG.getNode(ISD::FP_ROUND, VT, N0, N1);
   
   // fold (fp_round (fp_extend x)) -> x
   if (N0.getOpcode() == ISD::FP_EXTEND && VT == N0.getOperand(0).getValueType())
@@ -3645,7 +3650,7 @@
   
   // fold (fp_round (copysign X, Y)) -> (copysign (fp_round X), Y)
   if (N0.getOpcode() == ISD::FCOPYSIGN && N0.Val->hasOneUse()) {
-    SDOperand Tmp = DAG.getNode(ISD::FP_ROUND, VT, N0.getOperand(0));
+    SDOperand Tmp = DAG.getNode(ISD::FP_ROUND, VT, N0.getOperand(0), N1);
     AddToWorkList(Tmp.Val);
     return DAG.getNode(ISD::FCOPYSIGN, VT, Tmp, N0.getOperand(1));
   }
@@ -3675,12 +3680,22 @@
   // If this is fp_round(fpextend), don't fold it, allow ourselves to be folded.
   if (N->hasOneUse() && (*N->use_begin())->getOpcode() == ISD::FP_ROUND)
     return SDOperand();
-  
+
   // fold (fp_extend c1fp) -> c1fp
   if (N0CFP && VT != MVT::ppcf128)
     return DAG.getNode(ISD::FP_EXTEND, VT, N0);
-  
-  // fold (fpext (load x)) -> (fpext (fpround (extload x)))
+
+  // Turn fp_extend(fp_round(X, 1)) -> x since the fp_round doesn't affect the
+  // value of X.
+  if (N0.getOpcode() == ISD::FP_ROUND && N0.Val->getConstantOperandVal(1) == 1){
+    SDOperand In = N0.getOperand(0);
+    if (In.getValueType() == VT) return In;
+    if (VT < In.getValueType())
+      return DAG.getNode(ISD::FP_ROUND, VT, In, N0.getOperand(1));
+    return DAG.getNode(ISD::FP_EXTEND, VT, In);
+  }
+      
+  // fold (fpext (load x)) -> (fpext (fptrunc (extload x)))
   if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() &&
       (!AfterLegalize||TLI.isLoadXLegal(ISD::EXTLOAD, N0.getValueType()))) {
     LoadSDNode *LN0 = cast<LoadSDNode>(N0);
@@ -3691,7 +3706,8 @@
                                        LN0->isVolatile(), 
                                        LN0->getAlignment());
     CombineTo(N, ExtLoad);
-    CombineTo(N0.Val, DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad),
+    CombineTo(N0.Val, DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad,
+                                  DAG.getIntPtrConstant(1)),
               ExtLoad.getValue(1));
     return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
   }
@@ -4435,13 +4451,11 @@
 
       // Otherwise, use InIdx + VecSize
       unsigned Idx = cast<ConstantSDNode>(Extract.getOperand(1))->getValue();
-      BuildVecIndices.push_back(DAG.getConstant(Idx+NumInScalars,
-                                                TLI.getPointerTy()));
+      BuildVecIndices.push_back(DAG.getIntPtrConstant(Idx+NumInScalars));
     }
     
     // Add count and size info.
-    MVT::ValueType BuildVecVT =
-      MVT::getVectorType(TLI.getPointerTy(), NumElts);
+    MVT::ValueType BuildVecVT = MVT::getVectorType(TLI.getPointerTy(), NumElts);
     
     // Return the new VECTOR_SHUFFLE node.
     SDOperand Ops[5];
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index e659263..18d3a6d 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -220,10 +220,6 @@
 
   SDOperand ExpandEXTRACT_SUBVECTOR(SDOperand Op);
   SDOperand ExpandEXTRACT_VECTOR_ELT(SDOperand Op);
-  
-  SDOperand getIntPtrConstant(uint64_t Val) {
-    return DAG.getConstant(Val, TLI.getPointerTy());
-  }
 };
 }
 
@@ -2123,7 +2119,7 @@
             Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(),
                               SVOffset, isVolatile, Alignment);
             Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
-                               getIntPtrConstant(4));
+                               DAG.getIntPtrConstant(4));
             Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
                               isVolatile, MinAlign(Alignment, 4U));
 
@@ -2186,8 +2182,9 @@
         if (MVT::isVector(ST->getValue().getValueType())) {
           SDNode *InVal = ST->getValue().Val;
           int InIx = ST->getValue().ResNo;
-          unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
-          MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
+          MVT::ValueType InVT = InVal->getValueType(InIx);
+          unsigned NumElems = MVT::getVectorNumElements(InVT);
+          MVT::ValueType EVT = MVT::getVectorElementType(InVT);
 
           // Figure out if there is a simple type corresponding to this Vector
           // type.  If so, convert to the vector type.
@@ -2231,7 +2228,7 @@
         }
 
         Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
-                           getIntPtrConstant(IncrementSize));
+                           DAG.getIntPtrConstant(IncrementSize));
         assert(isTypeLegal(Tmp2.getValueType()) &&
                "Pointers must be legal!");
         SVOffset += IncrementSize;
@@ -2429,7 +2426,11 @@
       Tmp3 = DAG.getNode(ExtOp, NVT, Tmp3);
       // Perform the larger operation, then round down.
       Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2,Tmp3);
-      Result = DAG.getNode(TruncOp, Node->getValueType(0), Result);
+      if (TruncOp != ISD::FP_ROUND)
+        Result = DAG.getNode(TruncOp, Node->getValueType(0), Result);
+      else
+        Result = DAG.getNode(TruncOp, Node->getValueType(0), Result,
+                             DAG.getIntPtrConstant(0));
       break;
     }
     }
@@ -3496,13 +3497,13 @@
       MVT::ValueType OVT = Node->getOperand(0).getValueType();
       // Convert ppcf128 to i32
       if (OVT == MVT::ppcf128 && VT == MVT::i32) {
-        if (Node->getOpcode()==ISD::FP_TO_SINT)
-          Result = DAG.getNode(ISD::FP_TO_SINT, VT,
-                             DAG.getNode(ISD::FP_ROUND, MVT::f64,
-                                         (DAG.getNode(ISD::FP_ROUND_INREG, 
-                                          MVT::ppcf128, Node->getOperand(0),
-                                          DAG.getValueType(MVT::f64)))));
-        else {
+        if (Node->getOpcode() == ISD::FP_TO_SINT) {
+          Result = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128, 
+                               Node->getOperand(0), DAG.getValueType(MVT::f64));
+          Result = DAG.getNode(ISD::FP_ROUND, MVT::f64, Result, 
+                               DAG.getIntPtrConstant(1));
+          Result = DAG.getNode(ISD::FP_TO_SINT, VT, Result);
+        } else {
           const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
           APFloat apf = APFloat(APInt(128, 2, TwoE31));
           Tmp2 = DAG.getConstantFP(apf, OVT);
@@ -3573,14 +3574,13 @@
     break;
 
   case ISD::FP_EXTEND: {
-      MVT::ValueType DstVT = Op.getValueType();
-      MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
-      if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
-        // The only other way we can lower this is to turn it into a STORE,
-        // LOAD pair, targetting a temporary location (a stack slot).
-        Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT);
-        break;
-      }
+    MVT::ValueType DstVT = Op.getValueType();
+    MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
+    if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
+      // The only other way we can lower this is to turn it into a STORE,
+      // LOAD pair, targetting a temporary location (a stack slot).
+      Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT);
+      break;
     }
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Expand: assert(0 && "Shouldn't need to expand other operators here!");
@@ -3594,35 +3594,37 @@
       break;
     }
     break;
+  }
   case ISD::FP_ROUND: {
-      MVT::ValueType DstVT = Op.getValueType();
-      MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
-      if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
-        if (SrcVT == MVT::ppcf128) {
-          SDOperand Lo, Hi;
-          ExpandOp(Node->getOperand(0), Lo, Hi);
-          Result = DAG.getNode(ISD::FP_ROUND, DstVT, Hi);
-          break;
-        } else {
-          // The only other way we can lower this is to turn it into a STORE,
-          // LOAD pair, targetting a temporary location (a stack slot).
-          Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT);
-          break;
-        }
+    MVT::ValueType DstVT = Op.getValueType();
+    MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
+    if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
+      if (SrcVT == MVT::ppcf128) {
+        SDOperand Lo, Hi;
+        ExpandOp(Node->getOperand(0), Lo, Hi);
+        // Round it the rest of the way (e.g. to f32) if needed.
+        Result = DAG.getNode(ISD::FP_ROUND, DstVT, Hi, Op.getOperand(1));
+        break;
       }
+      // The only other way we can lower this is to turn it into a STORE,
+      // LOAD pair, targetting a temporary location (a stack slot).
+      Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT);
+      break;
     }
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Expand: assert(0 && "Shouldn't need to expand other operators here!");
     case Legal:
       Tmp1 = LegalizeOp(Node->getOperand(0));
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
       break;
     case Promote:
       Tmp1 = PromoteOp(Node->getOperand(0));
-      Result = DAG.getNode(ISD::FP_ROUND, Op.getValueType(), Tmp1);
+      Result = DAG.getNode(ISD::FP_ROUND, Op.getValueType(), Tmp1,
+                           Node->getOperand(1));
       break;
     }
     break;
+  }
   case ISD::ANY_EXTEND:
   case ISD::ZERO_EXTEND:
   case ISD::SIGN_EXTEND:
@@ -3869,13 +3871,18 @@
     case Expand: assert(0 && "BUG: Cannot expand FP regs!");
     case Promote:  assert(0 && "Unreachable with 2 FP types!");
     case Legal:
-      // Input is legal?  Do an FP_ROUND_INREG.
-      Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0),
-                           DAG.getValueType(VT));
+      if (Node->getConstantOperandVal(1) == 0) {
+        // Input is legal?  Do an FP_ROUND_INREG.
+        Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0),
+                             DAG.getValueType(VT));
+      } else {
+        // Just remove the truncate, it isn't affecting the value.
+        Result = DAG.getNode(ISD::FP_ROUND, NVT, Node->getOperand(0), 
+                             Node->getOperand(1));
+      }
       break;
     }
     break;
-
   case ISD::SINT_TO_FP:
   case ISD::UINT_TO_FP:
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
@@ -4028,24 +4035,14 @@
   case ISD::FCOPYSIGN:
     // These operators require that their input be fp extended.
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
-      case Legal:
-        Tmp1 = LegalizeOp(Node->getOperand(0));
-        break;
-      case Promote:
-        Tmp1 = PromoteOp(Node->getOperand(0));
-        break;
-      case Expand:
-        assert(0 && "not implemented");
+    case Expand: assert(0 && "not implemented");
+    case Legal:   Tmp1 = LegalizeOp(Node->getOperand(0)); break;
+    case Promote: Tmp1 = PromoteOp(Node->getOperand(0));  break;
     }
     switch (getTypeAction(Node->getOperand(1).getValueType())) {
-      case Legal:
-        Tmp2 = LegalizeOp(Node->getOperand(1));
-        break;
-      case Promote:
-        Tmp2 = PromoteOp(Node->getOperand(1));
-        break;
-      case Expand:
-        assert(0 && "not implemented");
+    case Expand: assert(0 && "not implemented");
+    case Legal:   Tmp2 = LegalizeOp(Node->getOperand(1)); break;
+    case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); break;
     }
     Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
     
@@ -4978,7 +4975,7 @@
     SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi,
                                      DAG.getConstant(0, Hi.getValueType()),
                                      ISD::SETLT);
-    SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+    SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
     SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
                                       SignSet, Four, Zero);
     uint64_t FF = 0x5f800000ULL;
@@ -5100,7 +5097,8 @@
       // do nothing
       Result = Sub;
     } else if (MVT::getSizeInBits(DestVT) < MVT::getSizeInBits(MVT::f64)) {
-      Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub);
+      Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub,
+                           DAG.getIntPtrConstant(0));
     } else if (MVT::getSizeInBits(DestVT) > MVT::getSizeInBits(MVT::f64)) {
       Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub);
     }
@@ -5112,7 +5110,7 @@
   SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0,
                                    DAG.getConstant(0, Op0.getValueType()),
                                    ISD::SETLT);
-  SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
   SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
                                     SignSet, Four, Zero);
 
@@ -5570,7 +5568,7 @@
       // Increment the pointer to the other half.
       unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
       Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                        getIntPtrConstant(IncrementSize));
+                        DAG.getIntPtrConstant(IncrementSize));
       SVOffset += IncrementSize;
       Alignment = MinAlign(Alignment, IncrementSize);
       Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset,
@@ -6523,7 +6521,7 @@
     Lo = DAG.getLoad(NewVT_Lo, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
     unsigned IncrementSize = NewNumElts_Lo * MVT::getSizeInBits(NewEltVT)/8;
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     SVOffset += IncrementSize;
     Alignment = MinAlign(Alignment, IncrementSize);
     Hi = DAG.getLoad(NewVT_Hi, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index d553b58..70f5c74 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -82,10 +82,6 @@
     return getTypeAction(VT) == Legal;
   }
   
-  SDOperand getIntPtrConstant(uint64_t Val) {
-    return DAG.getConstant(Val, TLI.getPointerTy());
-  }
-  
   /// PromotedNodes - For nodes that are below legal width, this map indicates
   /// what promoted value to use.
   DenseMap<SDOperand, SDOperand> PromotedNodes;
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
index 32a4809..ec8d6fa 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
@@ -253,7 +253,7 @@
     // Increment the pointer to the other half.
     unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
                      isVolatile, MinAlign(Alignment, IncrementSize));
 
@@ -300,7 +300,7 @@
     // Increment the pointer to the other half.
     unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
                         SVOffset+IncrementSize, NEVT,
                         isVolatile, MinAlign(Alignment, IncrementSize));
@@ -324,7 +324,7 @@
 
     // Increment the pointer to the other half.
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     // Load the rest of the low bits.
     Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
                         SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits),
@@ -869,7 +869,7 @@
   SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi,
                                    DAG.getConstant(0, Hi.getValueType()),
                                    ISD::SETLT);
-  SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
   SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
                                     SignSet, Four, Zero);
   uint64_t FF = 0x5f800000ULL;
@@ -1053,7 +1053,7 @@
                       SVOffset, isVolatile, Alignment);
 
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
     Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
                       isVolatile, MinAlign(Alignment, IncrementSize));
@@ -1076,7 +1076,7 @@
     // Increment the pointer to the other half.
     unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
                            SVOffset+IncrementSize, NEVT,
                            isVolatile, MinAlign(Alignment, IncrementSize));
@@ -1110,7 +1110,7 @@
 
     // Increment the pointer to the other half.
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      getIntPtrConstant(IncrementSize));
+                      DAG.getIntPtrConstant(IncrementSize));
     // Store the lowest ExcessBits bits in the second half.
     Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(),
                            SVOffset+IncrementSize,
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
index 4b03c70..ee565d2 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
@@ -144,8 +144,11 @@
 
 SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
   // NOTE: Assumes input is legal.
-  return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
-                     N->getOperand(0), DAG.getValueType(N->getValueType(0)));
+  if (N->getConstantOperandVal(1) == 0) 
+    return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
+                       N->getOperand(0), DAG.getValueType(N->getValueType(0)));
+  // If the precision discard isn't needed, just return the operand unrounded.
+  return N->getOperand(0);
 }
 
 SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) {
@@ -353,7 +356,8 @@
 
 SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) {
   SDOperand Op = GetPromotedOp(N->getOperand(0));
-  return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op);
+  return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op,
+                     DAG.getIntPtrConstant(0));
 }
 
 SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
index bf992bb..549afe9 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
@@ -139,7 +139,7 @@
   Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
   unsigned IncrementSize = MVT::getSizeInBits(LoVT)/8;
   Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                    getIntPtrConstant(IncrementSize));
+                    DAG.getIntPtrConstant(IncrementSize));
   SVOffset += IncrementSize;
   Alignment = MinAlign(Alignment, IncrementSize);
   Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
@@ -380,7 +380,7 @@
   
   // Increment the pointer to the other half.
   Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                    getIntPtrConstant(IncrementSize));
+                    DAG.getIntPtrConstant(IncrementSize));
   
   Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
                     isVol, MinAlign(Alignment, IncrementSize));
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 34825be..be889ea 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -710,6 +710,11 @@
   return Result;
 }
 
+SDOperand SelectionDAG::getIntPtrConstant(uint64_t Val, bool isTarget) {
+  return getConstant(Val, TLI.getPointerTy(), isTarget);
+}
+
+
 SDOperand SelectionDAG::getConstantFP(const APFloat& V, MVT::ValueType VT,
                                       bool isTarget) {
   assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!");
@@ -1704,7 +1709,7 @@
   // Constant fold unary operations with a floating point constant operand.
   if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand.Val)) {
     APFloat V = C->getValueAPF();    // make copy
-    if (VT!=MVT::ppcf128 && Operand.getValueType()!=MVT::ppcf128) {
+    if (VT != MVT::ppcf128 && Operand.getValueType() != MVT::ppcf128) {
       switch (Opcode) {
       case ISD::FNEG:
         V.changeSign();
@@ -1749,13 +1754,13 @@
   switch (Opcode) {
   case ISD::TokenFactor:
     return Operand;         // Factor of one node?  No factor.
-  case ISD::FP_ROUND:
+  case ISD::FP_ROUND: assert(0 && "Invalid method to make FP_ROUND node");
   case ISD::FP_EXTEND:
     assert(MVT::isFloatingPoint(VT) &&
            MVT::isFloatingPoint(Operand.getValueType()) && "Invalid FP cast!");
     if (Operand.getValueType() == VT) return Operand;  // noop conversion.
     break;
-  case ISD::SIGN_EXTEND:
+    case ISD::SIGN_EXTEND:
     assert(MVT::isInteger(VT) && MVT::isInteger(Operand.getValueType()) &&
            "Invalid SIGN_EXTEND!");
     if (Operand.getValueType() == VT) return Operand;   // noop extension
@@ -1909,6 +1914,13 @@
            "Not rounding down!");
     break;
   }
+  case ISD::FP_ROUND:
+    assert(MVT::isFloatingPoint(VT) &&
+           MVT::isFloatingPoint(N1.getValueType()) &&
+           MVT::getSizeInBits(VT) <= MVT::getSizeInBits(N1.getValueType()) &&
+           isa<ConstantSDNode>(N2) && "Invalid FP_ROUND!");
+    if (N1.getValueType() == VT) return N1;  // noop conversion.
+    break;
   case ISD::AssertSext:
   case ISD::AssertZext:
   case ISD::SIGN_EXTEND_INREG: {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 67da406..e1b5ed1 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -483,10 +483,6 @@
                         const Value *SV, SDOperand Root,
                         bool isVolatile, unsigned Alignment);
 
-  SDOperand getIntPtrConstant(uint64_t Val) {
-    return DAG.getConstant(Val, TLI.getPointerTy());
-  }
-
   SDOperand getValue(const Value *V);
 
   void setValue(const Value *V, SDOperand NewN) {
@@ -677,12 +673,10 @@
       }
     }
   
-    if (MVT::isFloatingPoint(PartVT) &&
-        MVT::isFloatingPoint(ValueVT))
-      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+    if (MVT::isFloatingPoint(PartVT) && MVT::isFloatingPoint(ValueVT))
+      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val, DAG.getIntPtrConstant(0));
 
-    if (MVT::getSizeInBits(PartVT) == 
-        MVT::getSizeInBits(ValueVT))
+    if (MVT::getSizeInBits(PartVT) == MVT::getSizeInBits(ValueVT))
       return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
 
     assert(0 && "Unknown mismatch!");
@@ -2163,7 +2157,7 @@
   // FPTrunc is never a no-op cast, no need to check
   SDOperand N = getValue(I.getOperand(0));
   MVT::ValueType DestVT = TLI.getValueType(I.getType());
-  setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N));
+  setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N, DAG.getIntPtrConstant(0)));
 }
 
 void SelectionDAGLowering::visitFPExt(User &I){ 
@@ -2284,7 +2278,7 @@
         // N = N + Offset
         uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field);
         N = DAG.getNode(ISD::ADD, N.getValueType(), N,
-                        getIntPtrConstant(Offset));
+                        DAG.getIntPtrConstant(Offset));
       }
       Ty = StTy->getElementType(Field);
     } else {
@@ -2295,7 +2289,8 @@
         if (CI->getZExtValue() == 0) continue;
         uint64_t Offs = 
             TD->getABITypeSize(Ty)*cast<ConstantInt>(CI)->getSExtValue();
-        N = DAG.getNode(ISD::ADD, N.getValueType(), N, getIntPtrConstant(Offs));
+        N = DAG.getNode(ISD::ADD, N.getValueType(), N,
+                        DAG.getIntPtrConstant(Offs));
         continue;
       }
       
@@ -2320,7 +2315,7 @@
         continue;
       }
       
-      SDOperand Scale = getIntPtrConstant(ElementSize);
+      SDOperand Scale = DAG.getIntPtrConstant(ElementSize);
       IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale);
       N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN);
     }
@@ -2348,7 +2343,7 @@
     AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize);
 
   AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
-                          getIntPtrConstant(TySize));
+                          DAG.getIntPtrConstant(TySize));
 
   // Handle alignment.  If the requested alignment is less than or equal to
   // the stack alignment, ignore it.  If the size is greater than or equal to
@@ -2361,12 +2356,12 @@
   // Round the size of the allocation up to the stack alignment size
   // by add SA-1 to the size.
   AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
-                          getIntPtrConstant(StackAlign-1));
+                          DAG.getIntPtrConstant(StackAlign-1));
   // Mask out the low bits for alignment purposes.
   AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
-                          getIntPtrConstant(~(uint64_t)(StackAlign-1)));
+                          DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1)));
 
-  SDOperand Ops[] = { getRoot(), AllocSize, getIntPtrConstant(Align) };
+  SDOperand Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
   const MVT::ValueType *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
                                                     MVT::Other);
   SDOperand DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3);
@@ -3815,7 +3810,7 @@
   // Scale the source by the type size.
   uint64_t ElementSize = TD->getABITypeSize(I.getType()->getElementType());
   Src = DAG.getNode(ISD::MUL, Src.getValueType(),
-                    Src, getIntPtrConstant(ElementSize));
+                    Src, DAG.getIntPtrConstant(ElementSize));
 
   TargetLowering::ArgListTy Args;
   TargetLowering::ArgListEntry Entry;
@@ -3994,7 +3989,7 @@
         Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
       } else {
         assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
-        Op = DAG.getNode(ISD::FP_ROUND, VT, Op);
+        Op = DAG.getNode(ISD::FP_ROUND, VT, Op, DAG.getIntPtrConstant(1));
       }
       Ops.push_back(Op);
       break;