PR11662.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeVectorOps.cpp
index ca67c22f50a1ae36c386ea3011739ddb92e344fc..4696c0d7546f24150fb990ae4309a7e074358af0 100644 (file)
@@ -185,8 +185,10 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
   case ISD::SRL:
   case ISD::ROTL:
   case ISD::ROTR:
-  case ISD::CTTZ:
   case ISD::CTLZ:
+  case ISD::CTTZ:
+  case ISD::CTLZ_ZERO_UNDEF:
+  case ISD::CTTZ_ZERO_UNDEF:
   case ISD::CTPOP:
   case ISD::SELECT:
   case ISD::VSELECT:
@@ -298,6 +300,7 @@ SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
   SDValue Chain = LD->getChain();
   SDValue BasePTR = LD->getBasePtr();
   EVT SrcVT = LD->getMemoryVT();
+  ISD::LoadExtType ExtType = LD->getExtensionType();
 
   SmallVector<SDValue, 8> LoadVals;
   SmallVector<SDValue, 8> LoadChains;
@@ -305,19 +308,20 @@ SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
   unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8;
 
   for (unsigned Idx=0; Idx<NumElem; Idx++) {
-    BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
-                       DAG.getIntPtrConstant(Stride));
-    SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl,
+    SDValue ScalarLoad = DAG.getExtLoad(ExtType, dl,
               Op.getNode()->getValueType(0).getScalarType(),
               Chain, BasePTR, LD->getPointerInfo().getWithOffset(Idx * Stride),
               SrcVT.getScalarType(),
               LD->isVolatile(), LD->isNonTemporal(),
               LD->getAlignment());
 
+    BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
+                       DAG.getIntPtrConstant(Stride));
+
      LoadVals.push_back(ScalarLoad.getValue(0));
      LoadChains.push_back(ScalarLoad.getValue(1));
   }
-  
+
   SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
             &LoadChains[0], LoadChains.size());
   SDValue Value = DAG.getNode(ISD::BUILD_VECTOR, dl,
@@ -350,7 +354,6 @@ SDValue VectorLegalizer::ExpandStore(SDValue Op) {
 
   // Cast floats into integers
   unsigned ScalarSize = MemSclVT.getSizeInBits();
-  EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize);
 
   // Round odd types to the next pow of two.
   if (!isPowerOf2_32(ScalarSize))
@@ -365,14 +368,14 @@ SDValue VectorLegalizer::ExpandStore(SDValue Op) {
     SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
                RegSclVT, Value, DAG.getIntPtrConstant(Idx));
 
-    BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
-                                DAG.getIntPtrConstant(Stride));
-
     // This scalar TruncStore may be illegal, but we legalize it later.
     SDValue Store = DAG.getTruncStore(Chain, dl, Ex, BasePTR,
                ST->getPointerInfo().getWithOffset(Idx*Stride), MemSclVT,
                isVolatile, isNonTemporal, Alignment);
 
+    BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,
+                                DAG.getIntPtrConstant(Stride));
+
     Stores.push_back(Store);
   }
   SDValue TF =  DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
@@ -385,7 +388,6 @@ SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
   // Implement VSELECT in terms of XOR, AND, OR
   // on platforms which do not support blend natively.
   EVT VT =  Op.getOperand(0).getValueType();
-  EVT OVT = Op.getOperand(1).getValueType();
   DebugLoc DL = Op.getDebugLoc();
 
   SDValue Mask = Op.getOperand(0);
@@ -394,12 +396,15 @@ SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) {
 
   // If we can't even use the basic vector operations of
   // AND,OR,XOR, we will have to scalarize the op.
-  if (!TLI.isOperationLegalOrCustom(ISD::AND, VT) ||
-      !TLI.isOperationLegalOrCustom(ISD::XOR, VT) ||
-      !TLI.isOperationLegalOrCustom(ISD::OR, VT))
-        return DAG.UnrollVectorOp(Op.getNode());
-
-  assert(VT.getSizeInBits() == OVT.getSizeInBits() && "Invalid mask size");
+  // Notice that the operation may be 'promoted' which means that it is
+  // 'bitcasted' to another type which is handled.
+  if (TLI.getOperationAction(ISD::AND, VT) == TargetLowering::Expand ||
+      TLI.getOperationAction(ISD::XOR, VT) == TargetLowering::Expand ||
+      TLI.getOperationAction(ISD::OR,  VT) == TargetLowering::Expand)
+    return DAG.UnrollVectorOp(Op.getNode());
+
+  assert(VT.getSizeInBits() == Op.getOperand(1).getValueType().getSizeInBits()
+         && "Invalid mask size");
   // Bitcast the operands to be the same type as the mask.
   // This is needed when we select between FP types because
   // the mask is a vector of integers.
@@ -420,9 +425,9 @@ SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) {
   DebugLoc DL = Op.getDebugLoc();
 
   // Make sure that the SINT_TO_FP and SRL instructions are available.
-  if (!TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, VT) ||
-      !TLI.isOperationLegalOrCustom(ISD::SRL, VT))
-      return DAG.UnrollVectorOp(Op.getNode());
+  if (TLI.getOperationAction(ISD::SINT_TO_FP, VT) == TargetLowering::Expand ||
+      TLI.getOperationAction(ISD::SRL,        VT) == TargetLowering::Expand)
+    return DAG.UnrollVectorOp(Op.getNode());
 
  EVT SVT = VT.getScalarType();
   assert((SVT.getSizeInBits() == 64 || SVT.getSizeInBits() == 32) &&