diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 67 | 
1 files changed, 49 insertions, 18 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 507e7ffb1d45..eac404c50365 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -199,12 +199,30 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {    if (Op.getOpcode() == ISD::LOAD) {      LoadSDNode *LD = cast<LoadSDNode>(Op.getNode());      ISD::LoadExtType ExtType = LD->getExtensionType(); -    if (LD->getMemoryVT().isVector() && ExtType != ISD::NON_EXTLOAD) { -      if (TLI.isLoadExtLegal(LD->getExtensionType(), LD->getMemoryVT())) +    if (LD->getMemoryVT().isVector() && ExtType != ISD::NON_EXTLOAD) +      switch (TLI.getLoadExtAction(LD->getExtensionType(), LD->getValueType(0), +                                   LD->getMemoryVT())) { +      default: llvm_unreachable("This action is not supported yet!"); +      case TargetLowering::Legal:          return TranslateLegalizeResults(Op, Result); -      Changed = true; -      return LegalizeOp(ExpandLoad(Op)); -    } +      case TargetLowering::Custom: +        if (SDValue Lowered = TLI.LowerOperation(Result, DAG)) { +          Changed = true; +          if (Lowered->getNumValues() != Op->getNumValues()) { +            // This expanded to something other than the load. Assume the +            // lowering code took care of any chain values, and just handle the +            // returned value. +            assert(Result.getValue(1).use_empty() && +                   "There are still live users of the old chain!"); +            return LegalizeOp(Lowered); +          } else { +            return TranslateLegalizeResults(Op, Lowered); +          } +        } +      case TargetLowering::Expand: +        Changed = true; +        return LegalizeOp(ExpandLoad(Op)); +      }    } else if (Op.getOpcode() == ISD::STORE) {      StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());      EVT StVT = ST->getMemoryVT(); @@ -273,6 +291,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {    case ISD::FP_TO_UINT:    case ISD::FNEG:    case ISD::FABS: +  case ISD::FMINNUM: +  case ISD::FMAXNUM:    case ISD::FCOPYSIGN:    case ISD::FSQRT:    case ISD::FSIN: @@ -353,9 +373,11 @@ SDValue VectorLegalizer::Promote(SDValue Op) {      return PromoteFP_TO_INT(Op, Op->getOpcode() == ISD::FP_TO_SINT);    } -  // The rest of the time, vector "promotion" is basically just bitcasting and -  // doing the operation in a different type.  For example, x86 promotes -  // ISD::AND on v2i32 to v1i64. +  // There are currently two cases of vector promotion: +  // 1) Bitcasting a vector of integers to a different type to a vector of the +  //    same overall length. For example, x86 promotes ISD::AND on v2i32 to v1i64. +  // 2) Extending a vector of floats to a vector of the same number oflarger +  //    floats. For example, AArch64 promotes ISD::FADD on v4f16 to v4f32.    MVT VT = Op.getSimpleValueType();    assert(Op.getNode()->getNumValues() == 1 &&           "Can't promote a vector with multiple results!"); @@ -365,14 +387,23 @@ SDValue VectorLegalizer::Promote(SDValue Op) {    for (unsigned j = 0; j != Op.getNumOperands(); ++j) {      if (Op.getOperand(j).getValueType().isVector()) -      Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Op.getOperand(j)); +      if (Op.getOperand(j) +              .getValueType() +              .getVectorElementType() +              .isFloatingPoint()) +        Operands[j] = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op.getOperand(j)); +      else +        Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Op.getOperand(j));      else        Operands[j] = Op.getOperand(j);    }    Op = DAG.getNode(Op.getOpcode(), dl, NVT, Operands); - -  return DAG.getNode(ISD::BITCAST, dl, VT, Op); +  if (VT.isFloatingPoint() || +      (VT.isVector() && VT.getVectorElementType().isFloatingPoint())) +    return DAG.getNode(ISD::FP_ROUND, dl, VT, Op, DAG.getIntPtrConstant(0)); +  else +    return DAG.getNode(ISD::BITCAST, dl, VT, Op);  }  SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) { @@ -480,7 +511,7 @@ SDValue VectorLegalizer::ExpandLoad(SDValue Op) {                                   LD->getPointerInfo().getWithOffset(Offset),                                   LD->isVolatile(), LD->isNonTemporal(),                                   LD->isInvariant(), LD->getAlignment(), -                                 LD->getTBAAInfo()); +                                 LD->getAAInfo());        } else {          EVT LoadVT = WideVT;          while (RemainingBytes < LoadBytes) { @@ -490,8 +521,8 @@ SDValue VectorLegalizer::ExpandLoad(SDValue Op) {          ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl, WideVT, Chain, BasePTR,                                      LD->getPointerInfo().getWithOffset(Offset),                                      LoadVT, LD->isVolatile(), -                                    LD->isNonTemporal(), LD->getAlignment(), -                                    LD->getTBAAInfo()); +                                    LD->isNonTemporal(), LD->isInvariant(), +                                    LD->getAlignment(), LD->getAAInfo());        }        RemainingBytes -= LoadBytes; @@ -561,8 +592,8 @@ SDValue VectorLegalizer::ExpandLoad(SDValue Op) {                  Op.getNode()->getValueType(0).getScalarType(),                  Chain, BasePTR, LD->getPointerInfo().getWithOffset(Idx * Stride),                  SrcVT.getScalarType(), -                LD->isVolatile(), LD->isNonTemporal(), -                LD->getAlignment(), LD->getTBAAInfo()); +                LD->isVolatile(), LD->isNonTemporal(), LD->isInvariant(), +                LD->getAlignment(), LD->getAAInfo());        BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,                           DAG.getConstant(Stride, BasePTR.getValueType())); @@ -593,7 +624,7 @@ SDValue VectorLegalizer::ExpandStore(SDValue Op) {    unsigned Alignment = ST->getAlignment();    bool isVolatile = ST->isVolatile();    bool isNonTemporal = ST->isNonTemporal(); -  const MDNode *TBAAInfo = ST->getTBAAInfo(); +  AAMDNodes AAInfo = ST->getAAInfo();    unsigned NumElem = StVT.getVectorNumElements();    // The type of the data we want to save @@ -621,7 +652,7 @@ SDValue VectorLegalizer::ExpandStore(SDValue Op) {      // 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, TBAAInfo); +               isVolatile, isNonTemporal, Alignment, AAInfo);      BasePTR = DAG.getNode(ISD::ADD, dl, BasePTR.getValueType(), BasePTR,                                 DAG.getConstant(Stride, BasePTR.getValueType()));  | 
