14#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64PERFECTSHUFFLE_H
15#define LLVM_LIB_TARGET_AARCH64_AARCH64PERFECTSHUFFLE_H
25 assert(M.size() == 4 &&
"Expected a 4 entry perfect shuffle");
29 return E.value() < 0 ||
E.value() == (int)
E.index();
33 return E.value() < 0 ||
E.value() == (int)
E.index() + 4;
39 unsigned PFIndexes[4];
40 for (
unsigned i = 0; i != 4; ++i) {
41 assert(M[i] < 8 &&
"Expected a maximum entry of 8 for shuffle mask");
49 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
50 PFIndexes[2] * 9 + PFIndexes[3];
53 return (PFEntry >> 30) + 1;
62 unsigned &WhichResultOut,
unsigned &OperandOrderOut) {
69 bool Result0Order0 =
true;
70 bool Result1Order0 =
true;
71 bool Result0Order1 =
true;
72 bool Result1Order1 =
true;
74 for (
unsigned i = 0; i != NumElts; i += 2) {
78 Result0Order0 =
false;
79 if (EvenElt != NumElts / 2 + i / 2)
80 Result1Order0 =
false;
81 if (EvenElt != NumElts + i / 2)
82 Result0Order1 =
false;
83 if (EvenElt != NumElts + NumElts / 2 + i / 2)
84 Result1Order1 =
false;
87 unsigned OddElt = (
unsigned)M[i + 1];
88 if (OddElt != NumElts + i / 2)
89 Result0Order0 =
false;
90 if (OddElt != NumElts + NumElts / 2 + i / 2)
91 Result1Order0 =
false;
93 Result0Order1 =
false;
94 if (OddElt != NumElts / 2 + i / 2)
95 Result1Order1 =
false;
99 if (Result0Order0 + Result1Order0 + Result0Order1 + Result1Order1 != 1)
102 WhichResultOut = (Result0Order0 || Result0Order1) ? 0 : 1;
103 OperandOrderOut = (Result0Order0 || Result1Order0) ? 0 : 1;
111 unsigned &WhichResult) {
112 if (NumElts % 2 != 0)
114 WhichResult = (M[0] == 0 ? 0 : 1);
115 unsigned Idx = WhichResult * NumElts / 2;
116 for (
unsigned i = 0; i != NumElts; i += 2) {
117 if ((M[i] >= 0 && (
unsigned)M[i] != Idx) ||
118 (M[i + 1] >= 0 && (
unsigned)M[i + 1] != Idx))
130 unsigned &WhichResultOut) {
132 unsigned WhichResult = 2;
133 for (
unsigned i = 0; i != NumElts; i++) {
135 WhichResult = ((
unsigned)M[i] == i * 2 ? 0 : 1);
139 if (WhichResult == 2)
143 for (
unsigned i = 0; i != NumElts; ++i) {
146 if ((
unsigned)M[i] != 2 * i + WhichResult)
149 WhichResultOut = WhichResult;
157 unsigned &WhichResult) {
158 unsigned Half = NumElts / 2;
159 WhichResult = (M[0] == 0 ? 0 : 1);
160 for (
unsigned j = 0; j != 2; ++j) {
161 unsigned Idx = WhichResult;
162 for (
unsigned i = 0; i != Half; ++i) {
163 int MIdx = M[i + j * Half];
164 if (MIdx >= 0 && (
unsigned)MIdx != Idx)
179 unsigned &WhichResultOut,
unsigned &OperandOrderOut) {
180 if (NumElts % 2 != 0)
186 bool Result0Order0 =
true;
187 bool Result1Order0 =
true;
188 bool Result0Order1 =
true;
189 bool Result1Order1 =
true;
191 for (
unsigned i = 0; i != NumElts; i += 2) {
195 Result0Order0 =
false;
196 if (EvenElt != i + 1)
197 Result1Order0 =
false;
198 if (EvenElt != NumElts + i)
199 Result0Order1 =
false;
200 if (EvenElt != NumElts + i + 1)
201 Result1Order1 =
false;
204 unsigned OddElt = (
unsigned)M[i + 1];
205 if (OddElt != NumElts + i)
206 Result0Order0 =
false;
207 if (OddElt != NumElts + i + 1)
208 Result1Order0 =
false;
210 Result0Order1 =
false;
212 Result1Order1 =
false;
216 if (Result0Order0 + Result1Order0 + Result0Order1 + Result1Order1 != 1)
219 WhichResultOut = (Result0Order0 || Result0Order1) ? 0 : 1;
220 OperandOrderOut = (Result0Order0 || Result1Order0) ? 0 : 1;
228 unsigned &WhichResult) {
229 if (NumElts % 2 != 0)
231 WhichResult = (M[0] == 0 ? 0 : 1);
232 for (
unsigned i = 0; i < NumElts; i += 2) {
233 if ((M[i] >= 0 && (
unsigned)M[i] != i + WhichResult) ||
234 (M[i + 1] >= 0 && (
unsigned)M[i + 1] != i + WhichResult))
247 "Only possible block sizes for REV are: 16, 32, 64, 128");
249 unsigned BlockElts = M[0] + 1;
257 for (
unsigned i = 0; i < NumElts; ++i) {
260 if ((
unsigned)M[i] != (i - i % BlockElts) + (BlockElts - 1 - i % BlockElts))
270 unsigned SegmentSize) {
274 if (SegmentSize * Segments != Mask.size())
278 if (Lane >= SegmentSize)
284 const unsigned SegmentIndex =
P.index() / SegmentSize;
285 return P.value() < 0 ||
286 unsigned(
P.value()) == Lane + SegmentIndex * SegmentSize;
295 unsigned SegmentSize) {
297 if (SegmentSize * Segments != Mask.size())
303 const unsigned IndexWithinSegment =
P.index() % SegmentSize;
304 return P.value() < 0 ||
unsigned(
P.value()) == IndexWithinSegment;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static const int BlockSize
Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an optimization pass for GlobalISel generic memory operations.
std::optional< unsigned > isDUPQMask(ArrayRef< int > Mask, unsigned Segments, unsigned SegmentSize)
isDUPQMask - matches a splat of equivalent lanes within segments of a given number of elements.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isZIPMask(ArrayRef< int > M, unsigned NumElts, unsigned &WhichResultOut, unsigned &OperandOrderOut)
Return true for zip1 or zip2 masks of the form: <0, 8, 1, 9, 2, 10, 3, 11> (WhichResultOut = 0,...
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
bool isDUPFirstSegmentMask(ArrayRef< int > Mask, unsigned Segments, unsigned SegmentSize)
isDUPFirstSegmentMask - matches a splat of the first 128b segment.
unsigned getPerfectShuffleCost(llvm::ArrayRef< int > M)
bool isUZPMask(ArrayRef< int > M, unsigned NumElts, unsigned &WhichResultOut)
Return true for uzp1 or uzp2 masks of the form: <0, 2, 4, 6, 8, 10, 12, 14> or <1,...
bool isREVMask(ArrayRef< int > M, unsigned EltSize, unsigned NumElts, unsigned BlockSize)
isREVMask - Check if a vector shuffle corresponds to a REV instruction with the specified blocksize.
bool isUZP_v_undef_Mask(ArrayRef< int > M, unsigned NumElts, unsigned &WhichResult)
isUZP_v_undef_Mask - Special case of isUZPMask for canonical form of "vector_shuffle v,...
const unsigned PerfectShuffleTable[6561+1]
bool isZIP_v_undef_Mask(ArrayRef< int > M, unsigned NumElts, unsigned &WhichResult)
isZIP_v_undef_Mask - Special case of isZIPMask for canonical form of "vector_shuffle v,...
bool isTRN_v_undef_Mask(ArrayRef< int > M, unsigned NumElts, unsigned &WhichResult)
isTRN_v_undef_Mask - Special case of isTRNMask for canonical form of "vector_shuffle v,...
bool isTRNMask(ArrayRef< int > M, unsigned NumElts, unsigned &WhichResultOut, unsigned &OperandOrderOut)
Return true for trn1 or trn2 masks of the form: <0, 8, 2, 10, 4, 12, 6, 14> (WhichResultOut = 0,...