LLVM  8.0.1
HexagonISelLoweringHVX.cpp
Go to the documentation of this file.
1 //===-- HexagonISelLoweringHVX.cpp --- Lowering HVX operations ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "HexagonISelLowering.h"
11 #include "HexagonRegisterInfo.h"
12 #include "HexagonSubtarget.h"
14 
15 using namespace llvm;
16 
21 
22 
23 void
24 HexagonTargetLowering::initializeHVXLowering() {
25  if (Subtarget.useHVX64BOps()) {
26  addRegisterClass(MVT::v64i8, &Hexagon::HvxVRRegClass);
27  addRegisterClass(MVT::v32i16, &Hexagon::HvxVRRegClass);
28  addRegisterClass(MVT::v16i32, &Hexagon::HvxVRRegClass);
29  addRegisterClass(MVT::v128i8, &Hexagon::HvxWRRegClass);
30  addRegisterClass(MVT::v64i16, &Hexagon::HvxWRRegClass);
31  addRegisterClass(MVT::v32i32, &Hexagon::HvxWRRegClass);
32  // These "short" boolean vector types should be legal because
33  // they will appear as results of vector compares. If they were
34  // not legal, type legalization would try to make them legal
35  // and that would require using operations that do not use or
36  // produce such types. That, in turn, would imply using custom
37  // nodes, which would be unoptimizable by the DAG combiner.
38  // The idea is to rely on target-independent operations as much
39  // as possible.
40  addRegisterClass(MVT::v16i1, &Hexagon::HvxQRRegClass);
41  addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
42  addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
43  addRegisterClass(MVT::v512i1, &Hexagon::HvxQRRegClass);
44  } else if (Subtarget.useHVX128BOps()) {
45  addRegisterClass(MVT::v128i8, &Hexagon::HvxVRRegClass);
46  addRegisterClass(MVT::v64i16, &Hexagon::HvxVRRegClass);
47  addRegisterClass(MVT::v32i32, &Hexagon::HvxVRRegClass);
48  addRegisterClass(MVT::v256i8, &Hexagon::HvxWRRegClass);
49  addRegisterClass(MVT::v128i16, &Hexagon::HvxWRRegClass);
50  addRegisterClass(MVT::v64i32, &Hexagon::HvxWRRegClass);
51  addRegisterClass(MVT::v32i1, &Hexagon::HvxQRRegClass);
52  addRegisterClass(MVT::v64i1, &Hexagon::HvxQRRegClass);
53  addRegisterClass(MVT::v128i1, &Hexagon::HvxQRRegClass);
54  addRegisterClass(MVT::v1024i1, &Hexagon::HvxQRRegClass);
55  }
56 
57  // Set up operation actions.
58 
59  bool Use64b = Subtarget.useHVX64BOps();
60  ArrayRef<MVT> LegalV = Use64b ? LegalV64 : LegalV128;
61  ArrayRef<MVT> LegalW = Use64b ? LegalW64 : LegalW128;
62  MVT ByteV = Use64b ? MVT::v64i8 : MVT::v128i8;
63  MVT ByteW = Use64b ? MVT::v128i8 : MVT::v256i8;
64 
65  auto setPromoteTo = [this] (unsigned Opc, MVT FromTy, MVT ToTy) {
66  setOperationAction(Opc, FromTy, Promote);
67  AddPromotedToType(Opc, FromTy, ToTy);
68  };
69 
72 
73  for (MVT T : LegalV) {
76 
84  if (T != ByteV) {
88  }
89 
96  // Make concat-vectors custom to handle concats of more than 2 vectors.
105  if (T != ByteV) {
107  // HVX only has shifts of words and halfwords.
111 
112  // Promote all shuffles to operate on vectors of bytes.
113  setPromoteTo(ISD::VECTOR_SHUFFLE, T, ByteV);
114  }
115 
123  }
124 
125  for (MVT T : LegalW) {
126  // Custom-lower BUILD_VECTOR for vector pairs. The standard (target-
127  // independent) handling of it would convert it to a load, which is
128  // not always the optimal choice.
130  // Make concat-vectors custom to handle concats of more than 2 vectors.
132 
133  // Custom-lower these operations for pairs. Expand them into a concat
134  // of the corresponding operations on individual vectors.
142 
148 
159  if (T != ByteW) {
163 
164  // Promote all shuffles to operate on vectors of bytes.
165  setPromoteTo(ISD::VECTOR_SHUFFLE, T, ByteW);
166  }
167  }
168 
169  // Boolean vectors.
170 
171  for (MVT T : LegalW) {
172  // Boolean types for vector pairs will overlap with the boolean
173  // types for single vectors, e.g.
174  // v64i8 -> v64i1 (single)
175  // v64i16 -> v64i1 (pair)
176  // Set these actions first, and allow the single actions to overwrite
177  // any duplicates.
178  MVT BoolW = MVT::getVectorVT(MVT::i1, T.getVectorNumElements());
183  }
184 
185  for (MVT T : LegalV) {
186  MVT BoolV = MVT::getVectorVT(MVT::i1, T.getVectorNumElements());
196  }
197 }
198 
199 SDValue
200 HexagonTargetLowering::getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops,
201  const SDLoc &dl, SelectionDAG &DAG) const {
202  SmallVector<SDValue,4> IntOps;
203  IntOps.push_back(DAG.getConstant(IntId, dl, MVT::i32));
204  for (const SDValue &Op : Ops)
205  IntOps.push_back(Op);
206  return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, ResTy, IntOps);
207 }
208 
209 MVT
210 HexagonTargetLowering::typeJoin(const TypePair &Tys) const {
211  assert(Tys.first.getVectorElementType() == Tys.second.getVectorElementType());
212 
213  MVT ElemTy = Tys.first.getVectorElementType();
214  return MVT::getVectorVT(ElemTy, Tys.first.getVectorNumElements() +
215  Tys.second.getVectorNumElements());
216 }
217 
218 HexagonTargetLowering::TypePair
219 HexagonTargetLowering::typeSplit(MVT VecTy) const {
220  assert(VecTy.isVector());
221  unsigned NumElem = VecTy.getVectorNumElements();
222  assert((NumElem % 2) == 0 && "Expecting even-sized vector type");
223  MVT HalfTy = MVT::getVectorVT(VecTy.getVectorElementType(), NumElem/2);
224  return { HalfTy, HalfTy };
225 }
226 
227 MVT
228 HexagonTargetLowering::typeExtElem(MVT VecTy, unsigned Factor) const {
229  MVT ElemTy = VecTy.getVectorElementType();
230  MVT NewElemTy = MVT::getIntegerVT(ElemTy.getSizeInBits() * Factor);
231  return MVT::getVectorVT(NewElemTy, VecTy.getVectorNumElements());
232 }
233 
234 MVT
235 HexagonTargetLowering::typeTruncElem(MVT VecTy, unsigned Factor) const {
236  MVT ElemTy = VecTy.getVectorElementType();
237  MVT NewElemTy = MVT::getIntegerVT(ElemTy.getSizeInBits() / Factor);
238  return MVT::getVectorVT(NewElemTy, VecTy.getVectorNumElements());
239 }
240 
241 SDValue
242 HexagonTargetLowering::opCastElem(SDValue Vec, MVT ElemTy,
243  SelectionDAG &DAG) const {
244  if (ty(Vec).getVectorElementType() == ElemTy)
245  return Vec;
246  MVT CastTy = tyVector(Vec.getValueType().getSimpleVT(), ElemTy);
247  return DAG.getBitcast(CastTy, Vec);
248 }
249 
250 SDValue
251 HexagonTargetLowering::opJoin(const VectorPair &Ops, const SDLoc &dl,
252  SelectionDAG &DAG) const {
253  return DAG.getNode(ISD::CONCAT_VECTORS, dl, typeJoin(ty(Ops)),
254  Ops.second, Ops.first);
255 }
256 
257 HexagonTargetLowering::VectorPair
258 HexagonTargetLowering::opSplit(SDValue Vec, const SDLoc &dl,
259  SelectionDAG &DAG) const {
260  TypePair Tys = typeSplit(ty(Vec));
261  if (Vec.getOpcode() == HexagonISD::QCAT)
262  return VectorPair(Vec.getOperand(0), Vec.getOperand(1));
263  return DAG.SplitVector(Vec, dl, Tys.first, Tys.second);
264 }
265 
266 bool
267 HexagonTargetLowering::isHvxSingleTy(MVT Ty) const {
268  return Subtarget.isHVXVectorType(Ty) &&
269  Ty.getSizeInBits() == 8 * Subtarget.getVectorLength();
270 }
271 
272 bool
273 HexagonTargetLowering::isHvxPairTy(MVT Ty) const {
274  return Subtarget.isHVXVectorType(Ty) &&
275  Ty.getSizeInBits() == 16 * Subtarget.getVectorLength();
276 }
277 
278 SDValue
279 HexagonTargetLowering::convertToByteIndex(SDValue ElemIdx, MVT ElemTy,
280  SelectionDAG &DAG) const {
281  if (ElemIdx.getValueType().getSimpleVT() != MVT::i32)
282  ElemIdx = DAG.getBitcast(MVT::i32, ElemIdx);
283 
284  unsigned ElemWidth = ElemTy.getSizeInBits();
285  if (ElemWidth == 8)
286  return ElemIdx;
287 
288  unsigned L = Log2_32(ElemWidth/8);
289  const SDLoc &dl(ElemIdx);
290  return DAG.getNode(ISD::SHL, dl, MVT::i32,
291  {ElemIdx, DAG.getConstant(L, dl, MVT::i32)});
292 }
293 
294 SDValue
295 HexagonTargetLowering::getIndexInWord32(SDValue Idx, MVT ElemTy,
296  SelectionDAG &DAG) const {
297  unsigned ElemWidth = ElemTy.getSizeInBits();
298  assert(ElemWidth >= 8 && ElemWidth <= 32);
299  if (ElemWidth == 32)
300  return Idx;
301 
302  if (ty(Idx) != MVT::i32)
303  Idx = DAG.getBitcast(MVT::i32, Idx);
304  const SDLoc &dl(Idx);
305  SDValue Mask = DAG.getConstant(32/ElemWidth - 1, dl, MVT::i32);
306  SDValue SubIdx = DAG.getNode(ISD::AND, dl, MVT::i32, {Idx, Mask});
307  return SubIdx;
308 }
309 
310 SDValue
311 HexagonTargetLowering::getByteShuffle(const SDLoc &dl, SDValue Op0,
313  SelectionDAG &DAG) const {
314  MVT OpTy = ty(Op0);
315  assert(OpTy == ty(Op1));
316 
317  MVT ElemTy = OpTy.getVectorElementType();
318  if (ElemTy == MVT::i8)
319  return DAG.getVectorShuffle(OpTy, dl, Op0, Op1, Mask);
320  assert(ElemTy.getSizeInBits() >= 8);
321 
322  MVT ResTy = tyVector(OpTy, MVT::i8);
323  unsigned ElemSize = ElemTy.getSizeInBits() / 8;
324 
325  SmallVector<int,128> ByteMask;
326  for (int M : Mask) {
327  if (M < 0) {
328  for (unsigned I = 0; I != ElemSize; ++I)
329  ByteMask.push_back(-1);
330  } else {
331  int NewM = M*ElemSize;
332  for (unsigned I = 0; I != ElemSize; ++I)
333  ByteMask.push_back(NewM+I);
334  }
335  }
336  assert(ResTy.getVectorNumElements() == ByteMask.size());
337  return DAG.getVectorShuffle(ResTy, dl, opCastElem(Op0, MVT::i8, DAG),
338  opCastElem(Op1, MVT::i8, DAG), ByteMask);
339 }
340 
341 SDValue
342 HexagonTargetLowering::buildHvxVectorReg(ArrayRef<SDValue> Values,
343  const SDLoc &dl, MVT VecTy,
344  SelectionDAG &DAG) const {
345  unsigned VecLen = Values.size();
347  MVT ElemTy = VecTy.getVectorElementType();
348  unsigned ElemWidth = ElemTy.getSizeInBits();
349  unsigned HwLen = Subtarget.getVectorLength();
350 
351  unsigned ElemSize = ElemWidth / 8;
352  assert(ElemSize*VecLen == HwLen);
354 
355  if (VecTy.getVectorElementType() != MVT::i32) {
356  assert((ElemSize == 1 || ElemSize == 2) && "Invalid element size");
357  unsigned OpsPerWord = (ElemSize == 1) ? 4 : 2;
358  MVT PartVT = MVT::getVectorVT(VecTy.getVectorElementType(), OpsPerWord);
359  for (unsigned i = 0; i != VecLen; i += OpsPerWord) {
360  SDValue W = buildVector32(Values.slice(i, OpsPerWord), dl, PartVT, DAG);
361  Words.push_back(DAG.getBitcast(MVT::i32, W));
362  }
363  } else {
364  Words.assign(Values.begin(), Values.end());
365  }
366 
367  unsigned NumWords = Words.size();
368  bool IsSplat = true, IsUndef = true;
369  SDValue SplatV;
370  for (unsigned i = 0; i != NumWords && IsSplat; ++i) {
371  if (isUndef(Words[i]))
372  continue;
373  IsUndef = false;
374  if (!SplatV.getNode())
375  SplatV = Words[i];
376  else if (SplatV != Words[i])
377  IsSplat = false;
378  }
379  if (IsUndef)
380  return DAG.getUNDEF(VecTy);
381  if (IsSplat) {
382  assert(SplatV.getNode());
383  auto *IdxN = dyn_cast<ConstantSDNode>(SplatV.getNode());
384  if (IdxN && IdxN->isNullValue())
385  return getZero(dl, VecTy, DAG);
386  return DAG.getNode(HexagonISD::VSPLATW, dl, VecTy, SplatV);
387  }
388 
389  // Delay recognizing constant vectors until here, so that we can generate
390  // a vsplat.
391  SmallVector<ConstantInt*, 128> Consts(VecLen);
392  bool AllConst = getBuildVectorConstInts(Values, VecTy, DAG, Consts);
393  if (AllConst) {
394  ArrayRef<Constant*> Tmp((Constant**)Consts.begin(),
395  (Constant**)Consts.end());
396  Constant *CV = ConstantVector::get(Tmp);
397  unsigned Align = HwLen;
398  SDValue CP = LowerConstantPool(DAG.getConstantPool(CV, VecTy, Align), DAG);
399  return DAG.getLoad(VecTy, dl, DAG.getEntryNode(), CP,
401  }
402 
403  // A special case is a situation where the vector is built entirely from
404  // elements extracted from another vector. This could be done via a shuffle
405  // more efficiently, but typically, the size of the source vector will not
406  // match the size of the vector being built (which precludes the use of a
407  // shuffle directly).
408  // This only handles a single source vector, and the vector being built
409  // should be of a sub-vector type of the source vector type.
410  auto IsBuildFromExtracts = [this,&Values] (SDValue &SrcVec,
411  SmallVectorImpl<int> &SrcIdx) {
412  SDValue Vec;
413  for (SDValue V : Values) {
414  if (isUndef(V)) {
415  SrcIdx.push_back(-1);
416  continue;
417  }
418  if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
419  return false;
420  // All extracts should come from the same vector.
421  SDValue T = V.getOperand(0);
422  if (Vec.getNode() != nullptr && T.getNode() != Vec.getNode())
423  return false;
424  Vec = T;
425  ConstantSDNode *C = dyn_cast<ConstantSDNode>(V.getOperand(1));
426  if (C == nullptr)
427  return false;
428  int I = C->getSExtValue();
429  assert(I >= 0 && "Negative element index");
430  SrcIdx.push_back(I);
431  }
432  SrcVec = Vec;
433  return true;
434  };
435 
436  SmallVector<int,128> ExtIdx;
437  SDValue ExtVec;
438  if (IsBuildFromExtracts(ExtVec, ExtIdx)) {
439  MVT ExtTy = ty(ExtVec);
440  unsigned ExtLen = ExtTy.getVectorNumElements();
441  if (ExtLen == VecLen || ExtLen == 2*VecLen) {
442  // Construct a new shuffle mask that will produce a vector with the same
443  // number of elements as the input vector, and such that the vector we
444  // want will be the initial subvector of it.
446  BitVector Used(ExtLen);
447 
448  for (int M : ExtIdx) {
449  Mask.push_back(M);
450  if (M >= 0)
451  Used.set(M);
452  }
453  // Fill the rest of the mask with the unused elements of ExtVec in hopes
454  // that it will result in a permutation of ExtVec's elements. It's still
455  // fine if it doesn't (e.g. if undefs are present, or elements are
456  // repeated), but permutations can always be done efficiently via vdelta
457  // and vrdelta.
458  for (unsigned I = 0; I != ExtLen; ++I) {
459  if (Mask.size() == ExtLen)
460  break;
461  if (!Used.test(I))
462  Mask.push_back(I);
463  }
464 
465  SDValue S = DAG.getVectorShuffle(ExtTy, dl, ExtVec,
466  DAG.getUNDEF(ExtTy), Mask);
467  if (ExtLen == VecLen)
468  return S;
469  return DAG.getTargetExtractSubreg(Hexagon::vsub_lo, dl, VecTy, S);
470  }
471  }
472 
473  // Construct two halves in parallel, then or them together.
474  assert(4*Words.size() == Subtarget.getVectorLength());
475  SDValue HalfV0 = getInstr(Hexagon::V6_vd0, dl, VecTy, {}, DAG);
476  SDValue HalfV1 = getInstr(Hexagon::V6_vd0, dl, VecTy, {}, DAG);
477  SDValue S = DAG.getConstant(4, dl, MVT::i32);
478  for (unsigned i = 0; i != NumWords/2; ++i) {
479  SDValue N = DAG.getNode(HexagonISD::VINSERTW0, dl, VecTy,
480  {HalfV0, Words[i]});
481  SDValue M = DAG.getNode(HexagonISD::VINSERTW0, dl, VecTy,
482  {HalfV1, Words[i+NumWords/2]});
483  HalfV0 = DAG.getNode(HexagonISD::VROR, dl, VecTy, {N, S});
484  HalfV1 = DAG.getNode(HexagonISD::VROR, dl, VecTy, {M, S});
485  }
486 
487  HalfV0 = DAG.getNode(HexagonISD::VROR, dl, VecTy,
488  {HalfV0, DAG.getConstant(HwLen/2, dl, MVT::i32)});
489  SDValue DstV = DAG.getNode(ISD::OR, dl, VecTy, {HalfV0, HalfV1});
490  return DstV;
491 }
492 
493 SDValue
494 HexagonTargetLowering::createHvxPrefixPred(SDValue PredV, const SDLoc &dl,
495  unsigned BitBytes, bool ZeroFill, SelectionDAG &DAG) const {
496  MVT PredTy = ty(PredV);
497  unsigned HwLen = Subtarget.getVectorLength();
498  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
499 
500  if (Subtarget.isHVXVectorType(PredTy, true)) {
501  // Move the vector predicate SubV to a vector register, and scale it
502  // down to match the representation (bytes per type element) that VecV
503  // uses. The scaling down will pick every 2nd or 4th (every Scale-th
504  // in general) element and put them at the front of the resulting
505  // vector. This subvector will then be inserted into the Q2V of VecV.
506  // To avoid having an operation that generates an illegal type (short
507  // vector), generate a full size vector.
508  //
509  SDValue T = DAG.getNode(HexagonISD::Q2V, dl, ByteTy, PredV);
510  SmallVector<int,128> Mask(HwLen);
511  // Scale = BitBytes(PredV) / Given BitBytes.
512  unsigned Scale = HwLen / (PredTy.getVectorNumElements() * BitBytes);
513  unsigned BlockLen = PredTy.getVectorNumElements() * BitBytes;
514 
515  for (unsigned i = 0; i != HwLen; ++i) {
516  unsigned Num = i % Scale;
517  unsigned Off = i / Scale;
518  Mask[BlockLen*Num + Off] = i;
519  }
520  SDValue S = DAG.getVectorShuffle(ByteTy, dl, T, DAG.getUNDEF(ByteTy), Mask);
521  if (!ZeroFill)
522  return S;
523  // Fill the bytes beyond BlockLen with 0s.
524  MVT BoolTy = MVT::getVectorVT(MVT::i1, HwLen);
525  SDValue Q = getInstr(Hexagon::V6_pred_scalar2, dl, BoolTy,
526  {DAG.getConstant(BlockLen, dl, MVT::i32)}, DAG);
527  SDValue M = DAG.getNode(HexagonISD::Q2V, dl, ByteTy, Q);
528  return DAG.getNode(ISD::AND, dl, ByteTy, S, M);
529  }
530 
531  // Make sure that this is a valid scalar predicate.
532  assert(PredTy == MVT::v2i1 || PredTy == MVT::v4i1 || PredTy == MVT::v8i1);
533 
534  unsigned Bytes = 8 / PredTy.getVectorNumElements();
535  SmallVector<SDValue,4> Words[2];
536  unsigned IdxW = 0;
537 
538  auto Lo32 = [&DAG, &dl] (SDValue P) {
539  return DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, P);
540  };
541  auto Hi32 = [&DAG, &dl] (SDValue P) {
542  return DAG.getTargetExtractSubreg(Hexagon::isub_hi, dl, MVT::i32, P);
543  };
544 
545  SDValue W0 = isUndef(PredV)
546  ? DAG.getUNDEF(MVT::i64)
547  : DAG.getNode(HexagonISD::P2D, dl, MVT::i64, PredV);
548  Words[IdxW].push_back(Hi32(W0));
549  Words[IdxW].push_back(Lo32(W0));
550 
551  while (Bytes < BitBytes) {
552  IdxW ^= 1;
553  Words[IdxW].clear();
554 
555  if (Bytes < 4) {
556  for (const SDValue &W : Words[IdxW ^ 1]) {
557  SDValue T = expandPredicate(W, dl, DAG);
558  Words[IdxW].push_back(Hi32(T));
559  Words[IdxW].push_back(Lo32(T));
560  }
561  } else {
562  for (const SDValue &W : Words[IdxW ^ 1]) {
563  Words[IdxW].push_back(W);
564  Words[IdxW].push_back(W);
565  }
566  }
567  Bytes *= 2;
568  }
569 
570  assert(Bytes == BitBytes);
571 
572  SDValue Vec = ZeroFill ? getZero(dl, ByteTy, DAG) : DAG.getUNDEF(ByteTy);
573  SDValue S4 = DAG.getConstant(HwLen-4, dl, MVT::i32);
574  for (const SDValue &W : Words[IdxW]) {
575  Vec = DAG.getNode(HexagonISD::VROR, dl, ByteTy, Vec, S4);
576  Vec = DAG.getNode(HexagonISD::VINSERTW0, dl, ByteTy, Vec, W);
577  }
578 
579  return Vec;
580 }
581 
582 SDValue
583 HexagonTargetLowering::buildHvxVectorPred(ArrayRef<SDValue> Values,
584  const SDLoc &dl, MVT VecTy,
585  SelectionDAG &DAG) const {
586  // Construct a vector V of bytes, such that a comparison V >u 0 would
587  // produce the required vector predicate.
588  unsigned VecLen = Values.size();
589  unsigned HwLen = Subtarget.getVectorLength();
590  assert(VecLen <= HwLen || VecLen == 8*HwLen);
592  bool AllT = true, AllF = true;
593 
594  auto IsTrue = [] (SDValue V) {
595  if (const auto *N = dyn_cast<ConstantSDNode>(V.getNode()))
596  return !N->isNullValue();
597  return false;
598  };
599  auto IsFalse = [] (SDValue V) {
600  if (const auto *N = dyn_cast<ConstantSDNode>(V.getNode()))
601  return N->isNullValue();
602  return false;
603  };
604 
605  if (VecLen <= HwLen) {
606  // In the hardware, each bit of a vector predicate corresponds to a byte
607  // of a vector register. Calculate how many bytes does a bit of VecTy
608  // correspond to.
609  assert(HwLen % VecLen == 0);
610  unsigned BitBytes = HwLen / VecLen;
611  for (SDValue V : Values) {
612  AllT &= IsTrue(V);
613  AllF &= IsFalse(V);
614 
615  SDValue Ext = !V.isUndef() ? DAG.getZExtOrTrunc(V, dl, MVT::i8)
616  : DAG.getUNDEF(MVT::i8);
617  for (unsigned B = 0; B != BitBytes; ++B)
618  Bytes.push_back(Ext);
619  }
620  } else {
621  // There are as many i1 values, as there are bits in a vector register.
622  // Divide the values into groups of 8 and check that each group consists
623  // of the same value (ignoring undefs).
624  for (unsigned I = 0; I != VecLen; I += 8) {
625  unsigned B = 0;
626  // Find the first non-undef value in this group.
627  for (; B != 8; ++B) {
628  if (!Values[I+B].isUndef())
629  break;
630  }
631  SDValue F = Values[I+B];
632  AllT &= IsTrue(F);
633  AllF &= IsFalse(F);
634 
635  SDValue Ext = (B < 8) ? DAG.getZExtOrTrunc(F, dl, MVT::i8)
636  : DAG.getUNDEF(MVT::i8);
637  Bytes.push_back(Ext);
638  // Verify that the rest of values in the group are the same as the
639  // first.
640  for (; B != 8; ++B)
641  assert(Values[I+B].isUndef() || Values[I+B] == F);
642  }
643  }
644 
645  if (AllT)
646  return DAG.getNode(HexagonISD::QTRUE, dl, VecTy);
647  if (AllF)
648  return DAG.getNode(HexagonISD::QFALSE, dl, VecTy);
649 
650  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
651  SDValue ByteVec = buildHvxVectorReg(Bytes, dl, ByteTy, DAG);
652  return DAG.getNode(HexagonISD::V2Q, dl, VecTy, ByteVec);
653 }
654 
655 SDValue
656 HexagonTargetLowering::extractHvxElementReg(SDValue VecV, SDValue IdxV,
657  const SDLoc &dl, MVT ResTy, SelectionDAG &DAG) const {
658  MVT ElemTy = ty(VecV).getVectorElementType();
659 
660  unsigned ElemWidth = ElemTy.getSizeInBits();
661  assert(ElemWidth >= 8 && ElemWidth <= 32);
662  (void)ElemWidth;
663 
664  SDValue ByteIdx = convertToByteIndex(IdxV, ElemTy, DAG);
665  SDValue ExWord = DAG.getNode(HexagonISD::VEXTRACTW, dl, MVT::i32,
666  {VecV, ByteIdx});
667  if (ElemTy == MVT::i32)
668  return ExWord;
669 
670  // Have an extracted word, need to extract the smaller element out of it.
671  // 1. Extract the bits of (the original) IdxV that correspond to the index
672  // of the desired element in the 32-bit word.
673  SDValue SubIdx = getIndexInWord32(IdxV, ElemTy, DAG);
674  // 2. Extract the element from the word.
675  SDValue ExVec = DAG.getBitcast(tyVector(ty(ExWord), ElemTy), ExWord);
676  return extractVector(ExVec, SubIdx, dl, ElemTy, MVT::i32, DAG);
677 }
678 
679 SDValue
680 HexagonTargetLowering::extractHvxElementPred(SDValue VecV, SDValue IdxV,
681  const SDLoc &dl, MVT ResTy, SelectionDAG &DAG) const {
682  // Implement other return types if necessary.
683  assert(ResTy == MVT::i1);
684 
685  unsigned HwLen = Subtarget.getVectorLength();
686  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
687  SDValue ByteVec = DAG.getNode(HexagonISD::Q2V, dl, ByteTy, VecV);
688 
689  unsigned Scale = HwLen / ty(VecV).getVectorNumElements();
690  SDValue ScV = DAG.getConstant(Scale, dl, MVT::i32);
691  IdxV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, ScV);
692 
693  SDValue ExtB = extractHvxElementReg(ByteVec, IdxV, dl, MVT::i32, DAG);
694  SDValue Zero = DAG.getTargetConstant(0, dl, MVT::i32);
695  return getInstr(Hexagon::C2_cmpgtui, dl, MVT::i1, {ExtB, Zero}, DAG);
696 }
697 
698 SDValue
699 HexagonTargetLowering::insertHvxElementReg(SDValue VecV, SDValue IdxV,
700  SDValue ValV, const SDLoc &dl, SelectionDAG &DAG) const {
701  MVT ElemTy = ty(VecV).getVectorElementType();
702 
703  unsigned ElemWidth = ElemTy.getSizeInBits();
704  assert(ElemWidth >= 8 && ElemWidth <= 32);
705  (void)ElemWidth;
706 
707  auto InsertWord = [&DAG,&dl,this] (SDValue VecV, SDValue ValV,
708  SDValue ByteIdxV) {
709  MVT VecTy = ty(VecV);
710  unsigned HwLen = Subtarget.getVectorLength();
711  SDValue MaskV = DAG.getNode(ISD::AND, dl, MVT::i32,
712  {ByteIdxV, DAG.getConstant(-4, dl, MVT::i32)});
713  SDValue RotV = DAG.getNode(HexagonISD::VROR, dl, VecTy, {VecV, MaskV});
714  SDValue InsV = DAG.getNode(HexagonISD::VINSERTW0, dl, VecTy, {RotV, ValV});
715  SDValue SubV = DAG.getNode(ISD::SUB, dl, MVT::i32,
716  {DAG.getConstant(HwLen, dl, MVT::i32), MaskV});
717  SDValue TorV = DAG.getNode(HexagonISD::VROR, dl, VecTy, {InsV, SubV});
718  return TorV;
719  };
720 
721  SDValue ByteIdx = convertToByteIndex(IdxV, ElemTy, DAG);
722  if (ElemTy == MVT::i32)
723  return InsertWord(VecV, ValV, ByteIdx);
724 
725  // If this is not inserting a 32-bit word, convert it into such a thing.
726  // 1. Extract the existing word from the target vector.
727  SDValue WordIdx = DAG.getNode(ISD::SRL, dl, MVT::i32,
728  {ByteIdx, DAG.getConstant(2, dl, MVT::i32)});
729  SDValue Ext = extractHvxElementReg(opCastElem(VecV, MVT::i32, DAG), WordIdx,
730  dl, MVT::i32, DAG);
731 
732  // 2. Treating the extracted word as a 32-bit vector, insert the given
733  // value into it.
734  SDValue SubIdx = getIndexInWord32(IdxV, ElemTy, DAG);
735  MVT SubVecTy = tyVector(ty(Ext), ElemTy);
736  SDValue Ins = insertVector(DAG.getBitcast(SubVecTy, Ext),
737  ValV, SubIdx, dl, ElemTy, DAG);
738 
739  // 3. Insert the 32-bit word back into the original vector.
740  return InsertWord(VecV, Ins, ByteIdx);
741 }
742 
743 SDValue
744 HexagonTargetLowering::insertHvxElementPred(SDValue VecV, SDValue IdxV,
745  SDValue ValV, const SDLoc &dl, SelectionDAG &DAG) const {
746  unsigned HwLen = Subtarget.getVectorLength();
747  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
748  SDValue ByteVec = DAG.getNode(HexagonISD::Q2V, dl, ByteTy, VecV);
749 
750  unsigned Scale = HwLen / ty(VecV).getVectorNumElements();
751  SDValue ScV = DAG.getConstant(Scale, dl, MVT::i32);
752  IdxV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV, ScV);
753  ValV = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i32, ValV);
754 
755  SDValue InsV = insertHvxElementReg(ByteVec, IdxV, ValV, dl, DAG);
756  return DAG.getNode(HexagonISD::V2Q, dl, ty(VecV), InsV);
757 }
758 
759 SDValue
760 HexagonTargetLowering::extractHvxSubvectorReg(SDValue VecV, SDValue IdxV,
761  const SDLoc &dl, MVT ResTy, SelectionDAG &DAG) const {
762  MVT VecTy = ty(VecV);
763  unsigned HwLen = Subtarget.getVectorLength();
764  unsigned Idx = cast<ConstantSDNode>(IdxV.getNode())->getZExtValue();
765  MVT ElemTy = VecTy.getVectorElementType();
766  unsigned ElemWidth = ElemTy.getSizeInBits();
767 
768  // If the source vector is a vector pair, get the single vector containing
769  // the subvector of interest. The subvector will never overlap two single
770  // vectors.
771  if (isHvxPairTy(VecTy)) {
772  unsigned SubIdx;
773  if (Idx * ElemWidth >= 8*HwLen) {
774  SubIdx = Hexagon::vsub_hi;
775  Idx -= VecTy.getVectorNumElements() / 2;
776  } else {
777  SubIdx = Hexagon::vsub_lo;
778  }
779  VecTy = typeSplit(VecTy).first;
780  VecV = DAG.getTargetExtractSubreg(SubIdx, dl, VecTy, VecV);
781  if (VecTy == ResTy)
782  return VecV;
783  }
784 
785  // The only meaningful subvectors of a single HVX vector are those that
786  // fit in a scalar register.
787  assert(ResTy.getSizeInBits() == 32 || ResTy.getSizeInBits() == 64);
788 
789  MVT WordTy = tyVector(VecTy, MVT::i32);
790  SDValue WordVec = DAG.getBitcast(WordTy, VecV);
791  unsigned WordIdx = (Idx*ElemWidth) / 32;
792 
793  SDValue W0Idx = DAG.getConstant(WordIdx, dl, MVT::i32);
794  SDValue W0 = extractHvxElementReg(WordVec, W0Idx, dl, MVT::i32, DAG);
795  if (ResTy.getSizeInBits() == 32)
796  return DAG.getBitcast(ResTy, W0);
797 
798  SDValue W1Idx = DAG.getConstant(WordIdx+1, dl, MVT::i32);
799  SDValue W1 = extractHvxElementReg(WordVec, W1Idx, dl, MVT::i32, DAG);
800  SDValue WW = DAG.getNode(HexagonISD::COMBINE, dl, MVT::i64, {W1, W0});
801  return DAG.getBitcast(ResTy, WW);
802 }
803 
804 SDValue
805 HexagonTargetLowering::extractHvxSubvectorPred(SDValue VecV, SDValue IdxV,
806  const SDLoc &dl, MVT ResTy, SelectionDAG &DAG) const {
807  MVT VecTy = ty(VecV);
808  unsigned HwLen = Subtarget.getVectorLength();
809  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
810  SDValue ByteVec = DAG.getNode(HexagonISD::Q2V, dl, ByteTy, VecV);
811  // IdxV is required to be a constant.
812  unsigned Idx = cast<ConstantSDNode>(IdxV.getNode())->getZExtValue();
813 
814  unsigned ResLen = ResTy.getVectorNumElements();
815  unsigned BitBytes = HwLen / VecTy.getVectorNumElements();
816  unsigned Offset = Idx * BitBytes;
817  SDValue Undef = DAG.getUNDEF(ByteTy);
819 
820  if (Subtarget.isHVXVectorType(ResTy, true)) {
821  // Converting between two vector predicates. Since the result is shorter
822  // than the source, it will correspond to a vector predicate with the
823  // relevant bits replicated. The replication count is the ratio of the
824  // source and target vector lengths.
825  unsigned Rep = VecTy.getVectorNumElements() / ResLen;
826  assert(isPowerOf2_32(Rep) && HwLen % Rep == 0);
827  for (unsigned i = 0; i != HwLen/Rep; ++i) {
828  for (unsigned j = 0; j != Rep; ++j)
829  Mask.push_back(i + Offset);
830  }
831  SDValue ShuffV = DAG.getVectorShuffle(ByteTy, dl, ByteVec, Undef, Mask);
832  return DAG.getNode(HexagonISD::V2Q, dl, ResTy, ShuffV);
833  }
834 
835  // Converting between a vector predicate and a scalar predicate. In the
836  // vector predicate, a group of BitBytes bits will correspond to a single
837  // i1 element of the source vector type. Those bits will all have the same
838  // value. The same will be true for ByteVec, where each byte corresponds
839  // to a bit in the vector predicate.
840  // The algorithm is to traverse the ByteVec, going over the i1 values from
841  // the source vector, and generate the corresponding representation in an
842  // 8-byte vector. To avoid repeated extracts from ByteVec, shuffle the
843  // elements so that the interesting 8 bytes will be in the low end of the
844  // vector.
845  unsigned Rep = 8 / ResLen;
846  // Make sure the output fill the entire vector register, so repeat the
847  // 8-byte groups as many times as necessary.
848  for (unsigned r = 0; r != HwLen/ResLen; ++r) {
849  // This will generate the indexes of the 8 interesting bytes.
850  for (unsigned i = 0; i != ResLen; ++i) {
851  for (unsigned j = 0; j != Rep; ++j)
852  Mask.push_back(Offset + i*BitBytes);
853  }
854  }
855 
856  SDValue Zero = getZero(dl, MVT::i32, DAG);
857  SDValue ShuffV = DAG.getVectorShuffle(ByteTy, dl, ByteVec, Undef, Mask);
858  // Combine the two low words from ShuffV into a v8i8, and byte-compare
859  // them against 0.
860  SDValue W0 = DAG.getNode(HexagonISD::VEXTRACTW, dl, MVT::i32, {ShuffV, Zero});
862  {ShuffV, DAG.getConstant(4, dl, MVT::i32)});
863  SDValue Vec64 = DAG.getNode(HexagonISD::COMBINE, dl, MVT::v8i8, {W1, W0});
864  return getInstr(Hexagon::A4_vcmpbgtui, dl, ResTy,
865  {Vec64, DAG.getTargetConstant(0, dl, MVT::i32)}, DAG);
866 }
867 
868 SDValue
869 HexagonTargetLowering::insertHvxSubvectorReg(SDValue VecV, SDValue SubV,
870  SDValue IdxV, const SDLoc &dl, SelectionDAG &DAG) const {
871  MVT VecTy = ty(VecV);
872  MVT SubTy = ty(SubV);
873  unsigned HwLen = Subtarget.getVectorLength();
874  MVT ElemTy = VecTy.getVectorElementType();
875  unsigned ElemWidth = ElemTy.getSizeInBits();
876 
877  bool IsPair = isHvxPairTy(VecTy);
878  MVT SingleTy = MVT::getVectorVT(ElemTy, (8*HwLen)/ElemWidth);
879  // The two single vectors that VecV consists of, if it's a pair.
880  SDValue V0, V1;
881  SDValue SingleV = VecV;
882  SDValue PickHi;
883 
884  if (IsPair) {
885  V0 = DAG.getTargetExtractSubreg(Hexagon::vsub_lo, dl, SingleTy, VecV);
886  V1 = DAG.getTargetExtractSubreg(Hexagon::vsub_hi, dl, SingleTy, VecV);
887 
888  SDValue HalfV = DAG.getConstant(SingleTy.getVectorNumElements(),
889  dl, MVT::i32);
890  PickHi = DAG.getSetCC(dl, MVT::i1, IdxV, HalfV, ISD::SETUGT);
891  if (isHvxSingleTy(SubTy)) {
892  if (const auto *CN = dyn_cast<const ConstantSDNode>(IdxV.getNode())) {
893  unsigned Idx = CN->getZExtValue();
894  assert(Idx == 0 || Idx == VecTy.getVectorNumElements()/2);
895  unsigned SubIdx = (Idx == 0) ? Hexagon::vsub_lo : Hexagon::vsub_hi;
896  return DAG.getTargetInsertSubreg(SubIdx, dl, VecTy, VecV, SubV);
897  }
898  // If IdxV is not a constant, generate the two variants: with the
899  // SubV as the high and as the low subregister, and select the right
900  // pair based on the IdxV.
901  SDValue InLo = DAG.getNode(ISD::CONCAT_VECTORS, dl, VecTy, {SubV, V1});
902  SDValue InHi = DAG.getNode(ISD::CONCAT_VECTORS, dl, VecTy, {V0, SubV});
903  return DAG.getNode(ISD::SELECT, dl, VecTy, PickHi, InHi, InLo);
904  }
905  // The subvector being inserted must be entirely contained in one of
906  // the vectors V0 or V1. Set SingleV to the correct one, and update
907  // IdxV to be the index relative to the beginning of that vector.
908  SDValue S = DAG.getNode(ISD::SUB, dl, MVT::i32, IdxV, HalfV);
909  IdxV = DAG.getNode(ISD::SELECT, dl, MVT::i32, PickHi, S, IdxV);
910  SingleV = DAG.getNode(ISD::SELECT, dl, SingleTy, PickHi, V1, V0);
911  }
912 
913  // The only meaningful subvectors of a single HVX vector are those that
914  // fit in a scalar register.
915  assert(SubTy.getSizeInBits() == 32 || SubTy.getSizeInBits() == 64);
916  // Convert IdxV to be index in bytes.
917  auto *IdxN = dyn_cast<ConstantSDNode>(IdxV.getNode());
918  if (!IdxN || !IdxN->isNullValue()) {
919  IdxV = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
920  DAG.getConstant(ElemWidth/8, dl, MVT::i32));
921  SingleV = DAG.getNode(HexagonISD::VROR, dl, SingleTy, SingleV, IdxV);
922  }
923  // When inserting a single word, the rotation back to the original position
924  // would be by HwLen-Idx, but if two words are inserted, it will need to be
925  // by (HwLen-4)-Idx.
926  unsigned RolBase = HwLen;
927  if (VecTy.getSizeInBits() == 32) {
928  SDValue V = DAG.getBitcast(MVT::i32, SubV);
929  SingleV = DAG.getNode(HexagonISD::VINSERTW0, dl, SingleTy, V);
930  } else {
931  SDValue V = DAG.getBitcast(MVT::i64, SubV);
932  SDValue R0 = DAG.getTargetExtractSubreg(Hexagon::isub_lo, dl, MVT::i32, V);
933  SDValue R1 = DAG.getTargetExtractSubreg(Hexagon::isub_hi, dl, MVT::i32, V);
934  SingleV = DAG.getNode(HexagonISD::VINSERTW0, dl, SingleTy, SingleV, R0);
935  SingleV = DAG.getNode(HexagonISD::VROR, dl, SingleTy, SingleV,
936  DAG.getConstant(4, dl, MVT::i32));
937  SingleV = DAG.getNode(HexagonISD::VINSERTW0, dl, SingleTy, SingleV, R1);
938  RolBase = HwLen-4;
939  }
940  // If the vector wasn't ror'ed, don't ror it back.
941  if (RolBase != 4 || !IdxN || !IdxN->isNullValue()) {
942  SDValue RolV = DAG.getNode(ISD::SUB, dl, MVT::i32,
943  DAG.getConstant(RolBase, dl, MVT::i32), IdxV);
944  SingleV = DAG.getNode(HexagonISD::VROR, dl, SingleTy, SingleV, RolV);
945  }
946 
947  if (IsPair) {
948  SDValue InLo = DAG.getNode(ISD::CONCAT_VECTORS, dl, VecTy, {SingleV, V1});
949  SDValue InHi = DAG.getNode(ISD::CONCAT_VECTORS, dl, VecTy, {V0, SingleV});
950  return DAG.getNode(ISD::SELECT, dl, VecTy, PickHi, InHi, InLo);
951  }
952  return SingleV;
953 }
954 
955 SDValue
956 HexagonTargetLowering::insertHvxSubvectorPred(SDValue VecV, SDValue SubV,
957  SDValue IdxV, const SDLoc &dl, SelectionDAG &DAG) const {
958  MVT VecTy = ty(VecV);
959  MVT SubTy = ty(SubV);
960  assert(Subtarget.isHVXVectorType(VecTy, true));
961  // VecV is an HVX vector predicate. SubV may be either an HVX vector
962  // predicate as well, or it can be a scalar predicate.
963 
964  unsigned VecLen = VecTy.getVectorNumElements();
965  unsigned HwLen = Subtarget.getVectorLength();
966  assert(HwLen % VecLen == 0 && "Unexpected vector type");
967 
968  unsigned Scale = VecLen / SubTy.getVectorNumElements();
969  unsigned BitBytes = HwLen / VecLen;
970  unsigned BlockLen = HwLen / Scale;
971 
972  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
973  SDValue ByteVec = DAG.getNode(HexagonISD::Q2V, dl, ByteTy, VecV);
974  SDValue ByteSub = createHvxPrefixPred(SubV, dl, BitBytes, false, DAG);
975  SDValue ByteIdx;
976 
977  auto *IdxN = dyn_cast<ConstantSDNode>(IdxV.getNode());
978  if (!IdxN || !IdxN->isNullValue()) {
979  ByteIdx = DAG.getNode(ISD::MUL, dl, MVT::i32, IdxV,
980  DAG.getConstant(BitBytes, dl, MVT::i32));
981  ByteVec = DAG.getNode(HexagonISD::VROR, dl, ByteTy, ByteVec, ByteIdx);
982  }
983 
984  // ByteVec is the target vector VecV rotated in such a way that the
985  // subvector should be inserted at index 0. Generate a predicate mask
986  // and use vmux to do the insertion.
987  MVT BoolTy = MVT::getVectorVT(MVT::i1, HwLen);
988  SDValue Q = getInstr(Hexagon::V6_pred_scalar2, dl, BoolTy,
989  {DAG.getConstant(BlockLen, dl, MVT::i32)}, DAG);
990  ByteVec = getInstr(Hexagon::V6_vmux, dl, ByteTy, {Q, ByteSub, ByteVec}, DAG);
991  // Rotate ByteVec back, and convert to a vector predicate.
992  if (!IdxN || !IdxN->isNullValue()) {
993  SDValue HwLenV = DAG.getConstant(HwLen, dl, MVT::i32);
994  SDValue ByteXdi = DAG.getNode(ISD::SUB, dl, MVT::i32, HwLenV, ByteIdx);
995  ByteVec = DAG.getNode(HexagonISD::VROR, dl, ByteTy, ByteVec, ByteXdi);
996  }
997  return DAG.getNode(HexagonISD::V2Q, dl, VecTy, ByteVec);
998 }
999 
1000 SDValue
1001 HexagonTargetLowering::extendHvxVectorPred(SDValue VecV, const SDLoc &dl,
1002  MVT ResTy, bool ZeroExt, SelectionDAG &DAG) const {
1003  // Sign- and any-extending of a vector predicate to a vector register is
1004  // equivalent to Q2V. For zero-extensions, generate a vmux between 0 and
1005  // a vector of 1s (where the 1s are of type matching the vector type).
1006  assert(Subtarget.isHVXVectorType(ResTy));
1007  if (!ZeroExt)
1008  return DAG.getNode(HexagonISD::Q2V, dl, ResTy, VecV);
1009 
1010  assert(ty(VecV).getVectorNumElements() == ResTy.getVectorNumElements());
1011  SDValue True = DAG.getNode(HexagonISD::VSPLAT, dl, ResTy,
1012  DAG.getConstant(1, dl, MVT::i32));
1013  SDValue False = getZero(dl, ResTy, DAG);
1014  return DAG.getSelect(dl, ResTy, VecV, True, False);
1015 }
1016 
1017 SDValue
1018 HexagonTargetLowering::LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG)
1019  const {
1020  const SDLoc &dl(Op);
1021  MVT VecTy = ty(Op);
1022 
1023  unsigned Size = Op.getNumOperands();
1025  for (unsigned i = 0; i != Size; ++i)
1026  Ops.push_back(Op.getOperand(i));
1027 
1028  if (VecTy.getVectorElementType() == MVT::i1)
1029  return buildHvxVectorPred(Ops, dl, VecTy, DAG);
1030 
1031  if (VecTy.getSizeInBits() == 16*Subtarget.getVectorLength()) {
1032  ArrayRef<SDValue> A(Ops);
1033  MVT SingleTy = typeSplit(VecTy).first;
1034  SDValue V0 = buildHvxVectorReg(A.take_front(Size/2), dl, SingleTy, DAG);
1035  SDValue V1 = buildHvxVectorReg(A.drop_front(Size/2), dl, SingleTy, DAG);
1036  return DAG.getNode(ISD::CONCAT_VECTORS, dl, VecTy, V0, V1);
1037  }
1038 
1039  return buildHvxVectorReg(Ops, dl, VecTy, DAG);
1040 }
1041 
1042 SDValue
1043 HexagonTargetLowering::LowerHvxConcatVectors(SDValue Op, SelectionDAG &DAG)
1044  const {
1045  // Vector concatenation of two integer (non-bool) vectors does not need
1046  // special lowering. Custom-lower concats of bool vectors and expand
1047  // concats of more than 2 vectors.
1048  MVT VecTy = ty(Op);
1049  const SDLoc &dl(Op);
1050  unsigned NumOp = Op.getNumOperands();
1051  if (VecTy.getVectorElementType() != MVT::i1) {
1052  if (NumOp == 2)
1053  return Op;
1054  // Expand the other cases into a build-vector.
1055  SmallVector<SDValue,8> Elems;
1056  for (SDValue V : Op.getNode()->ops())
1057  DAG.ExtractVectorElements(V, Elems);
1058  // A vector of i16 will be broken up into a build_vector of i16's.
1059  // This is a problem, since at the time of operation legalization,
1060  // all operations are expected to be type-legalized, and i16 is not
1061  // a legal type. If any of the extracted elements is not of a valid
1062  // type, sign-extend it to a valid one.
1063  for (unsigned i = 0, e = Elems.size(); i != e; ++i) {
1064  SDValue V = Elems[i];
1065  MVT Ty = ty(V);
1066  if (!isTypeLegal(Ty)) {
1067  EVT NTy = getTypeToTransformTo(*DAG.getContext(), Ty);
1068  if (V.getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
1069  Elems[i] = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NTy,
1070  DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NTy,
1071  V.getOperand(0), V.getOperand(1)),
1072  DAG.getValueType(Ty));
1073  continue;
1074  }
1075  // A few less complicated cases.
1076  if (V.getOpcode() == ISD::Constant)
1077  Elems[i] = DAG.getSExtOrTrunc(V, dl, NTy);
1078  else if (V.isUndef())
1079  Elems[i] = DAG.getUNDEF(NTy);
1080  else
1081  llvm_unreachable("Unexpected vector element");
1082  }
1083  }
1084  return DAG.getBuildVector(VecTy, dl, Elems);
1085  }
1086 
1087  assert(VecTy.getVectorElementType() == MVT::i1);
1088  unsigned HwLen = Subtarget.getVectorLength();
1089  assert(isPowerOf2_32(NumOp) && HwLen % NumOp == 0);
1090 
1091  SDValue Op0 = Op.getOperand(0);
1092 
1093  // If the operands are HVX types (i.e. not scalar predicates), then
1094  // defer the concatenation, and create QCAT instead.
1095  if (Subtarget.isHVXVectorType(ty(Op0), true)) {
1096  if (NumOp == 2)
1097  return DAG.getNode(HexagonISD::QCAT, dl, VecTy, Op0, Op.getOperand(1));
1098 
1099  ArrayRef<SDUse> U(Op.getNode()->ops());
1100  SmallVector<SDValue,4> SV(U.begin(), U.end());
1101  ArrayRef<SDValue> Ops(SV);
1102 
1103  MVT HalfTy = typeSplit(VecTy).first;
1104  SDValue V0 = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfTy,
1105  Ops.take_front(NumOp/2));
1106  SDValue V1 = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfTy,
1107  Ops.take_back(NumOp/2));
1108  return DAG.getNode(HexagonISD::QCAT, dl, VecTy, V0, V1);
1109  }
1110 
1111  // Count how many bytes (in a vector register) each bit in VecTy
1112  // corresponds to.
1113  unsigned BitBytes = HwLen / VecTy.getVectorNumElements();
1114 
1115  SmallVector<SDValue,8> Prefixes;
1116  for (SDValue V : Op.getNode()->op_values()) {
1117  SDValue P = createHvxPrefixPred(V, dl, BitBytes, true, DAG);
1118  Prefixes.push_back(P);
1119  }
1120 
1121  unsigned InpLen = ty(Op.getOperand(0)).getVectorNumElements();
1122  MVT ByteTy = MVT::getVectorVT(MVT::i8, HwLen);
1123  SDValue S = DAG.getConstant(InpLen*BitBytes, dl, MVT::i32);
1124  SDValue Res = getZero(dl, ByteTy, DAG);
1125  for (unsigned i = 0, e = Prefixes.size(); i != e; ++i) {
1126  Res = DAG.getNode(HexagonISD::VROR, dl, ByteTy, Res, S);
1127  Res = DAG.getNode(ISD::OR, dl, ByteTy, Res, Prefixes[e-i-1]);
1128  }
1129  return DAG.getNode(HexagonISD::V2Q, dl, VecTy, Res);
1130 }
1131 
1132 SDValue
1133 HexagonTargetLowering::LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG)
1134  const {
1135  // Change the type of the extracted element to i32.
1136  SDValue VecV = Op.getOperand(0);
1137  MVT ElemTy = ty(VecV).getVectorElementType();
1138  const SDLoc &dl(Op);
1139  SDValue IdxV = Op.getOperand(1);
1140  if (ElemTy == MVT::i1)
1141  return extractHvxElementPred(VecV, IdxV, dl, ty(Op), DAG);
1142 
1143  return extractHvxElementReg(VecV, IdxV, dl, ty(Op), DAG);
1144 }
1145 
1146 SDValue
1147 HexagonTargetLowering::LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG)
1148  const {
1149  const SDLoc &dl(Op);
1150  SDValue VecV = Op.getOperand(0);
1151  SDValue ValV = Op.getOperand(1);
1152  SDValue IdxV = Op.getOperand(2);
1153  MVT ElemTy = ty(VecV).getVectorElementType();
1154  if (ElemTy == MVT::i1)
1155  return insertHvxElementPred(VecV, IdxV, ValV, dl, DAG);
1156 
1157  return insertHvxElementReg(VecV, IdxV, ValV, dl, DAG);
1158 }
1159 
1160 SDValue
1161 HexagonTargetLowering::LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG)
1162  const {
1163  SDValue SrcV = Op.getOperand(0);
1164  MVT SrcTy = ty(SrcV);
1165  MVT DstTy = ty(Op);
1166  SDValue IdxV = Op.getOperand(1);
1167  unsigned Idx = cast<ConstantSDNode>(IdxV.getNode())->getZExtValue();
1168  assert(Idx % DstTy.getVectorNumElements() == 0);
1169  (void)Idx;
1170  const SDLoc &dl(Op);
1171 
1172  MVT ElemTy = SrcTy.getVectorElementType();
1173  if (ElemTy == MVT::i1)
1174  return extractHvxSubvectorPred(SrcV, IdxV, dl, DstTy, DAG);
1175 
1176  return extractHvxSubvectorReg(SrcV, IdxV, dl, DstTy, DAG);
1177 }
1178 
1179 SDValue
1180 HexagonTargetLowering::LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG)
1181  const {
1182  // Idx does not need to be a constant.
1183  SDValue VecV = Op.getOperand(0);
1184  SDValue ValV = Op.getOperand(1);
1185  SDValue IdxV = Op.getOperand(2);
1186 
1187  const SDLoc &dl(Op);
1188  MVT VecTy = ty(VecV);
1189  MVT ElemTy = VecTy.getVectorElementType();
1190  if (ElemTy == MVT::i1)
1191  return insertHvxSubvectorPred(VecV, ValV, IdxV, dl, DAG);
1192 
1193  return insertHvxSubvectorReg(VecV, ValV, IdxV, dl, DAG);
1194 }
1195 
1196 SDValue
1197 HexagonTargetLowering::LowerHvxAnyExt(SDValue Op, SelectionDAG &DAG) const {
1198  // Lower any-extends of boolean vectors to sign-extends, since they
1199  // translate directly to Q2V. Zero-extending could also be done equally
1200  // fast, but Q2V is used/recognized in more places.
1201  // For all other vectors, use zero-extend.
1202  MVT ResTy = ty(Op);
1203  SDValue InpV = Op.getOperand(0);
1204  MVT ElemTy = ty(InpV).getVectorElementType();
1205  if (ElemTy == MVT::i1 && Subtarget.isHVXVectorType(ResTy))
1206  return LowerHvxSignExt(Op, DAG);
1207  return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(Op), ResTy, InpV);
1208 }
1209 
1210 SDValue
1211 HexagonTargetLowering::LowerHvxSignExt(SDValue Op, SelectionDAG &DAG) const {
1212  MVT ResTy = ty(Op);
1213  SDValue InpV = Op.getOperand(0);
1214  MVT ElemTy = ty(InpV).getVectorElementType();
1215  if (ElemTy == MVT::i1 && Subtarget.isHVXVectorType(ResTy))
1216  return extendHvxVectorPred(InpV, SDLoc(Op), ty(Op), false, DAG);
1217  return Op;
1218 }
1219 
1220 SDValue
1221 HexagonTargetLowering::LowerHvxZeroExt(SDValue Op, SelectionDAG &DAG) const {
1222  MVT ResTy = ty(Op);
1223  SDValue InpV = Op.getOperand(0);
1224  MVT ElemTy = ty(InpV).getVectorElementType();
1225  if (ElemTy == MVT::i1 && Subtarget.isHVXVectorType(ResTy))
1226  return extendHvxVectorPred(InpV, SDLoc(Op), ty(Op), true, DAG);
1227  return Op;
1228 }
1229 
1230 SDValue
1231 HexagonTargetLowering::LowerHvxCttz(SDValue Op, SelectionDAG &DAG) const {
1232  // Lower vector CTTZ into a computation using CTLZ (Hacker's Delight):
1233  // cttz(x) = bitwidth(x) - ctlz(~x & (x-1))
1234  const SDLoc &dl(Op);
1235  MVT ResTy = ty(Op);
1236  SDValue InpV = Op.getOperand(0);
1237  assert(ResTy == ty(InpV));
1238 
1239  // Calculate the vectors of 1 and bitwidth(x).
1240  MVT ElemTy = ty(InpV).getVectorElementType();
1241  unsigned ElemWidth = ElemTy.getSizeInBits();
1242  // Using uint64_t because a shift by 32 can happen.
1243  uint64_t Splat1 = 0, SplatW = 0;
1244  assert(isPowerOf2_32(ElemWidth) && ElemWidth <= 32);
1245  for (unsigned i = 0; i != 32/ElemWidth; ++i) {
1246  Splat1 = (Splat1 << ElemWidth) | 1;
1247  SplatW = (SplatW << ElemWidth) | ElemWidth;
1248  }
1249  SDValue Vec1 = DAG.getNode(HexagonISD::VSPLATW, dl, ResTy,
1250  DAG.getConstant(uint32_t(Splat1), dl, MVT::i32));
1251  SDValue VecW = DAG.getNode(HexagonISD::VSPLATW, dl, ResTy,
1252  DAG.getConstant(uint32_t(SplatW), dl, MVT::i32));
1253  SDValue VecN1 = DAG.getNode(HexagonISD::VSPLATW, dl, ResTy,
1254  DAG.getConstant(-1, dl, MVT::i32));
1255  // Do not use DAG.getNOT, because that would create BUILD_VECTOR with
1256  // a BITCAST. Here we can skip the BITCAST (so we don't have to handle
1257  // it separately in custom combine or selection).
1258  SDValue A = DAG.getNode(ISD::AND, dl, ResTy,
1259  {DAG.getNode(ISD::XOR, dl, ResTy, {InpV, VecN1}),
1260  DAG.getNode(ISD::SUB, dl, ResTy, {InpV, Vec1})});
1261  return DAG.getNode(ISD::SUB, dl, ResTy,
1262  {VecW, DAG.getNode(ISD::CTLZ, dl, ResTy, A)});
1263 }
1264 
1265 SDValue
1266 HexagonTargetLowering::LowerHvxMul(SDValue Op, SelectionDAG &DAG) const {
1267  MVT ResTy = ty(Op);
1268  assert(ResTy.isVector() && isHvxSingleTy(ResTy));
1269  const SDLoc &dl(Op);
1270  SmallVector<int,256> ShuffMask;
1271 
1272  MVT ElemTy = ResTy.getVectorElementType();
1273  unsigned VecLen = ResTy.getVectorNumElements();
1274  SDValue Vs = Op.getOperand(0);
1275  SDValue Vt = Op.getOperand(1);
1276 
1277  switch (ElemTy.SimpleTy) {
1278  case MVT::i8: {
1279  // For i8 vectors Vs = (a0, a1, ...), Vt = (b0, b1, ...),
1280  // V6_vmpybv Vs, Vt produces a pair of i16 vectors Hi:Lo,
1281  // where Lo = (a0*b0, a2*b2, ...), Hi = (a1*b1, a3*b3, ...).
1282  MVT ExtTy = typeExtElem(ResTy, 2);
1283  unsigned MpyOpc = ElemTy == MVT::i8 ? Hexagon::V6_vmpybv
1284  : Hexagon::V6_vmpyhv;
1285  SDValue M = getInstr(MpyOpc, dl, ExtTy, {Vs, Vt}, DAG);
1286 
1287  // Discard high halves of the resulting values, collect the low halves.
1288  for (unsigned I = 0; I < VecLen; I += 2) {
1289  ShuffMask.push_back(I); // Pick even element.
1290  ShuffMask.push_back(I+VecLen); // Pick odd element.
1291  }
1292  VectorPair P = opSplit(opCastElem(M, ElemTy, DAG), dl, DAG);
1293  SDValue BS = getByteShuffle(dl, P.first, P.second, ShuffMask, DAG);
1294  return DAG.getBitcast(ResTy, BS);
1295  }
1296  case MVT::i16:
1297  // For i16 there is V6_vmpyih, which acts exactly like the MUL opcode.
1298  // (There is also V6_vmpyhv, which behaves in an analogous way to
1299  // V6_vmpybv.)
1300  return getInstr(Hexagon::V6_vmpyih, dl, ResTy, {Vs, Vt}, DAG);
1301  case MVT::i32: {
1302  // Use the following sequence for signed word multiply:
1303  // T0 = V6_vmpyiowh Vs, Vt
1304  // T1 = V6_vaslw T0, 16
1305  // T2 = V6_vmpyiewuh_acc T1, Vs, Vt
1306  SDValue S16 = DAG.getConstant(16, dl, MVT::i32);
1307  SDValue T0 = getInstr(Hexagon::V6_vmpyiowh, dl, ResTy, {Vs, Vt}, DAG);
1308  SDValue T1 = getInstr(Hexagon::V6_vaslw, dl, ResTy, {T0, S16}, DAG);
1309  SDValue T2 = getInstr(Hexagon::V6_vmpyiewuh_acc, dl, ResTy,
1310  {T1, Vs, Vt}, DAG);
1311  return T2;
1312  }
1313  default:
1314  break;
1315  }
1316  return SDValue();
1317 }
1318 
1319 SDValue
1320 HexagonTargetLowering::LowerHvxMulh(SDValue Op, SelectionDAG &DAG) const {
1321  MVT ResTy = ty(Op);
1322  assert(ResTy.isVector());
1323  const SDLoc &dl(Op);
1324  SmallVector<int,256> ShuffMask;
1325 
1326  MVT ElemTy = ResTy.getVectorElementType();
1327  unsigned VecLen = ResTy.getVectorNumElements();
1328  SDValue Vs = Op.getOperand(0);
1329  SDValue Vt = Op.getOperand(1);
1330  bool IsSigned = Op.getOpcode() == ISD::MULHS;
1331 
1332  if (ElemTy == MVT::i8 || ElemTy == MVT::i16) {
1333  // For i8 vectors Vs = (a0, a1, ...), Vt = (b0, b1, ...),
1334  // V6_vmpybv Vs, Vt produces a pair of i16 vectors Hi:Lo,
1335  // where Lo = (a0*b0, a2*b2, ...), Hi = (a1*b1, a3*b3, ...).
1336  // For i16, use V6_vmpyhv, which behaves in an analogous way to
1337  // V6_vmpybv: results Lo and Hi are products of even/odd elements
1338  // respectively.
1339  MVT ExtTy = typeExtElem(ResTy, 2);
1340  unsigned MpyOpc = ElemTy == MVT::i8
1341  ? (IsSigned ? Hexagon::V6_vmpybv : Hexagon::V6_vmpyubv)
1342  : (IsSigned ? Hexagon::V6_vmpyhv : Hexagon::V6_vmpyuhv);
1343  SDValue M = getInstr(MpyOpc, dl, ExtTy, {Vs, Vt}, DAG);
1344 
1345  // Discard low halves of the resulting values, collect the high halves.
1346  for (unsigned I = 0; I < VecLen; I += 2) {
1347  ShuffMask.push_back(I+1); // Pick even element.
1348  ShuffMask.push_back(I+VecLen+1); // Pick odd element.
1349  }
1350  VectorPair P = opSplit(opCastElem(M, ElemTy, DAG), dl, DAG);
1351  SDValue BS = getByteShuffle(dl, P.first, P.second, ShuffMask, DAG);
1352  return DAG.getBitcast(ResTy, BS);
1353  }
1354 
1355  assert(ElemTy == MVT::i32);
1356  SDValue S16 = DAG.getConstant(16, dl, MVT::i32);
1357 
1358  if (IsSigned) {
1359  // mulhs(Vs,Vt) =
1360  // = [(Hi(Vs)*2^16 + Lo(Vs)) *s (Hi(Vt)*2^16 + Lo(Vt))] >> 32
1361  // = [Hi(Vs)*2^16 *s Hi(Vt)*2^16 + Hi(Vs) *su Lo(Vt)*2^16
1362  // + Lo(Vs) *us (Hi(Vt)*2^16 + Lo(Vt))] >> 32
1363  // = [Hi(Vs) *s Hi(Vt)*2^32 + Hi(Vs) *su Lo(Vt)*2^16
1364  // + Lo(Vs) *us Vt] >> 32
1365  // The low half of Lo(Vs)*Lo(Vt) will be discarded (it's not added to
1366  // anything, so it cannot produce any carry over to higher bits),
1367  // so everything in [] can be shifted by 16 without loss of precision.
1368  // = [Hi(Vs) *s Hi(Vt)*2^16 + Hi(Vs)*su Lo(Vt) + Lo(Vs)*Vt >> 16] >> 16
1369  // = [Hi(Vs) *s Hi(Vt)*2^16 + Hi(Vs)*su Lo(Vt) + V6_vmpyewuh(Vs,Vt)] >> 16
1370  // Denote Hi(Vs) = Vs':
1371  // = [Vs'*s Hi(Vt)*2^16 + Vs' *su Lo(Vt) + V6_vmpyewuh(Vt,Vs)] >> 16
1372  // = Vs'*s Hi(Vt) + (V6_vmpyiewuh(Vs',Vt) + V6_vmpyewuh(Vt,Vs)) >> 16
1373  SDValue T0 = getInstr(Hexagon::V6_vmpyewuh, dl, ResTy, {Vt, Vs}, DAG);
1374  // Get Vs':
1375  SDValue S0 = getInstr(Hexagon::V6_vasrw, dl, ResTy, {Vs, S16}, DAG);
1376  SDValue T1 = getInstr(Hexagon::V6_vmpyiewuh_acc, dl, ResTy,
1377  {T0, S0, Vt}, DAG);
1378  // Shift by 16:
1379  SDValue S2 = getInstr(Hexagon::V6_vasrw, dl, ResTy, {T1, S16}, DAG);
1380  // Get Vs'*Hi(Vt):
1381  SDValue T2 = getInstr(Hexagon::V6_vmpyiowh, dl, ResTy, {S0, Vt}, DAG);
1382  // Add:
1383  SDValue T3 = DAG.getNode(ISD::ADD, dl, ResTy, {S2, T2});
1384  return T3;
1385  }
1386 
1387  // Unsigned mulhw. (Would expansion using signed mulhw be better?)
1388 
1389  auto LoVec = [&DAG,ResTy,dl] (SDValue Pair) {
1390  return DAG.getTargetExtractSubreg(Hexagon::vsub_lo, dl, ResTy, Pair);
1391  };
1392  auto HiVec = [&DAG,ResTy,dl] (SDValue Pair) {
1393  return DAG.getTargetExtractSubreg(Hexagon::vsub_hi, dl, ResTy, Pair);
1394  };
1395 
1396  MVT PairTy = typeJoin({ResTy, ResTy});
1397  SDValue P = getInstr(Hexagon::V6_lvsplatw, dl, ResTy,
1398  {DAG.getConstant(0x02020202, dl, MVT::i32)}, DAG);
1399  // Multiply-unsigned halfwords:
1400  // LoVec = Vs.uh[2i] * Vt.uh[2i],
1401  // HiVec = Vs.uh[2i+1] * Vt.uh[2i+1]
1402  SDValue T0 = getInstr(Hexagon::V6_vmpyuhv, dl, PairTy, {Vs, Vt}, DAG);
1403  // The low halves in the LoVec of the pair can be discarded. They are
1404  // not added to anything (in the full-precision product), so they cannot
1405  // produce a carry into the higher bits.
1406  SDValue T1 = getInstr(Hexagon::V6_vlsrw, dl, ResTy, {LoVec(T0), S16}, DAG);
1407  // Swap low and high halves in Vt, and do the halfword multiplication
1408  // to get products Vs.uh[2i] * Vt.uh[2i+1] and Vs.uh[2i+1] * Vt.uh[2i].
1409  SDValue D0 = getInstr(Hexagon::V6_vdelta, dl, ResTy, {Vt, P}, DAG);
1410  SDValue T2 = getInstr(Hexagon::V6_vmpyuhv, dl, PairTy, {Vs, D0}, DAG);
1411  // T2 has mixed products of halfwords: Lo(Vt)*Hi(Vs) and Hi(Vt)*Lo(Vs).
1412  // These products are words, but cannot be added directly because the
1413  // sums could overflow. Add these products, by halfwords, where each sum
1414  // of a pair of halfwords gives a word.
1415  SDValue T3 = getInstr(Hexagon::V6_vadduhw, dl, PairTy,
1416  {LoVec(T2), HiVec(T2)}, DAG);
1417  // Add the high halfwords from the products of the low halfwords.
1418  SDValue T4 = DAG.getNode(ISD::ADD, dl, ResTy, {T1, LoVec(T3)});
1419  SDValue T5 = getInstr(Hexagon::V6_vlsrw, dl, ResTy, {T4, S16}, DAG);
1420  SDValue T6 = DAG.getNode(ISD::ADD, dl, ResTy, {HiVec(T0), HiVec(T3)});
1421  SDValue T7 = DAG.getNode(ISD::ADD, dl, ResTy, {T5, T6});
1422  return T7;
1423 }
1424 
1425 SDValue
1426 HexagonTargetLowering::LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const {
1427  // Sign- and zero-extends are legal.
1429  return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, SDLoc(Op), ty(Op),
1430  Op.getOperand(0));
1431 }
1432 
1433 SDValue
1434 HexagonTargetLowering::LowerHvxShift(SDValue Op, SelectionDAG &DAG) const {
1435  if (SDValue S = getVectorShiftByInt(Op, DAG))
1436  return S;
1437  return Op;
1438 }
1439 
1440 SDValue
1441 HexagonTargetLowering::SplitHvxPairOp(SDValue Op, SelectionDAG &DAG) const {
1442  assert(!Op.isMachineOpcode());
1443  SmallVector<SDValue,2> OpsL, OpsH;
1444  const SDLoc &dl(Op);
1445 
1446  auto SplitVTNode = [&DAG,this] (const VTSDNode *N) {
1447  MVT Ty = typeSplit(N->getVT().getSimpleVT()).first;
1448  SDValue TV = DAG.getValueType(Ty);
1449  return std::make_pair(TV, TV);
1450  };
1451 
1452  for (SDValue A : Op.getNode()->ops()) {
1453  VectorPair P = Subtarget.isHVXVectorType(ty(A), true)
1454  ? opSplit(A, dl, DAG)
1455  : std::make_pair(A, A);
1456  // Special case for type operand.
1457  if (Op.getOpcode() == ISD::SIGN_EXTEND_INREG) {
1458  if (const auto *N = dyn_cast<const VTSDNode>(A.getNode()))
1459  P = SplitVTNode(N);
1460  }
1461  OpsL.push_back(P.first);
1462  OpsH.push_back(P.second);
1463  }
1464 
1465  MVT ResTy = ty(Op);
1466  MVT HalfTy = typeSplit(ResTy).first;
1467  SDValue L = DAG.getNode(Op.getOpcode(), dl, HalfTy, OpsL);
1468  SDValue H = DAG.getNode(Op.getOpcode(), dl, HalfTy, OpsH);
1469  SDValue S = DAG.getNode(ISD::CONCAT_VECTORS, dl, ResTy, L, H);
1470  return S;
1471 }
1472 
1473 SDValue
1474 HexagonTargetLowering::SplitHvxMemOp(SDValue Op, SelectionDAG &DAG) const {
1475  LSBaseSDNode *BN = cast<LSBaseSDNode>(Op.getNode());
1476  assert(BN->isUnindexed());
1477  MVT MemTy = BN->getMemoryVT().getSimpleVT();
1478  if (!isHvxPairTy(MemTy))
1479  return Op;
1480 
1481  const SDLoc &dl(Op);
1482  unsigned HwLen = Subtarget.getVectorLength();
1483  MVT SingleTy = typeSplit(MemTy).first;
1484  SDValue Chain = BN->getChain();
1485  SDValue Base0 = BN->getBasePtr();
1486  SDValue Base1 = DAG.getMemBasePlusOffset(Base0, HwLen, dl);
1487 
1488  MachineMemOperand *MOp0 = nullptr, *MOp1 = nullptr;
1489  if (MachineMemOperand *MMO = BN->getMemOperand()) {
1490  MachineFunction &MF = DAG.getMachineFunction();
1491  MOp0 = MF.getMachineMemOperand(MMO, 0, HwLen);
1492  MOp1 = MF.getMachineMemOperand(MMO, HwLen, HwLen);
1493  }
1494 
1495  unsigned MemOpc = BN->getOpcode();
1496  SDValue NewOp;
1497 
1498  if (MemOpc == ISD::LOAD) {
1499  SDValue Load0 = DAG.getLoad(SingleTy, dl, Chain, Base0, MOp0);
1500  SDValue Load1 = DAG.getLoad(SingleTy, dl, Chain, Base1, MOp1);
1501  NewOp = DAG.getMergeValues(
1502  { DAG.getNode(ISD::CONCAT_VECTORS, dl, MemTy, Load0, Load1),
1504  Load0.getValue(1), Load1.getValue(1)) }, dl);
1505  } else {
1506  assert(MemOpc == ISD::STORE);
1507  VectorPair Vals = opSplit(cast<StoreSDNode>(Op)->getValue(), dl, DAG);
1508  SDValue Store0 = DAG.getStore(Chain, dl, Vals.first, Base0, MOp0);
1509  SDValue Store1 = DAG.getStore(Chain, dl, Vals.second, Base1, MOp1);
1510  NewOp = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store0, Store1);
1511  }
1512 
1513  return NewOp;
1514 }
1515 
1516 SDValue
1517 HexagonTargetLowering::LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const {
1518  unsigned Opc = Op.getOpcode();
1519  bool IsPairOp = isHvxPairTy(ty(Op)) ||
1520  llvm::any_of(Op.getNode()->ops(), [this] (SDValue V) {
1521  return isHvxPairTy(ty(V));
1522  });
1523 
1524  if (IsPairOp) {
1525  switch (Opc) {
1526  default:
1527  break;
1528  case ISD::LOAD:
1529  case ISD::STORE:
1530  return SplitHvxMemOp(Op, DAG);
1531  case ISD::CTPOP:
1532  case ISD::CTLZ:
1533  case ISD::CTTZ:
1534  case ISD::MUL:
1535  case ISD::MULHS:
1536  case ISD::MULHU:
1537  case ISD::AND:
1538  case ISD::OR:
1539  case ISD::XOR:
1540  case ISD::SRA:
1541  case ISD::SHL:
1542  case ISD::SRL:
1543  case ISD::SETCC:
1544  case ISD::VSELECT:
1546  return SplitHvxPairOp(Op, DAG);
1547  }
1548  }
1549 
1550  switch (Opc) {
1551  default:
1552  break;
1553  case ISD::BUILD_VECTOR: return LowerHvxBuildVector(Op, DAG);
1554  case ISD::CONCAT_VECTORS: return LowerHvxConcatVectors(Op, DAG);
1555  case ISD::INSERT_SUBVECTOR: return LowerHvxInsertSubvector(Op, DAG);
1556  case ISD::INSERT_VECTOR_ELT: return LowerHvxInsertElement(Op, DAG);
1557  case ISD::EXTRACT_SUBVECTOR: return LowerHvxExtractSubvector(Op, DAG);
1558  case ISD::EXTRACT_VECTOR_ELT: return LowerHvxExtractElement(Op, DAG);
1559 
1560  case ISD::ANY_EXTEND: return LowerHvxAnyExt(Op, DAG);
1561  case ISD::SIGN_EXTEND: return LowerHvxSignExt(Op, DAG);
1562  case ISD::ZERO_EXTEND: return LowerHvxZeroExt(Op, DAG);
1563  case ISD::CTTZ: return LowerHvxCttz(Op, DAG);
1564  case ISD::SRA:
1565  case ISD::SHL:
1566  case ISD::SRL: return LowerHvxShift(Op, DAG);
1567  case ISD::MUL: return LowerHvxMul(Op, DAG);
1568  case ISD::MULHS:
1569  case ISD::MULHU: return LowerHvxMulh(Op, DAG);
1570  case ISD::ANY_EXTEND_VECTOR_INREG: return LowerHvxExtend(Op, DAG);
1571  case ISD::SETCC:
1572  case ISD::INTRINSIC_VOID: return Op;
1573  // Unaligned loads will be handled by the default lowering.
1574  case ISD::LOAD: return SDValue();
1575  }
1576 #ifndef NDEBUG
1577  Op.dumpr(&DAG);
1578 #endif
1579  llvm_unreachable("Unhandled HVX operation");
1580 }
1581 
1582 bool
1583 HexagonTargetLowering::isHvxOperation(SDValue Op) const {
1584  // If the type of the result, or any operand type are HVX vector types,
1585  // this is an HVX operation.
1586  return Subtarget.isHVXVectorType(ty(Op), true) ||
1587  llvm::any_of(Op.getNode()->ops(),
1588  [this] (SDValue V) {
1589  return Subtarget.isHVXVectorType(ty(V), true);
1590  });
1591 }
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
uint64_t CallInst * C
static MVT getIntegerVT(unsigned BitWidth)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
BitVector & set()
Definition: BitVector.h:398
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isUndef() const
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:212
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond)
Helper function to make it easier to build SetCC&#39;s if you just have an ISD::CondCode instead of an SD...
Definition: SelectionDAG.h:937
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an vector value) starting with the ...
Definition: ISDOpcodes.h:358
This class represents lattice values for constants.
Definition: AllocatorList.h:24
static MVT getVectorVT(MVT VT, unsigned NumElements)
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:367
iterator begin() const
Definition: ArrayRef.h:137
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
Definition: ISDOpcodes.h:519
bool isVector() const
Return true if this is a vector value type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:253
static const MVT LegalW128[]
bool test(unsigned Idx) const
Definition: BitVector.h:502
unsigned getVectorNumElements() const
const SDValue & getChain() const
F(f)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select&#39;s if you just have operands and don&#39;t want to check...
Definition: SelectionDAG.h:950
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
Definition: ISDOpcodes.h:508
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
static const MVT LegalV64[]
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1 at the ...
Definition: ISDOpcodes.h:353
SDValue getConstantPool(const Constant *C, EVT VT, unsigned Align=0, int Offs=0, bool isT=false, unsigned char TargetFlags=0)
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset, const SDLoc &DL)
Returns sum of the base pointer and offset.
A description of a memory reference used in the backend.
Shift and rotation operations.
Definition: ISDOpcodes.h:410
Base class for LoadSDNode and StoreSDNode.
SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
void setCondCodeAction(ISD::CondCode CC, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn&#39;t supported on the target and indicate what to d...
SimpleValueType SimpleTy
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:460
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
This class is used to represent EVT&#39;s, which are used to parameterize some operations.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
unsigned getSizeInBits() const
void assign(size_type NumElts, const T &Elt)
Definition: SmallVector.h:423
int64_t getSExtValue() const
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:398
#define T
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
Definition: ISDOpcodes.h:429
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:201
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
Definition: SelectionDAG.h:852
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:576
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
Definition: ISDOpcodes.h:497
ArrayRef< SDUse > ops() const
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:151
MVT getVectorElementType() const
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable...
Definition: ISDOpcodes.h:327
#define P(N)
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
Definition: ISDOpcodes.h:166
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:429
Machine Value Type.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
bool isMachineOpcode() const
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
This is an important base class in LLVM.
Definition: Constant.h:42
iterator_range< value_op_iterator > op_values() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:129
static const MVT LegalW64[]
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL...
Definition: ISDOpcodes.h:332
#define H(x, y, z)
Definition: MD5.cpp:57
static const MVT LegalV128[]
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1193
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
Extended Value Type.
Definition: ValueTypes.h:34
size_t size() const
Definition: SmallVector.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, unsigned Alignment=0, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands...
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
unsigned first
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type...
TokenFactor - This node takes multiple tokens as input and produces a single token result...
Definition: ISDOpcodes.h:50
bool isHVXVectorType(MVT VecTy, bool IncludeBool=false) const
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:339
std::pair< SDValue, SDValue > SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the vector with EXTRACT_SUBVECTOR using the provides VTs and return the low/high part...
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:222
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
Definition: SelectionDAG.h:734
iterator end() const
Definition: ArrayRef.h:138
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:413
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
void ExtractVectorElements(SDValue Op, SmallVectorImpl< SDValue > &Args, unsigned Start=0, unsigned Count=0)
Append the extracted elements from Start to Count out of the vector Op in Args.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:539
void setIndexedLoadAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
EVT getMemoryVT() const
Return the type of the in-memory value.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:420
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:468
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:471
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
Definition: ArrayRef.h:179
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:133
void dumpr() const
ArrayRef< T > take_back(size_t N=1) const
Return a copy of *this with only the last N elements.
Definition: ArrayRef.h:219
unsigned getVectorLength() const
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:387
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:486
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:188
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:614
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
uint32_t Size
Definition: Profile.cpp:47
unsigned getOpcode() const
SDValue getValue(unsigned R) const
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
Definition: ISDOpcodes.h:345
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SDValue getValueType(EVT)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:443
unsigned getNumOperands() const
Conversion operators.
Definition: ISDOpcodes.h:465
const SDValue & getOperand(unsigned i) const
SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const
For types supported by the target, this is an identity function.
const SDValue & getBasePtr() const
LLVMContext * getContext() const
Definition: SelectionDAG.h:407
static Constant * get(ArrayRef< Constant *> V)
Definition: Constants.cpp:1079
#define T1
void setIndexedStoreAction(unsigned IdxMode, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:380