[llvm] r319351 - [Hexagon] Create helpers extractVector and insertVector in lowering

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 29 11:58:10 PST 2017


Author: kparzysz
Date: Wed Nov 29 11:58:10 2017
New Revision: 319351

URL: http://llvm.org/viewvc/llvm-project?rev=319351&view=rev
Log:
[Hexagon] Create helpers extractVector and insertVector in lowering

Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h

Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=319351&r1=319350&r2=319351&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Wed Nov 29 11:58:10 2017
@@ -2580,6 +2580,101 @@ HexagonTargetLowering::buildVector64(Arr
 }
 
 SDValue
+HexagonTargetLowering::extractVector(SDValue VecV, SDValue IdxV,
+                                     const SDLoc &dl, MVT ValTy, MVT ResTy,
+                                     SelectionDAG &DAG) const {
+  MVT VecTy = ty(VecV);
+  assert(!ValTy.isVector() ||
+         VecTy.getVectorElementType() == ValTy.getVectorElementType());
+  unsigned VecWidth = VecTy.getSizeInBits();
+  unsigned ValWidth = ValTy.getSizeInBits();
+  unsigned ElemWidth = VecTy.getVectorElementType().getSizeInBits();
+  assert(VecWidth == 32 || VecWidth == 64);
+  assert((VecWidth % ElemWidth) == 0);
+
+  // Cast everything to scalar integer types.
+  MVT ScalarTy = tyScalar(VecTy);
+  VecV = DAG.getBitcast(ScalarTy, VecV);
+
+  SDValue WidthV = DAG.getConstant(ValWidth, dl, MVT::i32);
+  SDValue ExtV;
+
+  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(IdxV)) {
+    unsigned Off = C->getZExtValue() * ElemWidth;
+    if (VecWidth == 64 && ValWidth == 32) {
+      assert(Off == 0 || Off == 32);
+      unsigned SubIdx = Off == 0 ? Hexagon::isub_lo : Hexagon::isub_hi;
+      ExtV = DAG.getTargetExtractSubreg(SubIdx, dl, MVT::i32, VecV);
+    } else if (Off == 0 && (ValWidth % 8) == 0) {
+      ExtV = DAG.getZeroExtendInReg(VecV, dl, tyScalar(ValTy));
+    } else {
+      SDValue OffV = DAG.getConstant(Off, dl, MVT::i32);
+      // The return type of EXTRACTU must be the same as the type of the
+      // input vector.
+      ExtV = DAG.getNode(HexagonISD::EXTRACTU, dl, ScalarTy,
+                         {VecV, WidthV, OffV});
+    }
+  } else {
+    if (ty(IdxV) != MVT::i32)
+      IdxV = DAG.getZExtOrTrunc(IdxV, dl, MVT::i32);
+    SDValue OffV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
+                               DAG.getConstant(ElemWidth, dl, MVT::i32));
+    // EXTRACTURP takes width/offset in a 64-bit pair.
+    SDValue CombV = DAG.getNode(HexagonISD::COMBINE, dl, MVT::i64,
+                                  {WidthV, OffV});
+    ExtV = DAG.getNode(HexagonISD::EXTRACTURP, dl, ScalarTy,
+                       {VecV, CombV});
+  }
+
+  // Cast ExtV to the requested result type.
+  ExtV = DAG.getZExtOrTrunc(ExtV, dl, tyScalar(ResTy));
+  ExtV = DAG.getBitcast(ResTy, ExtV);
+  return ExtV;
+}
+
+SDValue
+HexagonTargetLowering::insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
+                                    const SDLoc &dl, MVT ValTy,
+                                    SelectionDAG &DAG) const {
+  MVT VecTy = ty(VecV);
+  unsigned VecWidth = VecTy.getSizeInBits();
+  unsigned ValWidth = ValTy.getSizeInBits();
+  assert(VecWidth == 32 || VecWidth == 64);
+  assert((VecWidth % ValWidth) == 0);
+
+  // Cast everything to scalar integer types.
+  MVT ScalarTy = MVT::getIntegerVT(VecWidth);
+  // The actual type of ValV may be different than ValTy (which is related
+  // to the vector type).
+  unsigned VW = ty(ValV).getSizeInBits();
+  ValV = DAG.getBitcast(MVT::getIntegerVT(VW), ValV);
+  VecV = DAG.getBitcast(ScalarTy, VecV);
+  if (VW != VecWidth)
+    ValV = DAG.getAnyExtOrTrunc(ValV, dl, ScalarTy);
+
+  SDValue WidthV = DAG.getConstant(ValWidth, dl, MVT::i32);
+  SDValue InsV;
+
+  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(IdxV)) {
+    unsigned W = C->getZExtValue() * ValWidth;
+    SDValue OffV = DAG.getConstant(W, dl, MVT::i32);
+    InsV = DAG.getNode(HexagonISD::INSERT, dl, ScalarTy,
+                       {VecV, ValV, WidthV, OffV});
+  } else {
+    if (ty(IdxV) != MVT::i32)
+      IdxV = DAG.getZExtOrTrunc(IdxV, dl, MVT::i32);
+    SDValue OffV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, WidthV);
+    // INSERTRP takes width/offset in a 64-bit pair.
+    SDValue CombV = DAG.getNode(HexagonISD::COMBINE, dl, MVT::i64,
+                                  {WidthV, OffV});
+    InsV = DAG.getNode(HexagonISD::INSERTRP, dl, ScalarTy,
+                       {VecV, ValV, CombV});
+  }
+
+  return DAG.getNode(ISD::BITCAST, dl, VecTy, InsV);
+}
+
+SDValue
 HexagonTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
   MVT VT = Op.getValueType().getSimpleVT();
   unsigned BW = VT.getSizeInBits();
@@ -2701,145 +2796,38 @@ HexagonTargetLowering::LowerEXTRACT_SUBV
 }
 
 SDValue
-HexagonTargetLowering::LowerEXTRACT_VECTOR(SDValue Op,
-                                           SelectionDAG &DAG) const {
-  // If we are dealing with EXTRACT_SUBVECTOR on a HVX type, we may
-  // be able to simplify it to an EXTRACT_SUBREG.
-  if (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR && Subtarget.useHVXOps() &&
-      Subtarget.isHVXVectorType(Op.getValueType().getSimpleVT()))
-    return LowerEXTRACT_SUBVECTOR_HVX(Op, DAG);
-
-  EVT VT = Op.getValueType();
-  int VTN = VT.isVector() ? VT.getVectorNumElements() : 1;
-  SDLoc dl(Op);
-  SDValue Idx = Op.getOperand(1);
+HexagonTargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
+                                               SelectionDAG &DAG) const {
   SDValue Vec = Op.getOperand(0);
-  EVT VecVT = Vec.getValueType();
-  EVT EltVT = VecVT.getVectorElementType();
-  int EltSize = EltVT.getSizeInBits();
-  SDValue Width = DAG.getConstant(Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT ?
-                                  EltSize : VTN * EltSize, dl, MVT::i64);
-
-  // Constant element number.
-  if (ConstantSDNode *CI = dyn_cast<ConstantSDNode>(Idx)) {
-    uint64_t X = CI->getZExtValue();
-    SDValue Offset = DAG.getConstant(X * EltSize, dl, MVT::i32);
-    const SDValue Ops[] = {Vec, Width, Offset};
-
-    ConstantSDNode *CW = dyn_cast<ConstantSDNode>(Width);
-    assert(CW && "Non constant width in LowerEXTRACT_VECTOR");
-
-    SDValue N;
-    MVT SVT = VecVT.getSimpleVT();
-    uint64_t W = CW->getZExtValue();
-
-    if (W == 1) {
-      MVT LocVT = MVT::getIntegerVT(SVT.getSizeInBits());
-      SDValue VecCast = DAG.getNode(ISD::BITCAST, dl, LocVT, Vec);
-      SDValue Shifted = DAG.getNode(ISD::SRA, dl, LocVT, VecCast, Offset);
-      return DAG.getNode(ISD::AND, dl, LocVT, Shifted,
-                         DAG.getConstant(1, dl, LocVT));
-    } else if (W == 32) {
-      // Translate this node into EXTRACT_SUBREG.
-      unsigned Subreg = (X == 0) ? Hexagon::isub_lo : 0;
-
-      if (X == 0)
-        Subreg = Hexagon::isub_lo;
-      else if (SVT == MVT::v2i32 && X == 1)
-        Subreg = Hexagon::isub_hi;
-      else if (SVT == MVT::v4i16 && X == 2)
-        Subreg = Hexagon::isub_hi;
-      else if (SVT == MVT::v8i8 && X == 4)
-        Subreg = Hexagon::isub_hi;
-      else
-        llvm_unreachable("Bad offset");
-      N = DAG.getTargetExtractSubreg(Subreg, dl, MVT::i32, Vec);
-
-    } else if (SVT.getSizeInBits() == 32) {
-      N = DAG.getNode(HexagonISD::EXTRACTU, dl, MVT::i32, Ops);
-    } else if (SVT.getSizeInBits() == 64) {
-      N = DAG.getNode(HexagonISD::EXTRACTU, dl, MVT::i64, Ops);
-      if (VT.getSizeInBits() == 32)
-        N = DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, N);
-    } else
-      return SDValue();
-
-    return DAG.getNode(ISD::BITCAST, dl, VT, N);
-  }
-
-  // Variable element number.
-  SDValue Offset = DAG.getNode(ISD::MUL, dl, MVT::i32, Idx,
-                               DAG.getConstant(EltSize, dl, MVT::i32));
-  SDValue Shifted = DAG.getNode(ISD::SHL, dl, MVT::i64, Width,
-                                DAG.getConstant(32, dl, MVT::i64));
-  SDValue Combined = DAG.getNode(ISD::OR, dl, MVT::i64, Shifted, Offset);
-
-  const SDValue Ops[] = {Vec, Combined};
-
-  SDValue N;
-  if (VecVT.getSizeInBits() == 32) {
-    N = DAG.getNode(HexagonISD::EXTRACTURP, dl, MVT::i32, Ops);
-  } else {
-    N = DAG.getNode(HexagonISD::EXTRACTURP, dl, MVT::i64, Ops);
-    if (VT.getSizeInBits() == 32)
-      N = DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, N);
-  }
-  return DAG.getNode(ISD::BITCAST, dl, VT, N);
+  MVT ElemTy = ty(Vec).getVectorElementType();
+  return extractVector(Vec, Op.getOperand(1), SDLoc(Op), ElemTy, ty(Op), DAG);
 }
 
 SDValue
-HexagonTargetLowering::LowerINSERT_VECTOR(SDValue Op,
-                                          SelectionDAG &DAG) const {
-  EVT VT = Op.getValueType();
-  int VTN = VT.isVector() ? VT.getVectorNumElements() : 1;
-  SDLoc dl(Op);
+HexagonTargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
+                                              SelectionDAG &DAG) const {
   SDValue Vec = Op.getOperand(0);
-  SDValue Val = Op.getOperand(1);
-  SDValue Idx = Op.getOperand(2);
-  EVT VecVT = Vec.getValueType();
-  EVT EltVT = VecVT.getVectorElementType();
-  int EltSize = EltVT.getSizeInBits();
-  SDValue Width = DAG.getConstant(Op.getOpcode() == ISD::INSERT_VECTOR_ELT ?
-                                  EltSize : VTN * EltSize, dl, MVT::i64);
-
-  if (ConstantSDNode *C = cast<ConstantSDNode>(Idx)) {
-    SDValue Offset = DAG.getConstant(C->getSExtValue() * EltSize, dl, MVT::i32);
-    const SDValue Ops[] = {Vec, Val, Width, Offset};
-
-    SDValue N;
-    if (VT.getSizeInBits() == 32)
-      N = DAG.getNode(HexagonISD::INSERT, dl, MVT::i32, Ops);
-    else if (VT.getSizeInBits() == 64)
-      N = DAG.getNode(HexagonISD::INSERT, dl, MVT::i64, Ops);
-    else
-      return SDValue();
-
-    return DAG.getNode(ISD::BITCAST, dl, VT, N);
-  }
-
-  // Variable element number.
-  SDValue Offset = DAG.getNode(ISD::MUL, dl, MVT::i32, Idx,
-                               DAG.getConstant(EltSize, dl, MVT::i32));
-  SDValue Shifted = DAG.getNode(ISD::SHL, dl, MVT::i64, Width,
-                                DAG.getConstant(32, dl, MVT::i64));
-  SDValue Combined = DAG.getNode(ISD::OR, dl, MVT::i64, Shifted, Offset);
-
-  if (VT.getSizeInBits() == 64 && Val.getValueSizeInBits() == 32) {
-    SDValue C = DAG.getConstant(0, dl, MVT::i32);
-    Val = DAG.getNode(HexagonISD::COMBINE, dl, VT, C, Val);
-  }
+  MVT VecTy = ty(Vec);
+  if (Subtarget.useHVXOps() && Subtarget.isHVXVectorType(VecTy))
+    return LowerEXTRACT_SUBVECTOR_HVX(Op, DAG);
 
-  const SDValue Ops[] = {Vec, Val, Combined};
+  return extractVector(Vec, Op.getOperand(1), SDLoc(Op), ty(Op), ty(Op), DAG);
+}
 
-  SDValue N;
-  if (VT.getSizeInBits() == 32)
-    N = DAG.getNode(HexagonISD::INSERTRP, dl, MVT::i32, Ops);
-  else if (VT.getSizeInBits() == 64)
-    N = DAG.getNode(HexagonISD::INSERTRP, dl, MVT::i64, Ops);
-  else
-    return SDValue();
+SDValue
+HexagonTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
+                                              SelectionDAG &DAG) const {
+  MVT VecTy = ty(Op);
+  return insertVector(Op.getOperand(0), Op.getOperand(1), Op.getOperand(2),
+                      SDLoc(Op), VecTy.getVectorElementType(), DAG);
+}
 
-  return DAG.getNode(ISD::BITCAST, dl, VT, N);
+SDValue
+HexagonTargetLowering::LowerINSERT_SUBVECTOR(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  SDValue ValV = Op.getOperand(1);
+  return insertVector(Op.getOperand(0), ValV, Op.getOperand(2),
+                      SDLoc(Op), ty(ValV), DAG);
 }
 
 bool
@@ -2894,10 +2882,10 @@ HexagonTargetLowering::LowerOperation(SD
 #endif
       llvm_unreachable("Should not custom lower this!");
     case ISD::CONCAT_VECTORS:       return LowerCONCAT_VECTORS(Op, DAG);
-    case ISD::INSERT_SUBVECTOR:     return LowerINSERT_VECTOR(Op, DAG);
-    case ISD::INSERT_VECTOR_ELT:    return LowerINSERT_VECTOR(Op, DAG);
-    case ISD::EXTRACT_SUBVECTOR:    return LowerEXTRACT_VECTOR(Op, DAG);
-    case ISD::EXTRACT_VECTOR_ELT:   return LowerEXTRACT_VECTOR(Op, DAG);
+    case ISD::INSERT_SUBVECTOR:     return LowerINSERT_SUBVECTOR(Op, DAG);
+    case ISD::INSERT_VECTOR_ELT:    return LowerINSERT_VECTOR_ELT(Op, DAG);
+    case ISD::EXTRACT_SUBVECTOR:    return LowerEXTRACT_SUBVECTOR(Op, DAG);
+    case ISD::EXTRACT_VECTOR_ELT:   return LowerEXTRACT_VECTOR_ELT(Op, DAG);
     case ISD::BUILD_VECTOR:         return LowerBUILD_VECTOR(Op, DAG);
     case ISD::VECTOR_SHUFFLE:       return LowerVECTOR_SHUFFLE(Op, DAG);
     case ISD::SRA:

Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h?rev=319351&r1=319350&r2=319351&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h Wed Nov 29 11:58:10 2017
@@ -117,13 +117,17 @@ namespace HexagonISD {
 
     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
     const char *getTargetNodeName(unsigned Opcode) const override;
+
+    SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
-    SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerEXTRACT_SUBVECTOR_HVX(SDValue Op, SelectionDAG &DAG) const;
-    SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const;
-    SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
+
     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
@@ -269,11 +273,24 @@ namespace HexagonISD {
       return AtomicExpansionKind::LLSC;
     }
 
-  protected:
+  private:
+    MVT ty(SDValue Op) const {
+      return Op.getValueType().getSimpleVT();
+    }
+    MVT tyScalar(MVT Ty) const {
+      if (!Ty.isVector())
+        return Ty;
+      return MVT::getIntegerVT(Ty.getSizeInBits());
+    }
+
     SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
                           SelectionDAG &DAG) const;
     SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy,
                           SelectionDAG &DAG) const;
+    SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl,
+                          MVT ValTy, MVT ResTy, SelectionDAG &DAG) const;
+    SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
+                         const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const;
 
     std::pair<const TargetRegisterClass*, uint8_t>
     findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)




More information about the llvm-commits mailing list