[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
Mon May 13 01:48:39 PDT 2024
================
@@ -3394,8 +3436,31 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
: 0;
Value *Arg = II->getArgOperand(ArgIdx);
Value *V;
+
+ if (!CanBeReassociated)
+ break;
+
+ if (match(Arg, m_VecReverse(m_Value(V)))) {
+ Value *Res;
+ switch (IID) {
+ case Intrinsic::vector_reduce_fadd:
+ Res = Builder.CreateFAddReduce(II->getArgOperand(0), V);
+ break;
+ case Intrinsic::vector_reduce_fmul:
+ Res = Builder.CreateFMulReduce(II->getArgOperand(0), V);
+ break;
+ case Intrinsic::vector_reduce_fmin:
+ Res = Builder.CreateFPMinReduce(V);
+ break;
+ case Intrinsic::vector_reduce_fmax:
+ Res = Builder.CreateFPMaxReduce(V);
+ break;
+ }
+ return replaceInstUsesWith(CI, Res);
+ }
+
----------------
david-arm wrote:
There is a problem with this approach. In the Intrinsic::vector_reduce_or case if I use the same approach as we do for fadd, etc. then what happens is on the first iteration we hit this code:
```
replaceUse(II->getOperandUse(ArgIdx), V);
return nullptr;
```
and then on the second iteration we still hit the existing code in Intrinsic::vector_reduce_or:
```
if (!IsReverse && match(Arg, m_ZExtOrSExtOrSelf(m_Value(Vect)))) {
...
return replaceInstUsesWith(CI, Res);
```
because on the 2nd iteration the reduce_or input is no longer a reverse intrinsic. InstCombine quite rightly gets unhappy with this error:
LLVM ERROR: Instruction Combining did not reach a fixpoint after 1 iterations
Essentially it looks like the only way I can stop the iterations is to return `replaceInstUsesWith` when we first spot the pattern (reduce.or(vector.reverse())) unless you have other suggestions that may help?
https://github.com/llvm/llvm-project/pull/91743
More information about the llvm-commits
mailing list