[llvm] [IA]: Construct (de)interleave4 out of (de)interleave2 (PR #89276)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 15 09:33:28 PDT 2024
================
@@ -16585,17 +16585,74 @@ bool AArch64TargetLowering::lowerInterleavedStore(StoreInst *SI,
return true;
}
+bool getDeinterleavedValues(Value *DI,
+ SmallVectorImpl<Value *> &DeinterleavedValues,
+ SmallVectorImpl<Instruction *> &DeadInsts) {
+ if (!DI->hasNUses(2))
+ return false;
+
+ // make sure that the users of DI are extractValue instructions
+ auto *Extr0 = *(++DI->user_begin());
+ if (!match(Extr0, m_ExtractValue<0>(m_Deinterleave2(m_Value()))))
+ return false;
+ auto *Extr1 = *(DI->user_begin());
+ if (!match(Extr1, m_ExtractValue<1>(m_Deinterleave2(m_Value()))))
+ return false;
+
+ // each extractValue instruction is expected to have a single user,
+ // which should be another DI
+ if (!Extr0->hasOneUser() || !Extr1->hasOneUser())
+ return false;
+ auto *DI1 = *(Extr0->user_begin());
+ if (!match(DI1, m_Deinterleave2(m_Value())))
+ return false;
+ auto *DI2 = *(Extr1->user_begin());
+ if (!match(DI2, m_Deinterleave2(m_Value())))
+ return false;
+
+ if (!DI1->hasNUses(2) || !DI2->hasNUses(2))
+ return false;
+
+ // Leaf nodes of the deinterleave tree
+ auto *A = *(++DI1->user_begin());
+ auto *C = *(DI1->user_begin());
+ auto *B = *(++DI2->user_begin());
+ auto *D = *(DI2->user_begin());
----------------
paulwalker-arm wrote:
Is this making an assumption about the order the results will be extracted? i.e. it looks like you're assuming A will be `m_ExtractValue<0>` and B is `m_ExtractValue<0>`. You also do this above but at least there the bad result would bogusly bail out of the transformation whereas here the emitted code will be wrong.
https://github.com/llvm/llvm-project/pull/89276
More information about the llvm-commits
mailing list