[llvm] [AArch64] recognise zip1/zip2 with flipped operands (PR #167235)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 19 02:37:24 PST 2025
================
@@ -6623,34 +6623,49 @@ inline unsigned getPerfectShuffleCost(llvm::ArrayRef<int> M) {
/// Return true for zip1 or zip2 masks of the form:
/// <0, 8, 1, 9, 2, 10, 3, 11> or
-/// <4, 12, 5, 13, 6, 14, 7, 15>
+/// <4, 12, 5, 13, 6, 14, 7, 15> or
+/// <8, 0, 9, 1, 10, 2, 11, 3> or
+/// <12, 4, 13, 5, 14, 6, 15, 7>
inline bool isZIPMask(ArrayRef<int> M, unsigned NumElts,
- unsigned &WhichResultOut) {
+ unsigned &WhichResultOut, unsigned &OperandOrderOut) {
if (NumElts % 2 != 0)
return false;
- // Check the first non-undef element for which half to use.
- unsigned WhichResult = 2;
- for (unsigned i = 0; i != NumElts / 2; i++) {
- if (M[i * 2] >= 0) {
- WhichResult = ((unsigned)M[i * 2] == i ? 0 : 1);
- break;
- } else if (M[i * 2 + 1] >= 0) {
- WhichResult = ((unsigned)M[i * 2 + 1] == NumElts + i ? 0 : 1);
- break;
- }
- }
- if (WhichResult == 2)
- return false;
+ // "Variant" refers to the distinction bwetween zip1 and zip2, while
+ // "Order" refers to sequence of input registers (matching vs flipped).
+ bool Variant0Order0 = true;
+ bool Variant1Order0 = true;
+ bool Variant0Order1 = true;
+ bool Variant1Order1 = true;
// Check all elements match.
- unsigned Idx = WhichResult * NumElts / 2;
for (unsigned i = 0; i != NumElts; i += 2) {
- if ((M[i] >= 0 && (unsigned)M[i] != Idx) ||
- (M[i + 1] >= 0 && (unsigned)M[i + 1] != Idx + NumElts))
- return false;
- Idx += 1;
+ if (M[i] >= 0) {
+ if ((unsigned)M[i] != i / 2)
----------------
davemgreen wrote:
Perhaps pull `(unsigned)M[i]` out into a separate variable.
https://github.com/llvm/llvm-project/pull/167235
More information about the llvm-commits
mailing list