Factorize (and generalize) the code promoting SELECT
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeIntegerTypes.cpp
index 10cfdc634bddd7e8c8f368e1a076ac2835c88cca..2a0b408fc8daab54cf69c0fc14b8581e9dfbf95c 100644 (file)
@@ -92,62 +92,26 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::UREM:        Result = PromoteIntRes_UDIV(N); break;
 
   case ISD::SADDO:
+  case ISD::SSUBO:       Result = PromoteIntRes_SADDSUBO(N, ResNo); break;
   case ISD::UADDO:
-  case ISD::SSUBO:
-  case ISD::USUBO:
+  case ISD::USUBO:       Result = PromoteIntRes_UADDSUBO(N, ResNo); break;
   case ISD::SMULO:
-  case ISD::UMULO:       Result = PromoteIntRes_XALUO(N, ResNo); break;
-
-  case ISD::ATOMIC_LOAD_ADD_8:
-  case ISD::ATOMIC_LOAD_SUB_8:
-  case ISD::ATOMIC_LOAD_AND_8:
-  case ISD::ATOMIC_LOAD_OR_8:
-  case ISD::ATOMIC_LOAD_XOR_8:
-  case ISD::ATOMIC_LOAD_NAND_8:
-  case ISD::ATOMIC_LOAD_MIN_8:
-  case ISD::ATOMIC_LOAD_MAX_8:
-  case ISD::ATOMIC_LOAD_UMIN_8:
-  case ISD::ATOMIC_LOAD_UMAX_8:
-  case ISD::ATOMIC_SWAP_8:
-  case ISD::ATOMIC_LOAD_ADD_16:
-  case ISD::ATOMIC_LOAD_SUB_16:
-  case ISD::ATOMIC_LOAD_AND_16:
-  case ISD::ATOMIC_LOAD_OR_16:
-  case ISD::ATOMIC_LOAD_XOR_16:
-  case ISD::ATOMIC_LOAD_NAND_16:
-  case ISD::ATOMIC_LOAD_MIN_16:
-  case ISD::ATOMIC_LOAD_MAX_16:
-  case ISD::ATOMIC_LOAD_UMIN_16:
-  case ISD::ATOMIC_LOAD_UMAX_16:
-  case ISD::ATOMIC_SWAP_16:
-  case ISD::ATOMIC_LOAD_ADD_32:
-  case ISD::ATOMIC_LOAD_SUB_32:
-  case ISD::ATOMIC_LOAD_AND_32:
-  case ISD::ATOMIC_LOAD_OR_32:
-  case ISD::ATOMIC_LOAD_XOR_32:
-  case ISD::ATOMIC_LOAD_NAND_32:
-  case ISD::ATOMIC_LOAD_MIN_32:
-  case ISD::ATOMIC_LOAD_MAX_32:
-  case ISD::ATOMIC_LOAD_UMIN_32:
-  case ISD::ATOMIC_LOAD_UMAX_32:
-  case ISD::ATOMIC_SWAP_32:
-  case ISD::ATOMIC_LOAD_ADD_64:
-  case ISD::ATOMIC_LOAD_SUB_64:
-  case ISD::ATOMIC_LOAD_AND_64:
-  case ISD::ATOMIC_LOAD_OR_64:
-  case ISD::ATOMIC_LOAD_XOR_64:
-  case ISD::ATOMIC_LOAD_NAND_64:
-  case ISD::ATOMIC_LOAD_MIN_64:
-  case ISD::ATOMIC_LOAD_MAX_64:
-  case ISD::ATOMIC_LOAD_UMIN_64:
-  case ISD::ATOMIC_LOAD_UMAX_64:
-  case ISD::ATOMIC_SWAP_64:
+  case ISD::UMULO:       Result = PromoteIntRes_XMULO(N, ResNo); break;
+
+  case ISD::ATOMIC_LOAD_ADD:
+  case ISD::ATOMIC_LOAD_SUB:
+  case ISD::ATOMIC_LOAD_AND:
+  case ISD::ATOMIC_LOAD_OR:
+  case ISD::ATOMIC_LOAD_XOR:
+  case ISD::ATOMIC_LOAD_NAND:
+  case ISD::ATOMIC_LOAD_MIN:
+  case ISD::ATOMIC_LOAD_MAX:
+  case ISD::ATOMIC_LOAD_UMIN:
+  case ISD::ATOMIC_LOAD_UMAX:
+  case ISD::ATOMIC_SWAP:
     Result = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break;
 
-  case ISD::ATOMIC_CMP_SWAP_8:
-  case ISD::ATOMIC_CMP_SWAP_16:
-  case ISD::ATOMIC_CMP_SWAP_32:
-  case ISD::ATOMIC_CMP_SWAP_64:
+  case ISD::ATOMIC_CMP_SWAP:
     Result = PromoteIntRes_Atomic2(cast<AtomicSDNode>(N)); break;
   }
 
@@ -170,7 +134,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
 
 SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
   SDValue Op2 = GetPromotedInteger(N->getOperand(2));
-  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getChain(), N->getBasePtr(),
+  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getMemoryVT(),
+                              N->getChain(), N->getBasePtr(),
                               Op2, N->getSrcValue(), N->getAlignment());
   // Legalized the chain result - switch anything that used the old chain to
   // use the new one.
@@ -181,7 +146,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
 SDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) {
   SDValue Op2 = GetPromotedInteger(N->getOperand(2));
   SDValue Op3 = GetPromotedInteger(N->getOperand(3));
-  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getChain(), N->getBasePtr(),
+  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getMemoryVT(),
+                              N->getChain(), N->getBasePtr(),
                               Op2, Op3, N->getSrcValue(), N->getAlignment());
   // Legalized the chain result - switch anything that used the old chain to
   // use the new one.
@@ -217,7 +183,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
     // Convert the element to an integer and promote it by hand.
     return DAG.getNode(ISD::ANY_EXTEND, NOutVT,
                        BitConvertToInteger(GetScalarizedVector(InOp)));
-  case SplitVector:
+  case SplitVector: {
     // For example, i32 = BIT_CONVERT v2i16 on alpha.  Convert the split
     // pieces of the input into integers and reassemble in the final type.
     SDValue Lo, Hi;
@@ -233,9 +199,13 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
                        JoinIntegers(Lo, Hi));
     return DAG.getNode(ISD::BIT_CONVERT, NOutVT, InOp);
   }
+  case WidenVector:
+    if (OutVT.bitsEq(NInVT))
+      // The input is widened to the same size.  Convert to the widened value.
+      return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetWidenedVector(InOp));
+  }
 
   // Otherwise, lower the bit-convert to a store/load from the stack.
-
   // Create the stack frame object.  Make sure it is aligned for both
   // the source and destination types.
   SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT);
@@ -359,8 +329,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
   if (TLI.isBigEndian())
     std::swap(Lo, Hi);
 
+  // Signed extend to the promoted type.
   SDValue Odd = DAG.getNode(ISD::TRUNCATE, MVT::i1, OldIdx);
-  return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
+  SDValue Res = DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
+  return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT), Res);
 }
 
 SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
@@ -428,6 +400,49 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
   return Res;
 }
 
+/// Promote the overflow flag of an overflowing arithmetic node.
+SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
+  // Simply change the return type of the boolean result.
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
+  MVT ValueVTs[] = { N->getValueType(0), NVT };
+  SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
+  SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
+
+  // Modified the sum result - switch anything that used the old sum to use
+  // the new one.
+  ReplaceValueWith(SDValue(N, 0), Res);
+
+  return SDValue(Res.getNode(), 1);
+}
+
+SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
+  if (ResNo == 1)
+    return PromoteIntRes_Overflow(N);
+
+  // The operation overflowed iff the result in the larger type is not the
+  // sign extension of its truncation to the original type.
+  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
+  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
+  MVT OVT = N->getOperand(0).getValueType();
+  MVT NVT = LHS.getValueType();
+
+  // Do the arithmetic in the larger type.
+  unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
+  SDValue Res = DAG.getNode(Opcode, NVT, LHS, RHS);
+
+  // Calculate the overflow flag: sign extend the arithmetic result from
+  // the original type.
+  SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+                            DAG.getValueType(OVT));
+  // Overflowed if and only if this is not equal to Res.
+  Ofl = DAG.getSetCC(N->getValueType(1), Ofl, Res, ISD::SETNE);
+
+  // Use the calculated overflow everywhere.
+  ReplaceValueWith(SDValue(N, 1), Ofl);
+
+  return Res;
+}
+
 SDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
   // Sign extend the input.
   SDValue LHS = SExtPromotedInteger(N->getOperand(0));
@@ -449,7 +464,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
 }
 
 SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
-  MVT SVT = TLI.getSetCCResultType(N->getOperand(0));
+  MVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType());
   assert(isTypeLegal(SVT) && "Illegal SetCC type!");
 
   // Get the SETCC result using the canonical SETCC type.
@@ -515,27 +530,38 @@ SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
   return DAG.getNode(ISD::TRUNCATE, NVT, Res);
 }
 
-SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
-  // Zero extend the input.
+SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
+  if (ResNo == 1)
+    return PromoteIntRes_Overflow(N);
+
+  // The operation overflowed iff the result in the larger type is not the
+  // zero extension of its truncation to the original type.
   SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
   SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
-  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
+  MVT OVT = N->getOperand(0).getValueType();
+  MVT NVT = LHS.getValueType();
 
-SDValue DAGTypeLegalizer::PromoteIntRes_XALUO(SDNode *N, unsigned ResNo) {
-  assert(ResNo == 1 && "Only boolean result promotion currently supported!");
+  // Do the arithmetic in the larger type.
+  unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
+  SDValue Res = DAG.getNode(Opcode, NVT, LHS, RHS);
 
-  // Simply change the return type of the boolean result.
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
-  MVT ValueVTs[] = { N->getValueType(0), NVT };
-  SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
-  SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
+  // Calculate the overflow flag: zero extend the arithmetic result from
+  // the original type.
+  SDValue Ofl = DAG.getZeroExtendInReg(Res, OVT);
+  // Overflowed if and only if this is not equal to Res.
+  Ofl = DAG.getSetCC(N->getValueType(1), Ofl, Res, ISD::SETNE);
 
-  // Modified the sum result - switch anything that used the old sum to use
-  // the new one.
-  ReplaceValueWith(SDValue(N, 0), Res);
+  // Use the calculated overflow everywhere.
+  ReplaceValueWith(SDValue(N, 1), Ofl);
 
-  return SDValue(Res.getNode(), 1);
+  return Res;
+}
+
+SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
+  // Zero extend the input.
+  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
+  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
+  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
 }
 
 SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
@@ -580,6 +606,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
   return Res;
 }
 
+SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
+  assert(ResNo == 1 && "Only boolean result promotion currently supported!");
+  return PromoteIntRes_Overflow(N);
+}
 
 //===----------------------------------------------------------------------===//
 //  Integer Operand Promotion
@@ -696,27 +726,10 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
 
 SDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
   assert(OpNo == 1 && "only know how to promote condition");
-  SDValue Cond = GetPromotedInteger(N->getOperand(1));  // Promote condition.
 
-  // Make sure the extra bits coming from type promotion conform to
-  // getBooleanContents.
-  unsigned CondBits = Cond.getValueSizeInBits();
-  switch (TLI.getBooleanContents()) {
-  default:
-    assert(false && "Unknown BooleanContent!");
-  case TargetLowering::UndefinedBooleanContent:
-    // The promoted value, which may contain rubbish in the upper bits, is fine.
-    break;
-  case TargetLowering::ZeroOrOneBooleanContent:
-    if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1)))
-      Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
-    break;
-  case TargetLowering::ZeroOrNegativeOneBooleanContent:
-    if (DAG.ComputeNumSignBits(Cond) != CondBits)
-      Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, Cond.getValueType(), Cond,
-                         DAG.getValueType(MVT::i1));
-    break;
-  }
+  // Promote all the way up to the canonical SetCC type.
+  MVT SVT = TLI.getSetCCResultType(MVT::Other);
+  SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT);
 
   // The chain (Op#0) and basic block destination (Op#2) are always legal types.
   return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Cond,
@@ -818,50 +831,10 @@ SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
 
 SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
   assert(OpNo == 0 && "Only know how to promote condition");
-  SDValue Cond = GetPromotedInteger(N->getOperand(0));
-
-  // Promote all the way up to SVT, the canonical SetCC type.
-  // FIXME: Not clear what value to pass to getSetCCResultType.
-  // [This only matters for CellSPU since all other targets
-  // ignore the argument.]  We used to pass Cond, resulting in
-  // SVT = MVT::i8, but CellSPU has no select patterns for i8,
-  // causing an abort later.  Passing the result type works
-  // around the problem.
-  MVT SVT = TLI.getSetCCResultType(N->getOperand(1));
-  assert(isTypeLegal(SVT) && "Illegal SetCC type!");
-  assert(Cond.getValueType().bitsLE(SVT) && "Unexpected SetCC type!");
-
-  // Make sure the extra bits conform to getBooleanContents.  There are
-  // two sets of extra bits: those in Cond, which come from type promotion,
-  // and those we need to add to have the final type be SVT (for most targets
-  // this last set of bits is empty).
-  unsigned CondBits = Cond.getValueSizeInBits();
-  ISD::NodeType ExtendCode;
-  switch (TLI.getBooleanContents()) {
-  default:
-    assert(false && "Unknown BooleanContent!");
-  case TargetLowering::UndefinedBooleanContent:
-    // Extend to SVT by adding rubbish.
-    ExtendCode = ISD::ANY_EXTEND;
-    break;
-  case TargetLowering::ZeroOrOneBooleanContent:
-    ExtendCode = ISD::ZERO_EXTEND;
-    if (!DAG.MaskedValueIsZero(Cond,APInt::getHighBitsSet(CondBits,CondBits-1)))
-      // All extra bits need to be cleared.  Do this by zero extending the
-      // original condition value all the way to SVT.
-      Cond = N->getOperand(0);
-    break;
-  case TargetLowering::ZeroOrNegativeOneBooleanContent: {
-    ExtendCode = ISD::SIGN_EXTEND;
-    unsigned SignBits = DAG.ComputeNumSignBits(Cond);
-    if (SignBits != CondBits)
-      // All extra bits need to be sign extended.  Do this by sign extending the
-      // original condition value all the way to SVT.
-      Cond = N->getOperand(0);
-    break;
-  }
-  }
-  Cond = DAG.getNode(ExtendCode, SVT, Cond);
+
+  // Promote all the way up to the canonical SetCC type.
+  MVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType());
+  SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT);
 
   return DAG.UpdateNodeOperands(SDValue(N, 0), Cond,
                                 N->getOperand(1), N->getOperand(2));
@@ -911,8 +884,6 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
 
   SDValue Val = GetPromotedInteger(N->getValue());  // Get promoted value.
 
-  assert(!N->isTruncatingStore() && "Cannot promote this store operand!");
-
   // Truncate the value and store the result.
   return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
                            SVOffset, N->getMemoryVT(),
@@ -1153,6 +1124,8 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
     }
   }
 
+#if 0
+  // FIXME: This code is broken for shifts with a zero amount!
   // If we know that all of the high bits of the shift amount are zero, then we
   // can do this as a couple of simple shifts.
   if ((KnownZero & HighBitMask) == HighBitMask) {
@@ -1174,6 +1147,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
                      DAG.getNode(Op2, NVT, InL, Amt2));
     return true;
   }
+#endif
 
   return false;
 }
@@ -1213,12 +1187,12 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
     if (N->getOpcode() == ISD::ADD) {
       Lo = DAG.getNode(ISD::ADD, NVT, LoOps, 2);
       Hi = DAG.getNode(ISD::ADD, NVT, HiOps, 2);
-      SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo, LoOps[0],
+      SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, LoOps[0],
                                   ISD::SETULT);
       SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1,
                                    DAG.getConstant(1, NVT),
                                    DAG.getConstant(0, NVT));
-      SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo, LoOps[1],
+      SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, LoOps[1],
                                   ISD::SETULT);
       SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2,
                                    DAG.getConstant(1, NVT), Carry1);
@@ -1226,8 +1200,9 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
     } else {
       Lo = DAG.getNode(ISD::SUB, NVT, LoOps, 2);
       Hi = DAG.getNode(ISD::SUB, NVT, HiOps, 2);
-      SDValue Cmp = DAG.getSetCC(TLI.getSetCCResultType(LoOps[0]),
-                                 LoOps[0], LoOps[1], ISD::SETULT);
+      SDValue Cmp =
+        DAG.getSetCC(TLI.getSetCCResultType(LoOps[0].getValueType()),
+                     LoOps[0], LoOps[1], ISD::SETULT);
       SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp,
                                    DAG.getConstant(1, NVT),
                                    DAG.getConstant(0, NVT));
@@ -1360,7 +1335,7 @@ void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
   GetExpandedInteger(N->getOperand(0), Lo, Hi);
   MVT NVT = Lo.getValueType();
 
-  SDValue HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
+  SDValue HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), Hi,
                                    DAG.getConstant(0, NVT), ISD::SETNE);
 
   SDValue LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo);
@@ -1388,7 +1363,7 @@ void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
   GetExpandedInteger(N->getOperand(0), Lo, Hi);
   MVT NVT = Lo.getValueType();
 
-  SDValue LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo,
+  SDValue LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo,
                                    DAG.getConstant(0, NVT), ISD::SETNE);
 
   SDValue LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
@@ -1882,9 +1857,11 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
       assert(0 && "Do not know how to expand this operator's operand!");
       abort();
 
-    case ISD::BUILD_VECTOR:    Res = ExpandOp_BUILD_VECTOR(N); break;
-    case ISD::BIT_CONVERT:     Res = ExpandOp_BIT_CONVERT(N); break;
-    case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
+    case ISD::BUILD_VECTOR:      Res = ExpandOp_BUILD_VECTOR(N); break;
+    case ISD::BIT_CONVERT:       Res = ExpandOp_BIT_CONVERT(N); break;
+    case ISD::EXTRACT_ELEMENT:   Res = ExpandOp_EXTRACT_ELEMENT(N); break;
+    case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
+    case ISD::SCALAR_TO_VECTOR:  Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
 
     case ISD::BR_CC:      Res = ExpandIntOp_BR_CC(N); break;
     case ISD::SELECT_CC:  Res = ExpandIntOp_SELECT_CC(N); break;
@@ -1974,15 +1951,16 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
   // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
   TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
   SDValue Tmp1, Tmp2;
-  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC,
-                           false, DagCombineInfo);
+  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+                           LHSLo, RHSLo, LowCC, false, DagCombineInfo);
   if (!Tmp1.getNode())
-    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC);
-  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                           CCCode, false, DagCombineInfo);
+    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
+                        LHSLo, RHSLo, LowCC);
+  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+                           LHSHi, RHSHi, CCCode, false, DagCombineInfo);
   if (!Tmp2.getNode())
-    Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                       DAG.getCondCode(CCCode));
+    Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi.getValueType()),
+                       LHSHi, RHSHi, DAG.getCondCode(CCCode));
 
   ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
   ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode());
@@ -2001,11 +1979,11 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
     return;
   }
 
-  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                             ISD::SETEQ, false, DagCombineInfo);
+  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+                             LHSHi, RHSHi, ISD::SETEQ, false, DagCombineInfo);
   if (!NewLHS.getNode())
-    NewLHS = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                          ISD::SETEQ);
+    NewLHS = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
+                          LHSHi, RHSHi, ISD::SETEQ);
   NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
                        NewLHS, Tmp1, Tmp2);
   NewRHS = SDValue();
@@ -2190,8 +2168,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
     // Check whether the sign bit is set.
     SDValue Lo, Hi;
     GetExpandedInteger(Op, Lo, Hi);
-    SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
-                                   DAG.getConstant(0, Hi.getValueType()),
+    SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi.getValueType()),
+                                   Hi, DAG.getConstant(0, Hi.getValueType()),
                                    ISD::SETLT);
 
     // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.