[llvm] [InstCombine] Fold vector.reduce.op(vector.reverse(X)) -> vector.reduce.op(X) (PR #91743)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Fri May 17 02:53:26 PDT 2024


================
@@ -1435,6 +1435,33 @@ static Instruction *foldBitOrderCrossLogicOp(Value *V,
   return nullptr;
 }
 
+static Value *simplifyReductionOperand(Value *Arg, bool CanReorderLanes) {
+  if (!CanReorderLanes)
+    return nullptr;
+
+  Value *V;
+  if (match(Arg, m_VecReverse(m_Value(V))))
+    return V;
+
+  ArrayRef<int> Mask;
+  if (!isa<FixedVectorType>(Arg->getType()) ||
+      !match(Arg, m_Shuffle(m_Value(V), m_Undef(), m_Mask(Mask))) ||
+      !cast<ShuffleVectorInst>(Arg)->isSingleSource())
+    return nullptr;
+
+  int Sz = Mask.size();
+  SmallBitVector UsedIndices(Sz);
+  for (int Idx : Mask) {
+    if (Idx == PoisonMaskElem || UsedIndices.test(Idx))
+      return nullptr;
+    UsedIndices.set(Idx);
+  }
+
+  // Can remove shuffle iff just shuffled elements, no repeats, undefs, or
+  // other changes.
+  return UsedIndices.all() ? V : nullptr;
----------------
david-arm wrote:

I had a look at using `getShuffleDemandedElts` and the code didn't immediately look much better as I still need to keep most of the existing checks, i.e. check for `isSingleSource` and so on. For now, I'd prefer to leave the code as it is, but I'm happy to revisit this in a follow-on patch. Just out of curiosity, have you seen any examples where we pass through the 2nd operand of the shufflevector? i.e. `reduce_or(shufflevector(<4 x i32> %a, <4 x i32> %b, <4 x i32> <7, 5, 6, 4>))`. I'd expect this to be canonicalised to `reduce_or(shufflevector(<4 x i32> %a, <4 x i32> undef, <4 x i32> <3, 1, 2, 0>))`

https://github.com/llvm/llvm-project/pull/91743


More information about the llvm-commits mailing list