[llvm] [IA]: Construct (de)interleave4 out of (de)interleave2 (PR #89276)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 21 06:47:16 PDT 2024
================
@@ -16585,17 +16585,87 @@ bool AArch64TargetLowering::lowerInterleavedStore(StoreInst *SI,
return true;
}
+bool getDeinterleavedValues(Value *DI,
+ SmallVectorImpl<Instruction *> &DeinterleavedValues) {
+ if (!DI->hasNUsesOrMore(2))
+ return false;
+ auto *Extr1 = dyn_cast<ExtractValueInst>(*(DI->user_begin()));
+ auto *Extr2 = dyn_cast<ExtractValueInst>(*(++DI->user_begin()));
+ if (!Extr1 || !Extr2)
+ return false;
+
+ if (!Extr1->hasNUsesOrMore(1) || !Extr2->hasNUsesOrMore(1))
+ return false;
+ auto *DI1 = *(Extr1->user_begin());
+ auto *DI2 = *(Extr2->user_begin());
+
+ if (!DI1->hasNUsesOrMore(2) || !DI2->hasNUsesOrMore(2))
+ return false;
+ // Leaf nodes of the deinterleave tree:
+ auto *A = dyn_cast<ExtractValueInst>(*(DI1->user_begin()));
+ auto *B = dyn_cast<ExtractValueInst>(*(++DI1->user_begin()));
+ auto *C = dyn_cast<ExtractValueInst>(*(DI2->user_begin()));
+ auto *D = dyn_cast<ExtractValueInst>(*(++DI2->user_begin()));
+ // Make sure that the A,B,C,D are instructions of ExtractValue,
+ // before getting the extract index
+ if (!A || !B || !C || !D)
+ return false;
+
+ DeinterleavedValues.resize(4);
+ // Place the values into the vector in the order of extraction:
+ DeinterleavedValues[A->getIndices()[0] + (Extr1->getIndices()[0] * 2)] = A;
+ DeinterleavedValues[B->getIndices()[0] + (Extr1->getIndices()[0] * 2)] = B;
+ DeinterleavedValues[C->getIndices()[0] + (Extr2->getIndices()[0] * 2)] = C;
+ DeinterleavedValues[D->getIndices()[0] + (Extr2->getIndices()[0] * 2)] = D;
----------------
paulwalker-arm wrote:
It looks like the `*2` is being applied to the wrong extract, which explains why you had to swap the middle values below.
It depends on how paranoid we need to be because I suppose there's the chance that an index might not be 0 or 1, so worth adding `& 0x3` to limit the range?
You'll also need to have another round of null pointer checks for `DeinterleavedValues[0-3]` just in case the extracts are not evenly distributed.
https://github.com/llvm/llvm-project/pull/89276
More information about the llvm-commits
mailing list