[llvm] [InstCombine] Pull vector reverse through intrinsics (PR #146384)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 1 03:30:58 PDT 2025
================
@@ -1456,6 +1456,45 @@ InstCombinerImpl::foldShuffledIntrinsicOperands(IntrinsicInst *II) {
return new ShuffleVectorInst(NewIntrinsic, Mask);
}
+/// If all arguments of the intrinsic are reverses, try to pull the reverse
+/// after the intrinsic.
+Value *InstCombinerImpl::foldReversedIntrinsicOperands(IntrinsicInst *II) {
+ if (!isTriviallyVectorizable(II->getIntrinsicID()) ||
+ !II->getCalledFunction()->isSpeculatable())
+ return nullptr;
+
+ // At least 1 operand must be a reverse with 1 use because we are creating 2
+ // instructions.
+ if (none_of(II->args(), [](Value *V) {
+ return match(V, m_OneUse(m_VecReverse(m_Value())));
+ }))
+ return nullptr;
+
+ Value *X;
+ Constant *C;
+ SmallVector<Value *> NewArgs;
+ for (Use &Arg : II->args()) {
+ if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(),
+ Arg.getOperandNo(), nullptr))
+ NewArgs.push_back(Arg);
+ else if (match(&Arg, m_VecReverse(m_Value(X))))
+ NewArgs.push_back(X);
+ else if (Value *Splat = getSplatValue(Arg))
----------------
lukel97 wrote:
I looked at the existing binop combine to see what it was doing and it actually doesn't create new splats, it instead checks `isSplatValue` which doesn't allow undef lanes:
```c++
if (match(LHS, m_VecReverse(m_Value(V1)))) {
// Op(rev(V1), rev(V2)) -> rev(Op(V1, V2))
if (match(RHS, m_VecReverse(m_Value(V2))) &&
(LHS->hasOneUse() || RHS->hasOneUse() ||
(LHS == RHS && LHS->hasNUses(2))))
return createBinOpReverse(V1, V2);
// Op(rev(V1), RHSSplat)) -> rev(Op(V1, RHSSplat))
if (LHS->hasOneUse() && isSplatValue(RHS))
return createBinOpReverse(V1, RHS);
}
// Op(LHSSplat, rev(V2)) -> rev(Op(LHSSplat, V2))
else if (isSplatValue(LHS) && match(RHS, m_OneUse(m_VecReverse(m_Value(V2)))))
return createBinOpReverse(LHS, V2);
```
So I've done the same here in e0acdf38c5c3dcc021fe1a6ffe34115fb02bc321 to keep it consistent, disallowing poison lanes. I don't think supporting poison lanes is important given that reverse intrinsics are really only used for scalable vectors.
https://github.com/llvm/llvm-project/pull/146384
More information about the llvm-commits
mailing list