Fix PR1833 - eh.exception and eh.selector return two
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeDAG.cpp
index 066090032baaf5166fd6fe417cc5c0061fee16c6..688e4f9fea07c5fca399b751c8eaeea62f496b0d 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -15,6 +15,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Target/TargetData.h"
@@ -23,9 +24,9 @@
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -602,6 +603,7 @@ SDOperand ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
                              ST->isVolatile(), Alignment);
   Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
                     DAG.getConstant(IncrementSize, TLI.getPointerTy()));
+  Alignment = MinAlign(Alignment, IncrementSize);
   Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr,
                              ST->getSrcValue(), SVOffset + IncrementSize,
                              NewStoredVT, ST->isVolatile(), Alignment);
@@ -618,13 +620,13 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
   SDOperand Ptr = LD->getBasePtr();
   MVT::ValueType VT = LD->getValueType(0);
   MVT::ValueType LoadedVT = LD->getLoadedVT();
-  if (MVT::isFloatingPoint(VT)) {
+  if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT)) {
     // Expand to a (misaligned) integer load of the same size,
     // then bitconvert to floating point.
     MVT::ValueType intVT;
-    if (LoadedVT==MVT::f64)
+    if (LoadedVT == MVT::f64)
       intVT = MVT::i64;
-    else if (LoadedVT==MVT::f32)
+    else if (LoadedVT == MVT::f32)
       intVT = MVT::i32;
     else
       assert(0 && "Unaligned load of unsupported floating point type");
@@ -640,11 +642,25 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
     return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), 
                        Ops, 2);
   }
-  assert(MVT::isInteger(LoadedVT) && "Unaligned load of unsupported type.");
-  MVT::ValueType NewLoadedVT = LoadedVT - 1;
-  int NumBits = MVT::getSizeInBits(NewLoadedVT);
-  int Alignment = LD->getAlignment();
-  int IncrementSize = NumBits / 8;
+  assert((MVT::isInteger(LoadedVT) || MVT::isVector(LoadedVT)) &&
+         "Unaligned load of unsupported type.");
+
+  // Compute the new VT that is half the size of the old one.  We either have an
+  // integer MVT or we have a vector MVT.
+  unsigned NumBits = MVT::getSizeInBits(LoadedVT);
+  MVT::ValueType NewLoadedVT;
+  if (!MVT::isVector(LoadedVT)) {
+    NewLoadedVT = MVT::getIntegerType(NumBits/2);
+  } else {
+    // FIXME: This is not right for <1 x anything> it is also not right for
+    // non-power-of-two vectors.
+    NewLoadedVT = MVT::getVectorType(MVT::getVectorElementType(LoadedVT),
+                                     MVT::getVectorNumElements(LoadedVT)/2);
+  }
+  NumBits >>= 1;
+  
+  unsigned Alignment = LD->getAlignment();
+  unsigned IncrementSize = NumBits / 8;
   ISD::LoadExtType HiExtType = LD->getExtensionType();
 
   // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD.
@@ -660,7 +676,7 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
                       DAG.getConstant(IncrementSize, TLI.getPointerTy()));
     Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(),
                         SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
-                        Alignment);
+                        MinAlign(Alignment, IncrementSize));
   } else {
     Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset,
                         NewLoadedVT,LD->isVolatile(), Alignment);
@@ -668,7 +684,7 @@ SDOperand ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG,
                       DAG.getConstant(IncrementSize, TLI.getPointerTy()));
     Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(),
                         SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
-                        Alignment);
+                        MinAlign(Alignment, IncrementSize));
   }
 
   // aggregate the two parts
@@ -842,7 +858,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Expand: {
         unsigned Reg = TLI.getExceptionAddressRegister();
-        Result = DAG.getCopyFromReg(Tmp1, Reg, VT).getValue(Op.ResNo);
+        Result = DAG.getCopyFromReg(Tmp1, Reg, VT);
       }
       break;
     case TargetLowering::Custom:
@@ -852,12 +868,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     case TargetLowering::Legal: {
       SDOperand Ops[] = { DAG.getConstant(0, VT), Tmp1 };
       Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other),
-                           Ops, 2).getValue(Op.ResNo);
+                           Ops, 2);
       break;
     }
     }
     }
-    break;
+    if (Result.Val->getNumValues() == 1) break;
+
+    assert(Result.Val->getNumValues() == 2 &&
+           "Cannot return more than two values!");
+
+    // Since we produced two values, make sure to remember that we
+    // legalized both of them.
+    Tmp1 = LegalizeOp(Result);
+    Tmp2 = LegalizeOp(Result.getValue(1));
+    AddLegalizedOperand(Op.getValue(0), Tmp1);
+    AddLegalizedOperand(Op.getValue(1), Tmp2);
+    return Op.ResNo ? Tmp2 : Tmp1;
   case ISD::EHSELECTION: {
     Tmp1 = LegalizeOp(Node->getOperand(0));
     Tmp2 = LegalizeOp(Node->getOperand(1));
@@ -866,7 +893,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Expand: {
         unsigned Reg = TLI.getExceptionSelectorRegister();
-        Result = DAG.getCopyFromReg(Tmp2, Reg, VT).getValue(Op.ResNo);
+        Result = DAG.getCopyFromReg(Tmp2, Reg, VT);
       }
       break;
     case TargetLowering::Custom:
@@ -876,12 +903,23 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     case TargetLowering::Legal: {
       SDOperand Ops[] = { DAG.getConstant(0, VT), Tmp2 };
       Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other),
-                           Ops, 2).getValue(Op.ResNo);
+                           Ops, 2);
       break;
     }
     }
     }
-    break;
+    if (Result.Val->getNumValues() == 1) break;
+
+    assert(Result.Val->getNumValues() == 2 &&
+           "Cannot return more than two values!");
+
+    // Since we produced two values, make sure to remember that we
+    // legalized both of them.
+    Tmp1 = LegalizeOp(Result);
+    Tmp2 = LegalizeOp(Result.getValue(1));
+    AddLegalizedOperand(Op.getValue(0), Tmp1);
+    AddLegalizedOperand(Op.getValue(1), Tmp2);
+    return Op.ResNo ? Tmp2 : Tmp1;
   case ISD::EH_RETURN: {
     MVT::ValueType VT = Node->getValueType(0);
     // The only "good" option for this node is to custom lower it.
@@ -1141,12 +1179,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     // The only option for this is to custom lower it.
     Tmp3 = TLI.LowerOperation(Result.getValue(0), DAG);
     assert(Tmp3.Val && "Target didn't custom lower this node!");
-    assert(Tmp3.Val->getNumValues() == Result.Val->getNumValues() &&
+
+    // The number of incoming and outgoing values should match; unless the final
+    // outgoing value is a flag.
+    assert((Tmp3.Val->getNumValues() == Result.Val->getNumValues() ||
+            (Tmp3.Val->getNumValues() == Result.Val->getNumValues() + 1 &&
+             Tmp3.Val->getValueType(Tmp3.Val->getNumValues() - 1) ==
+               MVT::Flag)) &&
            "Lowering call/formal_arguments produced unexpected # results!");
     
     // Since CALL/FORMAL_ARGUMENTS nodes produce multiple values, make sure to
     // remember that we legalized all of them, so it doesn't get relegalized.
     for (unsigned i = 0, e = Tmp3.Val->getNumValues(); i != e; ++i) {
+      if (Tmp3.Val->getValueType(i) == MVT::Flag)
+        continue;
       Tmp1 = LegalizeOp(Tmp3.getValue(i));
       if (Op.ResNo == i)
         Tmp2 = Tmp1;
@@ -1471,6 +1517,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
              " not tell us which reg is the stack pointer!");
       SDOperand Chain = Tmp1.getOperand(0);
+
+      // Chain the dynamic stack allocation so that it doesn't modify the stack
+      // pointer when other instructions are using the stack.
+      Chain = DAG.getCALLSEQ_START(Chain,
+                                   DAG.getConstant(0, TLI.getPointerTy()));
+
       SDOperand Size  = Tmp2.getOperand(1);
       SDOperand SP = DAG.getCopyFromReg(Chain, SPReg, VT);
       Chain = SP.getValue(1);
@@ -1481,7 +1533,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         SP = DAG.getNode(ISD::AND, VT, SP,
                          DAG.getConstant(-(uint64_t)Align, VT));
       Tmp1 = DAG.getNode(ISD::SUB, VT, SP, Size);       // Value
-      Tmp2 = DAG.getCopyToReg(Chain, SPReg, Tmp1);      // Output chain
+      Chain = DAG.getCopyToReg(Chain, SPReg, Tmp1);     // Output chain
+
+      Tmp2 =
+        DAG.getCALLSEQ_END(Chain,
+                           DAG.getConstant(0, TLI.getPointerTy()),
+                           DAG.getConstant(0, TLI.getPointerTy()),
+                           SDOperand());
+
       Tmp1 = LegalizeOp(Tmp1);
       Tmp2 = LegalizeOp(Tmp2);
       break;
@@ -1597,21 +1656,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, NULL, 0); break;
       }
 
+      Addr = LD;
       if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) {
         // For PIC, the sequence is:
         // BRIND(load(Jumptable + index) + RelocBase)
-        // RelocBase is the JumpTable on PPC and X86, GOT on Alpha
-        SDOperand Reloc;
-        if (TLI.usesGlobalOffsetTable())
-          Reloc = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PTy);
-        else
-          Reloc = Table;
-        Addr = (PTy != MVT::i32) ? DAG.getNode(ISD::SIGN_EXTEND, PTy, LD) : LD;
-        Addr = DAG.getNode(ISD::ADD, PTy, Addr, Reloc);
-        Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr);
-      } else {
-        Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD);
+        // RelocBase can be JumpTable, GOT or some sort of global base.
+        if (PTy != MVT::i32)
+          Addr = DAG.getNode(ISD::SIGN_EXTEND, PTy, Addr);
+        Addr = DAG.getNode(ISD::ADD, PTy, Addr,
+                           TLI.getPICJumpTableRelocBase(Table, DAG));
       }
+      Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr);
     }
     }
     break;
@@ -1762,8 +1817,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Result = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
                                 LD->getSrcValue(), LD->getSrcValueOffset(),
                                 MVT::i8, LD->isVolatile(), LD->getAlignment());
-      Tmp1 = Result.getValue(0);
-      Tmp2 = Result.getValue(1);
+        Tmp1 = Result.getValue(0);
+        Tmp2 = Result.getValue(1);
       break;
       case TargetLowering::Custom:
         isCustom = true;
@@ -1919,8 +1974,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
           Result = LegalizeOp(Result);
         } else {
           SDNode *InVal = Tmp2.Val;
-          unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
-          MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+          int InIx = Tmp2.ResNo;
+          unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
+          MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
           
           // Figure out if there is a simple type corresponding to this Vector
           // type.  If so, convert to the vector type.
@@ -2054,7 +2110,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
             Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
                                getIntPtrConstant(4));
             Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
-                              isVolatile, std::max(Alignment, 4U));
+                              isVolatile, MinAlign(Alignment, 4U));
 
             Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
             break;
@@ -2114,8 +2170,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         // in the high half of the vector.
         if (MVT::isVector(ST->getValue().getValueType())) {
           SDNode *InVal = ST->getValue().Val;
-          unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
-          MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+          int InIx = ST->getValue().ResNo;
+          unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
+          MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
 
           // Figure out if there is a simple type corresponding to this Vector
           // type.  If so, convert to the vector type.
@@ -2138,7 +2195,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
             break;
           } else {
             SplitVectorOp(Node->getOperand(1), Lo, Hi);
-            IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
+            IncrementSize = MVT::getVectorNumElements(Lo.Val->getValueType(0)) * 
+                            MVT::getSizeInBits(EVT)/8;
           }
         } else {
           ExpandOp(Node->getOperand(1), Lo, Hi);
@@ -2162,8 +2220,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         assert(isTypeLegal(Tmp2.getValueType()) &&
                "Pointers must be legal!");
         SVOffset += IncrementSize;
-        if (Alignment > IncrementSize)
-          Alignment = IncrementSize;
+        Alignment = MinAlign(Alignment, IncrementSize);
         Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(),
                           SVOffset, isVolatile, Alignment);
         Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
@@ -2506,18 +2563,31 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       break;
     }
 
+    SDOperand Tmp6;
+    switch (getTypeAction(Node->getOperand(5).getValueType())) {  // bool
+    case Expand: assert(0 && "Cannot expand this yet!");
+    case Legal:
+      Tmp6 = LegalizeOp(Node->getOperand(5));
+      break;
+    case Promote:
+      Tmp6 = PromoteOp(Node->getOperand(5));
+      break;
+    }
+
     switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
     default: assert(0 && "This action not implemented for this operation!");
     case TargetLowering::Custom:
       isCustom = true;
       // FALLTHROUGH
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5);
+    case TargetLowering::Legal: {
+      SDOperand Ops[] = { Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6 };
+      Result = DAG.UpdateNodeOperands(Result, Ops, 6);
       if (isCustom) {
         Tmp1 = TLI.LowerOperation(Result, DAG);
         if (Tmp1.Val) Result = Tmp1;
       }
       break;
+    }
     case TargetLowering::Expand: {
       // Otherwise, the target does not support this operation.  Lower the
       // operation to an explicit libcall as appropriate.
@@ -2909,6 +2979,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
           Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2);
           Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2);
           Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result);
+        } else if (MVT::isVector(VT)) {
+          Result = LegalizeOp(UnrollVectorOp(Op));
         } else {
           assert(VT == MVT::i32 &&
                  "Cannot expand this binary operator!");
@@ -2918,12 +2990,18 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
           Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy);
         }
       } else {
-        // Floating point mod -> fmod libcall.
-        RTLIB::Libcall LC = VT == MVT::f32
-          ? RTLIB::REM_F32 : RTLIB::REM_F64;
-        SDOperand Dummy;
-        Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
-                               false/*sign irrelevant*/, Dummy);
+        assert(MVT::isFloatingPoint(VT) &&
+               "remainder op must have integer or floating-point type");
+        if (MVT::isVector(VT)) {
+          Result = LegalizeOp(UnrollVectorOp(Op));
+        } else {
+          // Floating point mod -> fmod libcall.
+          RTLIB::Libcall LC = VT == MVT::f32
+            ? RTLIB::REM_F32 : RTLIB::REM_F64;
+          SDOperand Dummy;
+          Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                                 false/*sign irrelevant*/, Dummy);
+        }
       }
       break;
     }
@@ -3247,8 +3325,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       // The input has to be a vector type, we have to either scalarize it, pack
       // it, or convert it based on whether the input vector type is legal.
       SDNode *InVal = Node->getOperand(0).Val;
-      unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
-      MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+      int InIx = Node->getOperand(0).ResNo;
+      unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
+      MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
     
       // Figure out if there is a simple type corresponding to this Vector
       // type.  If so, convert to the vector type.
@@ -3507,7 +3586,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
           MVT::ValueType slotVT = 
                   (Node->getOpcode() == ISD::FP_EXTEND) ? oldVT : newVT;
           const Type *Ty = MVT::getTypeForValueType(slotVT);
-          uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
+          uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty);
           unsigned Align  = TLI.getTargetData()->getPrefTypeAlignment(Ty);
           MachineFunction &MF = DAG.getMachineFunction();
           int SSFI =
@@ -3601,7 +3680,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         // slots and always reusing the same one.  We currently always create
         // new ones, as reuse may inhibit scheduling.
         const Type *Ty = MVT::getTypeForValueType(ExtraVT);
-        uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
+        uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty);
         unsigned Align  = TLI.getTargetData()->getPrefTypeAlignment(Ty);
         MachineFunction &MF = DAG.getMachineFunction();
         int SSFI =
@@ -3634,6 +3713,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     AddLegalizedOperand(SDOperand(Node, 0), Result);
     AddLegalizedOperand(SDOperand(Node, 1), Tmp1);
     return Op.ResNo ? Tmp1 : Result;
+  }
+   case ISD::FLT_ROUNDS: {
+    MVT::ValueType VT = Node->getValueType(0);
+    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+    default: assert(0 && "This action not supported for this op yet!");
+    case TargetLowering::Custom:
+      Result = TLI.LowerOperation(Op, DAG);
+      if (Result.Val) break;
+      // Fall Thru
+    case TargetLowering::Legal:
+      // If this operation is not supported, lower it to constant 1
+      Result = DAG.getConstant(1, VT);
+      break;
+    }
   }
   }
   
@@ -4134,6 +4227,13 @@ SDOperand SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDOperand Op) {
     unsigned EltSize = MVT::getSizeInBits(Op.getValueType())/8;
     Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx,
                       DAG.getConstant(EltSize, Idx.getValueType()));
+
+    if (MVT::getSizeInBits(Idx.getValueType()) >
+        MVT::getSizeInBits(TLI.getPointerTy()))
+      Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx);
+    else
+      Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
+
     StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr);
 
     Op = DAG.getLoad(Op.getValueType(), Ch, StackPtr, NULL, 0);
@@ -5110,10 +5210,21 @@ SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
     // Otherwise, try a larger type.
   }
 
-  // Okay, we found the operation and type to use.  Truncate the result of the
-  // extended FP_TO_*INT operation to the desired size.
-  return DAG.getNode(ISD::TRUNCATE, DestVT,
-                     DAG.getNode(OpToUse, NewOutTy, LegalOp));
+  
+  // Okay, we found the operation and type to use.
+  SDOperand Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp);
+  
+  // If the operation produces an invalid type, it must be custom lowered.  Use
+  // the target lowering hooks to expand it.  Just keep the low part of the
+  // expanded operation, we know that we're truncating anyway.
+  if (getTypeAction(NewOutTy) == Expand) {
+    Operation = SDOperand(TLI.ExpandOperationResult(Operation.Val, DAG), 0);
+    assert(Operation.Val && "Didn't return anything");
+  }
+  
+  // Truncate the result of the extended FP_TO_*INT operation to the desired
+  // size.
+  return DAG.getNode(ISD::TRUNCATE, DestVT, Operation);
 }
 
 /// ExpandBSWAP - Open code the operations for BSWAP of the specified operation.
@@ -5275,6 +5386,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
 #endif
     assert(0 && "Do not know how to expand this operator!");
     abort();
+  case ISD::EXTRACT_VECTOR_ELT:
+    assert(VT==MVT::i64 && "Do not know how to expand this operator!");
+    // ExpandEXTRACT_VECTOR_ELT tolerates invalid result types.
+    Lo  = ExpandEXTRACT_VECTOR_ELT(Op);
+    return ExpandOp(Lo, Lo, Hi);
   case ISD::UNDEF:
     NVT = TLI.getTypeToExpandTo(VT);
     Lo = DAG.getNode(ISD::UNDEF, NVT);
@@ -5306,6 +5422,20 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     Lo = Node->getOperand(0);
     Hi = Node->getOperand(1);
     break;
+      
+  case ISD::MERGE_VALUES:
+    if (Node->getNumValues() == 1) {
+      ExpandOp(Op.getOperand(0), Lo, Hi);
+      break;
+    }
+    // FIXME: For now only expand i64,chain = MERGE_VALUES (x, y)
+    assert(Op.ResNo == 0 && Node->getNumValues() == 2 &&
+           Op.getValue(1).getValueType() == MVT::Other &&
+           "unhandled MERGE_VALUES");
+    ExpandOp(Op.getOperand(0), Lo, Hi);
+    // Remember that we legalized the chain.
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(Op.getOperand(1)));
+    break;
     
   case ISD::SIGN_EXTEND_INREG:
     ExpandOp(Node->getOperand(0), Lo, Hi);
@@ -5406,8 +5536,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
                         getIntPtrConstant(IncrementSize));
       SVOffset += IncrementSize;
-      if (Alignment > IncrementSize)
-        Alignment = IncrementSize;
+      Alignment = MinAlign(Alignment, IncrementSize);
       Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset,
                        isVolatile, Alignment);
 
@@ -5423,7 +5552,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     } else {
       MVT::ValueType EVT = LD->getLoadedVT();
 
-      if (VT == MVT::f64 && EVT == MVT::f32) {
+      if ((VT == MVT::f64 && EVT == MVT::f32) ||
+          (VT == MVT::ppcf128 && (EVT==MVT::f64 || EVT==MVT::f32))) {
         // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
         SDOperand Load = DAG.getLoad(EVT, Ch, Ptr, LD->getSrcValue(),
                                      SVOffset, isVolatile, Alignment);
@@ -5570,16 +5700,17 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     break;
   }
 
-  case ISD::READCYCLECOUNTER:
+  case ISD::READCYCLECOUNTER: {
     assert(TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == 
                  TargetLowering::Custom &&
            "Must custom expand ReadCycleCounter");
-    Lo = TLI.LowerOperation(Op, DAG);
-    assert(Lo.Val && "Node must be custom expanded!");
-    Hi = Lo.getValue(1);
+    SDOperand Tmp = TLI.LowerOperation(Op, DAG);
+    assert(Tmp.Val && "Node must be custom expanded!");
+    ExpandOp(Tmp.getValue(0), Lo, Hi);
     AddLegalizedOperand(SDOperand(Node, 1), // Remember we legalized the chain.
-                        LegalizeOp(Lo.getValue(2)));
+                        LegalizeOp(Tmp.getValue(1)));
     break;
+  }
 
     // These operators cannot be expanded directly, emit them as calls to
     // library functions.
@@ -5906,6 +6037,15 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
         Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
         break;
       }
+      if (HasMULHU) {
+        Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+        Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+        RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
+        LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
+        Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
+        Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+        break;
+      }
     }
 
     // If nothing else, we can make a libcall.
@@ -6164,10 +6304,15 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
   SDNode *Node = Op.Val;
   unsigned NumElements = MVT::getVectorNumElements(Op.getValueType());
   assert(NumElements > 1 && "Cannot split a single element vector!");
-  unsigned NewNumElts = NumElements/2;
+
   MVT::ValueType NewEltVT = MVT::getVectorElementType(Op.getValueType());
-  MVT::ValueType NewVT = MVT::getVectorType(NewEltVT, NewNumElts);
-  
+
+  unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1);
+  unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
+
+  MVT::ValueType NewVT_Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo);
+  MVT::ValueType NewVT_Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi);
+
   // See if we already split it.
   std::map<SDOperand, std::pair<SDOperand, SDOperand> >::iterator I
     = SplitNodes.find(Op);
@@ -6183,6 +6328,10 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
     Node->dump(&DAG);
 #endif
     assert(0 && "Unhandled operation in SplitVectorOp!");
+  case ISD::UNDEF:
+    Lo = DAG.getNode(ISD::UNDEF, NewVT_Lo);
+    Hi = DAG.getNode(ISD::UNDEF, NewVT_Hi);
+    break;
   case ISD::BUILD_PAIR:
     Lo = Node->getOperand(0);
     Hi = Node->getOperand(1);
@@ -6191,25 +6340,62 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
     SplitVectorOp(Node->getOperand(0), Lo, Hi);
     unsigned Index = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
     SDOperand ScalarOp = Node->getOperand(1);
-    if (Index < NewNumElts)
-      Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Lo, ScalarOp,
+    if (Index < NewNumElts_Lo)
+      Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
                        DAG.getConstant(Index, TLI.getPointerTy()));
     else
-      Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Hi, ScalarOp,
-                       DAG.getConstant(Index - NewNumElts, TLI.getPointerTy()));
+      Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
+                       DAG.getConstant(Index - NewNumElts_Lo,
+                                       TLI.getPointerTy()));
+    break;
+  }
+  case ISD::VECTOR_SHUFFLE: {
+    // Build the low part.
+    SDOperand Mask = Node->getOperand(2);
+    SmallVector<SDOperand, 8> Ops;
+    MVT::ValueType PtrVT = TLI.getPointerTy();
+    
+    // Insert all of the elements from the input that are needed.  We use 
+    // buildvector of extractelement here because the input vectors will have
+    // to be legalized, so this makes the code simpler.
+    for (unsigned i = 0; i != NewNumElts_Lo; ++i) {
+      unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+      SDOperand InVec = Node->getOperand(0);
+      if (Idx >= NumElements) {
+        InVec = Node->getOperand(1);
+        Idx -= NumElements;
+      }
+      Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+                                DAG.getConstant(Idx, PtrVT)));
+    }
+    Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
+    Ops.clear();
+    
+    for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) {
+      unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+      SDOperand InVec = Node->getOperand(0);
+      if (Idx >= NumElements) {
+        InVec = Node->getOperand(1);
+        Idx -= NumElements;
+      }
+      Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+                                DAG.getConstant(Idx, PtrVT)));
+    }
+    Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
     break;
   }
   case ISD::BUILD_VECTOR: {
     SmallVector<SDOperand, 8> LoOps(Node->op_begin(), 
-                                    Node->op_begin()+NewNumElts);
-    Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &LoOps[0], LoOps.size());
+                                    Node->op_begin()+NewNumElts_Lo);
+    Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &LoOps[0], LoOps.size());
 
-    SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumElts, 
+    SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumElts_Lo
                                     Node->op_end());
-    Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &HiOps[0], HiOps.size());
+    Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &HiOps[0], HiOps.size());
     break;
   }
   case ISD::CONCAT_VECTORS: {
+    // FIXME: Handle non-power-of-two vectors?
     unsigned NewNumSubvectors = Node->getNumOperands() / 2;
     if (NewNumSubvectors == 1) {
       Lo = Node->getOperand(0);
@@ -6217,11 +6403,31 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
     } else {
       SmallVector<SDOperand, 8> LoOps(Node->op_begin(), 
                                       Node->op_begin()+NewNumSubvectors);
-      Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT, &LoOps[0], LoOps.size());
+      Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Lo, &LoOps[0], LoOps.size());
 
       SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumSubvectors, 
                                       Node->op_end());
-      Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT, &HiOps[0], HiOps.size());
+      Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Hi, &HiOps[0], HiOps.size());
+    }
+    break;
+  }
+  case ISD::SELECT: {
+    SDOperand Cond = Node->getOperand(0);
+
+    SDOperand LL, LH, RL, RH;
+    SplitVectorOp(Node->getOperand(1), LL, LH);
+    SplitVectorOp(Node->getOperand(2), RL, RH);
+
+    if (MVT::isVector(Cond.getValueType())) {
+      // Handle a vector merge.
+      SDOperand CL, CH;
+      SplitVectorOp(Cond, CL, CH);
+      Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, CL, LL, RL);
+      Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, CH, LH, RH);
+    } else {
+      // Handle a simple select with vector operands.
+      Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, Cond, LL, RL);
+      Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, Cond, LH, RH);
     }
     break;
   }
@@ -6237,21 +6443,24 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
   case ISD::FPOW:
   case ISD::AND:
   case ISD::OR:
-  case ISD::XOR: {
+  case ISD::XOR:
+  case ISD::UREM:
+  case ISD::SREM:
+  case ISD::FREM: {
     SDOperand LL, LH, RL, RH;
     SplitVectorOp(Node->getOperand(0), LL, LH);
     SplitVectorOp(Node->getOperand(1), RL, RH);
     
-    Lo = DAG.getNode(Node->getOpcode(), NewVT, LL, RL);
-    Hi = DAG.getNode(Node->getOpcode(), NewVT, LH, RH);
+    Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, LL, RL);
+    Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, LH, RH);
     break;
   }
   case ISD::FPOWI: {
     SDOperand L, H;
     SplitVectorOp(Node->getOperand(0), L, H);
 
-    Lo = DAG.getNode(Node->getOpcode(), NewVT, L, Node->getOperand(1));
-    Hi = DAG.getNode(Node->getOpcode(), NewVT, H, Node->getOperand(1));
+    Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L, Node->getOperand(1));
+    Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H, Node->getOperand(1));
     break;
   }
   case ISD::CTTZ:
@@ -6261,12 +6470,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
   case ISD::FABS:
   case ISD::FSQRT:
   case ISD::FSIN:
-  case ISD::FCOS: {
+  case ISD::FCOS:
+  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_UINT:
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP: {
     SDOperand L, H;
     SplitVectorOp(Node->getOperand(0), L, H);
 
-    Lo = DAG.getNode(Node->getOpcode(), NewVT, L);
-    Hi = DAG.getNode(Node->getOpcode(), NewVT, H);
+    Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L);
+    Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H);
     break;
   }
   case ISD::LOAD: {
@@ -6278,14 +6491,13 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
     unsigned Alignment = LD->getAlignment();
     bool isVolatile = LD->isVolatile();
 
-    Lo = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
-    unsigned IncrementSize = NewNumElts * MVT::getSizeInBits(NewEltVT)/8;
+    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));
     SVOffset += IncrementSize;
-    if (Alignment > IncrementSize)
-      Alignment = IncrementSize;
-    Hi = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
+    Alignment = MinAlign(Alignment, IncrementSize);
+    Hi = DAG.getLoad(NewVT_Hi, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
     
     // Build a factor node to remember that this load is independent of the
     // other one.
@@ -6313,8 +6525,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
     }
     // Split the vector and convert each of the pieces now.
     SplitVectorOp(InOp, Lo, Hi);
-    Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT, Lo);
-    Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT, Hi);
+    Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT_Lo, Lo);
+    Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT_Hi, Hi);
     break;
   }
   }