[llvm] [IA]: Construct (de)interleave4 out of (de)interleave2 (PR #89276)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 30 09:56:16 PDT 2024
================
@@ -16906,17 +16906,141 @@ bool AArch64TargetLowering::lowerInterleavedStore(StoreInst *SI,
return true;
}
+bool getDeinterleave2Values(
+ Value *DI, SmallVectorImpl<Instruction *> &DeinterleavedValues) {
+ if (!DI->hasNUses(2))
+ return false;
+ auto *Extr1 = dyn_cast<ExtractValueInst>(*(DI->user_begin()));
+ auto *Extr2 = dyn_cast<ExtractValueInst>(*(++DI->user_begin()));
+ if (!Extr1 || !Extr2)
+ return false;
+
+ DeinterleavedValues.resize(2);
+ // Place the values into the vector in the order of extraction:
+ DeinterleavedValues[0x1 & (Extr1->getIndices()[0])] = Extr1;
+ DeinterleavedValues[0x1 & (Extr2->getIndices()[0])] = Extr2;
+ if (!DeinterleavedValues[0] || !DeinterleavedValues[1])
+ return false;
+
+ // Make sure that the extracted values match the deinterleave tree pattern
+ if (!match(DeinterleavedValues[0], m_ExtractValue<0>((m_Specific(DI)))) ||
+ !match(DeinterleavedValues[1], m_ExtractValue<1>((m_Specific(DI))))) {
+ LLVM_DEBUG(dbgs() << "matching deinterleave2 failed\n");
+ return false;
+ }
+ return true;
+}
+
+/*
+Diagram for DI tree.
+ [LOAD]
+ |
+ [DI]
+ / \
+ [Extr<0>] [Extr<1>]
+ | |
+ [DI] [DI]
+ / \ / \
+ [Extr<0>][Extr<1>] [Extr<0>][Extr<1>]
+ | | | |
+roots: A C B D
+roots in correct order of DI4: A B C D.
+If there is a pattern matches the deinterleave tree above, then we can construct
+DI4 out of that pattern. This function tries to match the deinterleave tree
+pattern, and fetch the tree roots, so that in further steps they can be replaced
+by the output of DI4.
+*/
+bool getDeinterleave4Values(Value *DI,
+ SmallVectorImpl<Instruction *> &DeinterleavedValues,
+ SmallVectorImpl<Instruction *> &DeadInstructions) {
+ if (!DI->hasNUses(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->hasNUses(1) || !Extr2->hasNUses(1))
----------------
paulwalker-arm wrote:
Please use `!###->hasOneUse()` here because it's more efficient than `!hasNUses(1)`.
https://github.com/llvm/llvm-project/pull/89276
More information about the llvm-commits
mailing list