[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