llvm.org GIT mirror llvm / 16e0f15
[X86][SSE] Moved shuffle mask widening/narrowing helper functions earlier in the file. Will be necessary for a future patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288395 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Pilgrim 3 years ago
1 changed file(s) with 84 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
44794479 if (!isUndefOrZero(Mask[i]))
44804480 return false;
44814481 return true;
4482 }
4483
4484 /// \brief Helper function to test whether a shuffle mask could be
4485 /// simplified by widening the elements being shuffled.
4486 ///
4487 /// Appends the mask for wider elements in WidenedMask if valid. Otherwise
4488 /// leaves it in an unspecified state.
4489 ///
4490 /// NOTE: This must handle normal vector shuffle masks and *target* vector
4491 /// shuffle masks. The latter have the special property of a '-2' representing
4492 /// a zero-ed lane of a vector.
4493 static bool canWidenShuffleElements(ArrayRef Mask,
4494 SmallVectorImpl &WidenedMask) {
4495 WidenedMask.assign(Mask.size() / 2, 0);
4496 for (int i = 0, Size = Mask.size(); i < Size; i += 2) {
4497 // If both elements are undef, its trivial.
4498 if (Mask[i] == SM_SentinelUndef && Mask[i + 1] == SM_SentinelUndef) {
4499 WidenedMask[i / 2] = SM_SentinelUndef;
4500 continue;
4501 }
4502
4503 // Check for an undef mask and a mask value properly aligned to fit with
4504 // a pair of values. If we find such a case, use the non-undef mask's value.
4505 if (Mask[i] == SM_SentinelUndef && Mask[i + 1] >= 0 &&
4506 Mask[i + 1] % 2 == 1) {
4507 WidenedMask[i / 2] = Mask[i + 1] / 2;
4508 continue;
4509 }
4510 if (Mask[i + 1] == SM_SentinelUndef && Mask[i] >= 0 && Mask[i] % 2 == 0) {
4511 WidenedMask[i / 2] = Mask[i] / 2;
4512 continue;
4513 }
4514
4515 // When zeroing, we need to spread the zeroing across both lanes to widen.
4516 if (Mask[i] == SM_SentinelZero || Mask[i + 1] == SM_SentinelZero) {
4517 if ((Mask[i] == SM_SentinelZero || Mask[i] == SM_SentinelUndef) &&
4518 (Mask[i + 1] == SM_SentinelZero || Mask[i + 1] == SM_SentinelUndef)) {
4519 WidenedMask[i / 2] = SM_SentinelZero;
4520 continue;
4521 }
4522 return false;
4523 }
4524
4525 // Finally check if the two mask values are adjacent and aligned with
4526 // a pair.
4527 if (Mask[i] != SM_SentinelUndef && Mask[i] % 2 == 0 &&
4528 Mask[i] + 1 == Mask[i + 1]) {
4529 WidenedMask[i / 2] = Mask[i] / 2;
4530 continue;
4531 }
4532
4533 // Otherwise we can't safely widen the elements used in this shuffle.
4534 return false;
4535 }
4536 assert(WidenedMask.size() == Mask.size() / 2 &&
4537 "Incorrect size of mask after widening the elements!");
4538
4539 return true;
4540 }
4541
4542 /// Helper function to scale a shuffle or target shuffle mask, replacing each
4543 /// mask index with the scaled sequential indices for an equivalent narrowed
4544 /// mask. This is the reverse process to canWidenShuffleElements, but can always
4545 /// succeed.
4546 static void scaleShuffleMask(int Scale, ArrayRef Mask,
4547 SmallVectorImpl &ScaledMask) {
4548 assert(0 < Scale && "Unexpected scaling factor");
4549 int NumElts = Mask.size();
4550 ScaledMask.assign(NumElts * Scale, -1);
4551
4552 for (int i = 0; i != NumElts; ++i) {
4553 int M = Mask[i];
4554
4555 // Repeat sentinel values in every mask element.
4556 if (M < 0) {
4557 for (int s = 0; s != Scale; ++s)
4558 ScaledMask[(Scale * i) + s] = M;
4559 continue;
4560 }
4561
4562 // Scale mask element and increment across each mask element.
4563 for (int s = 0; s != Scale; ++s)
4564 ScaledMask[(Scale * i) + s] = (Scale * M) + s;
4565 }
44824566 }
44834567
44844568 /// Return true if the specified EXTRACT_SUBVECTOR operand specifies a vector
75127596 return isRepeatedShuffleMask(256, VT, Mask, RepeatedMask);
75137597 }
75147598
7515 static void scaleShuffleMask(int Scale, ArrayRef Mask,
7516 SmallVectorImpl &ScaledMask) {
7517 assert(0 < Scale && "Unexpected scaling factor");
7518 int NumElts = Mask.size();
7519 ScaledMask.assign(NumElts * Scale, -1);
7520
7521 for (int i = 0; i != NumElts; ++i) {
7522 int M = Mask[i];
7523
7524 // Repeat sentinel values in every mask element.
7525 if (M < 0) {
7526 for (int s = 0; s != Scale; ++s)
7527 ScaledMask[(Scale * i) + s] = M;
7528 continue;
7529 }
7530
7531 // Scale mask element and increment across each mask element.
7532 for (int s = 0; s != Scale; ++s)
7533 ScaledMask[(Scale * i) + s] = (Scale * M) + s;
7534 }
7535 }
7536
75377599 /// \brief Checks whether a shuffle mask is equivalent to an explicit list of
75387600 /// arguments.
75397601 ///
1092710989 default:
1092810990 llvm_unreachable("Unimplemented!");
1092910991 }
10930 }
10931
10932 /// \brief Helper function to test whether a shuffle mask could be
10933 /// simplified by widening the elements being shuffled.
10934 ///
10935 /// Appends the mask for wider elements in WidenedMask if valid. Otherwise
10936 /// leaves it in an unspecified state.
10937 ///
10938 /// NOTE: This must handle normal vector shuffle masks and *target* vector
10939 /// shuffle masks. The latter have the special property of a '-2' representing
10940 /// a zero-ed lane of a vector.
10941 static bool canWidenShuffleElements(ArrayRef Mask,
10942 SmallVectorImpl &WidenedMask) {
10943 WidenedMask.assign(Mask.size() / 2, 0);
10944 for (int i = 0, Size = Mask.size(); i < Size; i += 2) {
10945 // If both elements are undef, its trivial.
10946 if (Mask[i] == SM_SentinelUndef && Mask[i + 1] == SM_SentinelUndef) {
10947 WidenedMask[i/2] = SM_SentinelUndef;
10948 continue;
10949 }
10950
10951 // Check for an undef mask and a mask value properly aligned to fit with
10952 // a pair of values. If we find such a case, use the non-undef mask's value.
10953 if (Mask[i] == SM_SentinelUndef && Mask[i + 1] >= 0 && Mask[i + 1] % 2 == 1) {
10954 WidenedMask[i/2] = Mask[i + 1] / 2;
10955 continue;
10956 }
10957 if (Mask[i + 1] == SM_SentinelUndef && Mask[i] >= 0 && Mask[i] % 2 == 0) {
10958 WidenedMask[i/2] = Mask[i] / 2;
10959 continue;
10960 }
10961
10962 // When zeroing, we need to spread the zeroing across both lanes to widen.
10963 if (Mask[i] == SM_SentinelZero || Mask[i + 1] == SM_SentinelZero) {
10964 if ((Mask[i] == SM_SentinelZero || Mask[i] == SM_SentinelUndef) &&
10965 (Mask[i + 1] == SM_SentinelZero || Mask[i + 1] == SM_SentinelUndef)) {
10966 WidenedMask[i/2] = SM_SentinelZero;
10967 continue;
10968 }
10969 return false;
10970 }
10971
10972 // Finally check if the two mask values are adjacent and aligned with
10973 // a pair.
10974 if (Mask[i] != SM_SentinelUndef && Mask[i] % 2 == 0 && Mask[i] + 1 == Mask[i + 1]) {
10975 WidenedMask[i/2] = Mask[i] / 2;
10976 continue;
10977 }
10978
10979 // Otherwise we can't safely widen the elements used in this shuffle.
10980 return false;
10981 }
10982 assert(WidenedMask.size() == Mask.size() / 2 &&
10983 "Incorrect size of mask after widening the elements!");
10984
10985 return true;
1098610992 }
1098710993
1098810994 /// \brief Generic routine to split vector shuffle into half-sized shuffles.