llvm.org GIT mirror llvm / 42f462a
[IR] move shuffle mask queries from TTI to ShuffleVectorInst The optimizer is getting smarter (eg, D47986) about differentiating shuffles based on its mask values, so we should make queries on the mask constant operand generally available to avoid code duplication. We'll probably use this soon in the vectorizers and instcombine (D48023 and https://bugs.llvm.org/show_bug.cgi?id=37806). We might clean up TTI a bit more once all of its current 'SK_*' options are covered. Differential Revision: https://reviews.llvm.org/D48236 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335067 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 1 year, 4 months ago
4 changed file(s) with 383 addition(s) and 178 deletion(s). Raw diff Collapse all Expand all
24252425
24262426 /// Return the shuffle mask value for the specified element of the mask.
24272427 /// Return -1 if the element is undef.
2428 static int getMaskValue(Constant *Mask, unsigned Elt);
2428 static int getMaskValue(const Constant *Mask, unsigned Elt);
24292429
24302430 /// Return the shuffle mask value of this instruction for the given element
24312431 /// index. Return -1 if the element is undef.
24352435
24362436 /// Convert the input shuffle mask operand to a vector of integers. Undefined
24372437 /// elements of the mask are returned as -1.
2438 static void getShuffleMask(Constant *Mask, SmallVectorImpl &Result);
2438 static void getShuffleMask(const Constant *Mask,
2439 SmallVectorImpl &Result);
24392440
24402441 /// Return the mask for this instruction as a vector of integers. Undefined
24412442 /// elements of the mask are returned as -1.
24472448 SmallVector Mask;
24482449 getShuffleMask(Mask);
24492450 return Mask;
2451 }
2452
2453 /// Return true if this shuffle returns a vector with a different number of
2454 /// elements than its source elements.
2455 /// Example: shufflevector <4 x n> A, <4 x n> B, <1,2>
2456 bool changesLength() const {
2457 unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements();
2458 unsigned NumMaskElts = getMask()->getType()->getVectorNumElements();
2459 return NumSourceElts != NumMaskElts;
2460 }
2461
2462 /// Return true if this shuffle mask chooses elements from exactly one source
2463 /// vector.
2464 /// Example: <7,5,undef,7>
2465 /// This assumes that vector operands are the same length as the mask.
2466 static bool isSingleSourceMask(ArrayRef Mask);
2467 static bool isSingleSourceMask(const Constant *Mask) {
2468 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2469 SmallVector MaskAsInts;
2470 getShuffleMask(Mask, MaskAsInts);
2471 return isSingleSourceMask(MaskAsInts);
2472 }
2473
2474 /// Return true if this shuffle chooses elements from exactly one source
2475 /// vector without changing the length of that vector.
2476 /// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
2477 /// TODO: Optionally allow length-changing shuffles.
2478 bool isSingleSource() const {
2479 return !changesLength() && isSingleSourceMask(getMask());
2480 }
2481
2482 /// Return true if this shuffle mask chooses elements from exactly one source
2483 /// vector without lane crossings. A shuffle using this mask is not
2484 /// necessarily a no-op because it may change the number of elements from its
2485 /// input vectors or it may provide demanded bits knowledge via undef lanes.
2486 /// Example:
2487 static bool isIdentityMask(ArrayRef Mask);
2488 static bool isIdentityMask(const Constant *Mask) {
2489 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2490 SmallVector MaskAsInts;
2491 getShuffleMask(Mask, MaskAsInts);
2492 return isIdentityMask(MaskAsInts);
2493 }
2494
2495 /// Return true if this shuffle mask chooses elements from exactly one source
2496 /// vector without lane crossings and does not change the number of elements
2497 /// from its input vectors.
2498 /// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
2499 /// TODO: Optionally allow length-changing shuffles.
2500 bool isIdentity() const {
2501 return !changesLength() && isIdentityMask(getShuffleMask());
2502 }
2503
2504 /// Return true if this shuffle mask chooses elements from its source vectors
2505 /// without lane crossings. A shuffle using this mask would be
2506 /// equivalent to a vector select with a constant condition operand.
2507 /// Example: <4,1,6,undef>
2508 /// This returns false if the mask does not choose from both input vectors.
2509 /// In that case, the shuffle is better classified as an identity shuffle.
2510 /// This assumes that vector operands are the same length as the mask
2511 /// (a length-changing shuffle can never be equivalent to a vector select).
2512 static bool isSelectMask(ArrayRef Mask);
2513 static bool isSelectMask(const Constant *Mask) {
2514 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2515 SmallVector MaskAsInts;
2516 getShuffleMask(Mask, MaskAsInts);
2517 return isSelectMask(MaskAsInts);
2518 }
2519
2520 /// Return true if this shuffle chooses elements from its source vectors
2521 /// without lane crossings and all operands have the same number of elements.
2522 /// In other words, this shuffle is equivalent to a vector select with a
2523 /// constant condition operand.
2524 /// Example: shufflevector <4 x n> A, <4 x n> B,
2525 /// This returns false if the mask does not choose from both input vectors.
2526 /// In that case, the shuffle is better classified as an identity shuffle.
2527 /// TODO: Optionally allow length-changing shuffles.
2528 bool isSelect() const {
2529 return !changesLength() && isSelectMask(getMask());
2530 }
2531
2532 /// Return true if this shuffle mask swaps the order of elements from exactly
2533 /// one source vector.
2534 /// Example: <7,6,undef,4>
2535 /// This assumes that vector operands are the same length as the mask.
2536 static bool isReverseMask(ArrayRef Mask);
2537 static bool isReverseMask(const Constant *Mask) {
2538 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2539 SmallVector MaskAsInts;
2540 getShuffleMask(Mask, MaskAsInts);
2541 return isReverseMask(MaskAsInts);
2542 }
2543
2544 /// Return true if this shuffle swaps the order of elements from exactly
2545 /// one source vector.
2546 /// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
2547 /// TODO: Optionally allow length-changing shuffles.
2548 bool isReverse() const {
2549 return !changesLength() && isReverseMask(getMask());
2550 }
2551
2552 /// Return true if this shuffle mask chooses all elements with the same value
2553 /// as the first element of exactly one source vector.
2554 /// Example: <4,undef,undef,4>
2555 /// This assumes that vector operands are the same length as the mask.
2556 static bool isZeroEltSplatMask(ArrayRef Mask);
2557 static bool isZeroEltSplatMask(const Constant *Mask) {
2558 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2559 SmallVector MaskAsInts;
2560 getShuffleMask(Mask, MaskAsInts);
2561 return isZeroEltSplatMask(MaskAsInts);
2562 }
2563
2564 /// Return true if all elements of this shuffle are the same value as the
2565 /// first element of exactly one source vector without changing the length
2566 /// of that vector.
2567 /// Example: shufflevector <4 x n> A, <4 x n> B,
2568 /// TODO: Optionally allow length-changing shuffles.
2569 /// TODO: Optionally allow splats from other elements.
2570 bool isZeroEltSplat() const {
2571 return !changesLength() && isZeroEltSplatMask(getMask());
2572 }
2573
2574 /// Return true if this shuffle mask is a transpose mask.
2575 /// Transpose vector masks transpose a 2xn matrix. They read corresponding
2576 /// even- or odd-numbered vector elements from two n-dimensional source
2577 /// vectors and write each result into consecutive elements of an
2578 /// n-dimensional destination vector. Two shuffles are necessary to complete
2579 /// the transpose, one for the even elements and another for the odd elements.
2580 /// This description closely follows how the TRN1 and TRN2 AArch64
2581 /// instructions operate.
2582 ///
2583 /// For example, a simple 2x2 matrix can be transposed with:
2584 ///
2585 /// ; Original matrix
2586 /// m0 =
2587 /// m1 =
2588 ///
2589 /// ; Transposed matrix
2590 /// t0 = = shufflevector m0, m1, <0, 2>
2591 /// t1 = = shufflevector m0, m1, <1, 3>
2592 ///
2593 /// For matrices having greater than n columns, the resulting nx2 transposed
2594 /// matrix is stored in two result vectors such that one vector contains
2595 /// interleaved elements from all the even-numbered rows and the other vector
2596 /// contains interleaved elements from all the odd-numbered rows. For example,
2597 /// a 2x4 matrix can be transposed with:
2598 ///
2599 /// ; Original matrix
2600 /// m0 =
2601 /// m1 =
2602 ///
2603 /// ; Transposed matrix
2604 /// t0 = = shufflevector m0, m1 <0, 4, 2, 6>
2605 /// t1 = = shufflevector m0, m1 <1, 5, 3, 7>
2606 static bool isTransposeMask(ArrayRef Mask);
2607 static bool isTransposeMask(const Constant *Mask) {
2608 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2609 SmallVector MaskAsInts;
2610 getShuffleMask(Mask, MaskAsInts);
2611 return isTransposeMask(MaskAsInts);
2612 }
2613
2614 /// Return true if this shuffle transposes the elements of its inputs without
2615 /// changing the length of the vectors. This operation may also be known as a
2616 /// merge or interleave. See the description for isTransposeMask() for the
2617 /// exact specification.
2618 /// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
2619 bool isTranspose() const {
2620 return !changesLength() && isTransposeMask(getMask());
24502621 }
24512622
24522623 /// Change values in a shuffle permute mask assuming the two vector operands
627627
628628 int TargetTransformInfo::getInstructionLatency(const Instruction *I) const {
629629 return TTIImpl->getInstructionLatency(I);
630 }
631
632 static bool isReverseVectorMask(ArrayRef Mask) {
633 bool ReverseLHS = true;
634 bool ReverseRHS = true;
635 unsigned MaskSize = Mask.size();
636
637 for (unsigned i = 0; i < MaskSize && (ReverseLHS || ReverseRHS); ++i) {
638 if (Mask[i] < 0)
639 continue;
640 ReverseLHS &= (Mask[i] == (int)(MaskSize - 1 - i));
641 ReverseRHS &= (Mask[i] == (int)(MaskSize + MaskSize - 1 - i));
642 }
643 return ReverseLHS || ReverseRHS;
644 }
645
646 static bool isSingleSourceVectorMask(ArrayRef Mask) {
647 bool ShuffleLHS = false;
648 bool ShuffleRHS = false;
649 unsigned MaskSize = Mask.size();
650
651 for (unsigned i = 0; i < MaskSize && !(ShuffleLHS && ShuffleRHS); ++i) {
652 if (Mask[i] < 0)
653 continue;
654 if ((unsigned)Mask[i] >= MaskSize)
655 ShuffleRHS = true;
656 else
657 ShuffleLHS = true;
658 }
659 return !(ShuffleLHS && ShuffleRHS);
660 }
661
662 static bool isZeroEltBroadcastVectorMask(ArrayRef Mask) {
663 bool BroadcastLHS = true;
664 bool BroadcastRHS = true;
665 unsigned MaskSize = Mask.size();
666
667 for (unsigned i = 0; i < MaskSize && (BroadcastLHS || BroadcastRHS); ++i) {
668 if (Mask[i] < 0)
669 continue;
670 BroadcastLHS &= (Mask[i] == 0);
671 BroadcastRHS &= (Mask[i] == (int)MaskSize);
672 }
673 return BroadcastLHS || BroadcastRHS;
674 }
675
676 static bool isIdentityVectorMask(ArrayRef Mask) {
677 bool IdentityLHS = true;
678 bool IdentityRHS = true;
679 unsigned MaskSize = Mask.size();
680
681 // Example: shufflevector A, B, <0,1,u,3>
682 // Example: shufflevector A, B, <4,u,6,u>
683 for (unsigned i = 0; i < MaskSize && (IdentityLHS || IdentityRHS); ++i) {
684 if (Mask[i] < 0)
685 continue;
686 IdentityLHS &= (Mask[i] == (int)i);
687 IdentityRHS &= (Mask[i] == (int)(i + MaskSize));
688 }
689 return IdentityLHS || IdentityRHS;
690 }
691
692 static bool isSelectVectorMask(ArrayRef Mask) {
693 bool IsSelect = true;
694 bool FoundLHS = false;
695 bool FoundRHS = false;
696 unsigned MaskSize = Mask.size();
697
698 // Example: shufflevector A, B, <0,1,6,3>
699 // Example: shufflevector A, B, <4,1,6,3>
700 for (unsigned i = 0; i < MaskSize && IsSelect; ++i) {
701 if (Mask[i] < 0)
702 continue;
703 bool IsLHS = (Mask[i] == (int)i);
704 bool IsRHS = (Mask[i] == (int)(i + MaskSize));
705 FoundLHS |= IsLHS;
706 FoundRHS |= IsRHS;
707 IsSelect = IsLHS || IsRHS;
708 }
709 // If we don't use both vectors this is really an Identity mask.
710 return IsSelect && FoundLHS && FoundRHS;
711 }
712
713 static bool isTransposeVectorMask(ArrayRef Mask) {
714 // Transpose vector masks transpose a 2xn matrix. They read corresponding
715 // even- or odd-numbered vector elements from two n-dimensional source
716 // vectors and write each result into consecutive elements of an
717 // n-dimensional destination vector. Two shuffles are necessary to complete
718 // the transpose, one for the even elements and another for the odd elements.
719 // This description closely follows how the TRN1 and TRN2 AArch64
720 // instructions operate.
721 //
722 // For example, a simple 2x2 matrix can be transposed with:
723 //
724 // ; Original matrix
725 // m0 =
726 // m1 =
727 //
728 // ; Transposed matrix
729 // t0 = = shufflevector m0, m1, <0, 2>
730 // t1 = = shufflevector m0, m1, <1, 3>
731 //
732 // For matrices having greater than n columns, the resulting nx2 transposed
733 // matrix is stored in two result vectors such that one vector contains
734 // interleaved elements from all the even-numbered rows and the other vector
735 // contains interleaved elements from all the odd-numbered rows. For example,
736 // a 2x4 matrix can be transposed with:
737 //
738 // ; Original matrix
739 // m0 =
740 // m1 =
741 //
742 // ; Transposed matrix
743 // t0 = = shufflevector m0, m1 <0, 4, 2, 6>
744 // t1 = = shufflevector m0, m1 <1, 5, 3, 7>
745 //
746 // The above explanation places limitations on what valid transpose masks can
747 // look like. These limitations are defined by the checks below.
748 //
749 // 1. The number of elements in the mask must be a power of two.
750 if (!isPowerOf2_32(Mask.size()))
751 return false;
752
753 // 2. The first element of the mask must be either a zero (for the
754 // even-numbered vector elements) or a one (for the odd-numbered vector
755 // elements).
756 if (Mask[0] != 0 && Mask[0] != 1)
757 return false;
758
759 // 3. The difference between the first two elements must be equal to the
760 // number of elements in the mask.
761 if (Mask[1] - Mask[0] != (int)Mask.size())
762 return false;
763
764 // 4. The difference between consecutive even-numbered and odd-numbered
765 // elements must be equal to two.
766 for (int I = 2; I < (int)Mask.size(); ++I)
767 if (Mask[I] - Mask[I - 2] != 2)
768 return false;
769
770 return true;
771630 }
772631
773632 static TargetTransformInfo::OperandValueKind
12351094 }
12361095 case Instruction::ShuffleVector: {
12371096 const ShuffleVectorInst *Shuffle = cast(I);
1238 Type *VecTypOp0 = Shuffle->getOperand(0)->getType();
1239 unsigned NumVecElems = VecTypOp0->getVectorNumElements();
1240 SmallVector Mask = Shuffle->getShuffleMask();
1241
1242 if (NumVecElems == Mask.size()) {
1243 if (isIdentityVectorMask(Mask))
1244 return 0;
1245
1246 if (isReverseVectorMask(Mask))
1247 return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Reverse,
1248 VecTypOp0, 0, nullptr);
1249
1250 if (isSelectVectorMask(Mask))
1251 return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Select,
1252 VecTypOp0, 0, nullptr);
1253
1254 if (isTransposeVectorMask(Mask))
1255 return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Transpose,
1256 VecTypOp0, 0, nullptr);
1257
1258 if (isZeroEltBroadcastVectorMask(Mask))
1259 return TTIImpl->getShuffleCost(TargetTransformInfo::SK_Broadcast,
1260 VecTypOp0, 0, nullptr);
1261
1262 if (isSingleSourceVectorMask(Mask))
1263 return TTIImpl->getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc,
1264 VecTypOp0, 0, nullptr);
1265
1266 return TTIImpl->getShuffleCost(TargetTransformInfo::SK_PermuteTwoSrc,
1267 VecTypOp0, 0, nullptr);
1268 }
1269
1270 return -1;
1097 // TODO: Identify and add costs for insert/extract subvector, etc.
1098 if (Shuffle->changesLength())
1099 return -1;
1100
1101 if (Shuffle->isIdentity())
1102 return 0;
1103
1104 Type *Ty = Shuffle->getType();
1105 if (Shuffle->isReverse())
1106 return TTIImpl->getShuffleCost(SK_Reverse, Ty, 0, nullptr);
1107
1108 if (Shuffle->isSelect())
1109 return TTIImpl->getShuffleCost(SK_Select, Ty, 0, nullptr);
1110
1111 if (Shuffle->isTranspose())
1112 return TTIImpl->getShuffleCost(SK_Transpose, Ty, 0, nullptr);
1113
1114 if (Shuffle->isZeroEltSplat())
1115 return TTIImpl->getShuffleCost(SK_Broadcast, Ty, 0, nullptr);
1116
1117 if (Shuffle->isSingleSource())
1118 return TTIImpl->getShuffleCost(SK_PermuteSingleSrc, Ty, 0, nullptr);
1119
1120 return TTIImpl->getShuffleCost(SK_PermuteTwoSrc, Ty, 0, nullptr);
12711121 }
12721122 case Instruction::Call:
12731123 if (const IntrinsicInst *II = dyn_cast(I)) {
16571657 return false;
16581658 }
16591659
1660 int ShuffleVectorInst::getMaskValue(Constant *Mask, unsigned i) {
1660 int ShuffleVectorInst::getMaskValue(const Constant *Mask, unsigned i) {
16611661 assert(i < Mask->getType()->getVectorNumElements() && "Index out of range");
16621662 if (auto *CDS = dyn_cast(Mask))
16631663 return CDS->getElementAsInteger(i);
16671667 return cast(C)->getZExtValue();
16681668 }
16691669
1670 void ShuffleVectorInst::getShuffleMask(Constant *Mask,
1670 void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
16711671 SmallVectorImpl &Result) {
16721672 unsigned NumElts = Mask->getType()->getVectorNumElements();
16731673
16821682 cast(C)->getZExtValue());
16831683 }
16841684 }
1685
1686 bool ShuffleVectorInst::isSingleSourceMask(ArrayRef Mask) {
1687 assert(!Mask.empty() && "Shuffle mask must contain elements");
1688 bool UsesLHS = false;
1689 bool UsesRHS = false;
1690 for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
1691 if (Mask[i] == -1)
1692 continue;
1693 assert(Mask[i] >= 0 && Mask[i] < (NumElts * 2) &&
1694 "Out-of-bounds shuffle mask element");
1695 UsesLHS |= (Mask[i] < NumElts);
1696 UsesRHS |= (Mask[i] >= NumElts);
1697 if (UsesLHS && UsesRHS)
1698 return false;
1699 }
1700 assert((UsesLHS ^ UsesRHS) && "Should have selected from exactly 1 source");
1701 return true;
1702 }
1703
1704 bool ShuffleVectorInst::isIdentityMask(ArrayRef Mask) {
1705 if (!isSingleSourceMask(Mask))
1706 return false;
1707 for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
1708 if (Mask[i] == -1)
1709 continue;
1710 if (Mask[i] != i && Mask[i] != (NumElts + i))
1711 return false;
1712 }
1713 return true;
1714 }
1715
1716 bool ShuffleVectorInst::isReverseMask(ArrayRef Mask) {
1717 if (!isSingleSourceMask(Mask))
1718 return false;
1719 for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
1720 if (Mask[i] == -1)
1721 continue;
1722 if (Mask[i] != (NumElts - 1 - i) && Mask[i] != (NumElts + NumElts - 1 - i))
1723 return false;
1724 }
1725 return true;
1726 }
1727
1728 bool ShuffleVectorInst::isZeroEltSplatMask(ArrayRef Mask) {
1729 if (!isSingleSourceMask(Mask))
1730 return false;
1731 for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
1732 if (Mask[i] == -1)
1733 continue;
1734 if (Mask[i] != 0 && Mask[i] != NumElts)
1735 return false;
1736 }
1737 return true;
1738 }
1739
1740 bool ShuffleVectorInst::isSelectMask(ArrayRef Mask) {
1741 // Select is differentiated from identity. It requires using both sources.
1742 if (isSingleSourceMask(Mask))
1743 return false;
1744 for (int i = 0, NumElts = Mask.size(); i < NumElts; ++i) {
1745 if (Mask[i] == -1)
1746 continue;
1747 if (Mask[i] != i && Mask[i] != (NumElts + i))
1748 return false;
1749 }
1750 return true;
1751 }
1752
1753 bool ShuffleVectorInst::isTransposeMask(ArrayRef Mask) {
1754 // Example masks that will return true:
1755 // v1 =
1756 // v2 =
1757 // trn1 = shufflevector v1, v2 <0, 4, 2, 6> =
1758 // trn2 = shufflevector v1, v2 <1, 5, 3, 7> =
1759
1760 // 1. The number of elements in the mask must be a power-of-2 and at least 2.
1761 int NumElts = Mask.size();
1762 if (NumElts < 2 || !isPowerOf2_32(NumElts))
1763 return false;
1764
1765 // 2. The first element of the mask must be either a 0 or a 1.
1766 if (Mask[0] != 0 && Mask[0] != 1)
1767 return false;
1768
1769 // 3. The difference between the first 2 elements must be equal to the
1770 // number of elements in the mask.
1771 if ((Mask[1] - Mask[0]) != NumElts)
1772 return false;
1773
1774 // 4. The difference between consecutive even-numbered and odd-numbered
1775 // elements must be equal to 2.
1776 for (int i = 2; i < NumElts; ++i) {
1777 int MaskEltVal = Mask[i];
1778 if (MaskEltVal == -1)
1779 return false;
1780 int MaskEltPrevVal = Mask[i - 2];
1781 if (MaskEltVal - MaskEltPrevVal != 2)
1782 return false;
1783 }
1784 return true;
1785 }
1786
16851787
16861788 //===----------------------------------------------------------------------===//
16871789 // InsertValueInst Class
746746 EXPECT_THAT(Indices, testing::ContainerEq(ArrayRef({-1, 4, 3})));
747747 }
748748
749 TEST(InstructionsTest, ShuffleMaskQueries) {
750 // Create the elements for various constant vectors.
751 LLVMContext Ctx;
752 Type *Int32Ty = Type::getInt32Ty(Ctx);
753 Constant *CU = UndefValue::get(Int32Ty);
754 Constant *C0 = ConstantInt::get(Int32Ty, 0);
755 Constant *C1 = ConstantInt::get(Int32Ty, 1);
756 Constant *C2 = ConstantInt::get(Int32Ty, 2);
757 Constant *C3 = ConstantInt::get(Int32Ty, 3);
758 Constant *C4 = ConstantInt::get(Int32Ty, 4);
759 Constant *C5 = ConstantInt::get(Int32Ty, 5);
760 Constant *C6 = ConstantInt::get(Int32Ty, 6);
761 Constant *C7 = ConstantInt::get(Int32Ty, 7);
762
763 Constant *Identity = ConstantVector::get({C0, CU, C2, C3, C4});
764 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(Identity));
765 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(Identity)); // identity is distinguished from select
766 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(Identity));
767 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(Identity)); // identity is always single source
768 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Identity));
769 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(Identity));
770
771 Constant *Select = ConstantVector::get({CU, C1, C5});
772 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(Select));
773 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(Select));
774 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(Select));
775 EXPECT_FALSE(ShuffleVectorInst::isSingleSourceMask(Select));
776 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Select));
777 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(Select));
778
779 Constant *Reverse = ConstantVector::get({C3, C2, C1, CU});
780 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(Reverse));
781 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(Reverse));
782 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(Reverse));
783 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(Reverse)); // reverse is always single source
784 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Reverse));
785 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(Reverse));
786
787 Constant *SingleSource = ConstantVector::get({C2, C2, C0, CU});
788 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(SingleSource));
789 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(SingleSource));
790 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(SingleSource));
791 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(SingleSource));
792 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(SingleSource));
793 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(SingleSource));
794
795 Constant *ZeroEltSplat = ConstantVector::get({C0, C0, CU, C0});
796 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(ZeroEltSplat));
797 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(ZeroEltSplat));
798 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(ZeroEltSplat));
799 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(ZeroEltSplat)); // 0-splat is always single source
800 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(ZeroEltSplat));
801 EXPECT_FALSE(ShuffleVectorInst::isTransposeMask(ZeroEltSplat));
802
803 Constant *Transpose = ConstantVector::get({C0, C4, C2, C6});
804 EXPECT_FALSE(ShuffleVectorInst::isIdentityMask(Transpose));
805 EXPECT_FALSE(ShuffleVectorInst::isSelectMask(Transpose));
806 EXPECT_FALSE(ShuffleVectorInst::isReverseMask(Transpose));
807 EXPECT_FALSE(ShuffleVectorInst::isSingleSourceMask(Transpose));
808 EXPECT_FALSE(ShuffleVectorInst::isZeroEltSplatMask(Transpose));
809 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(Transpose));
810
811 // More tests to make sure the logic is/stays correct...
812 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(ConstantVector::get({CU, C1, CU, C3})));
813 EXPECT_TRUE(ShuffleVectorInst::isIdentityMask(ConstantVector::get({C4, CU, C6, CU})));
814
815 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(ConstantVector::get({C4, C1, C6, CU})));
816 EXPECT_TRUE(ShuffleVectorInst::isSelectMask(ConstantVector::get({CU, C1, C6, C3})));
817
818 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(ConstantVector::get({C7, C6, CU, C4})));
819 EXPECT_TRUE(ShuffleVectorInst::isReverseMask(ConstantVector::get({C3, CU, C1, CU})));
820
821 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(ConstantVector::get({C7, C5, CU, C7})));
822 EXPECT_TRUE(ShuffleVectorInst::isSingleSourceMask(ConstantVector::get({C3, C0, CU, C3})));
823
824 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(ConstantVector::get({C4, CU, CU, C4})));
825 EXPECT_TRUE(ShuffleVectorInst::isZeroEltSplatMask(ConstantVector::get({CU, C0, CU, C0})));
826
827 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(ConstantVector::get({C1, C5, C3, C7})));
828 EXPECT_TRUE(ShuffleVectorInst::isTransposeMask(ConstantVector::get({C1, C3})));
829 }
830
749831 } // end anonymous namespace
750832 } // end namespace llvm