Skip to content

Commit 098adb0

Browse files
committed
Rework as order canonicalization instead of elimination
1 parent d31b649 commit 098adb0

File tree

3 files changed

+39
-33
lines changed

3 files changed

+39
-33
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,41 +3591,15 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
35913591
break;
35923592
}
35933593
case Intrinsic::experimental_vp_reverse: {
3594-
Value *BO0, *BO1, *X, *Y;
3594+
Value *X;
35953595
Value *Vec = II->getArgOperand(0);
35963596
Value *Mask = II->getArgOperand(1);
35973597
if (!match(Mask, m_AllOnes()))
35983598
break;
35993599
Value *EVL = II->getArgOperand(2);
3600-
auto m_VPReverse = [&](Value *&Vec) {
3601-
return m_Intrinsic<Intrinsic::experimental_vp_reverse>(
3602-
m_Value(Vec), m_AllOnes(), m_Specific(EVL));
3603-
};
3604-
if (match(Vec, m_OneUse(m_BinOp(m_Value(BO0), m_Value(BO1))))) {
3605-
auto *OldBinOp = cast<BinaryOperator>(Vec);
3606-
if (match(BO0, m_VPReverse(X))) {
3607-
// rev(binop rev(X), rev(Y)) --> binop X, Y
3608-
if (match(BO1, m_VPReverse(Y)))
3609-
return replaceInstUsesWith(CI, BinaryOperator::CreateWithCopiedFlags(
3610-
OldBinOp->getOpcode(), X, Y,
3611-
OldBinOp, OldBinOp->getName(),
3612-
II->getIterator()));
3613-
// rev(binop rev(X), BO1Splat) --> binop X, BO1Splat
3614-
if (isSplatValue(BO1))
3615-
return replaceInstUsesWith(CI, BinaryOperator::CreateWithCopiedFlags(
3616-
OldBinOp->getOpcode(), X, BO1,
3617-
OldBinOp, OldBinOp->getName(),
3618-
II->getIterator()));
3619-
}
3620-
// rev(binop BO0Splat, rev(Y)) --> binop BO0Splat, Y
3621-
if (match(BO1, m_VPReverse(Y)) && isSplatValue(BO0))
3622-
return replaceInstUsesWith(CI,
3623-
BinaryOperator::CreateWithCopiedFlags(
3624-
OldBinOp->getOpcode(), BO0, Y, OldBinOp,
3625-
OldBinOp->getName(), II->getIterator()));
3626-
}
36273600
// rev(unop rev(X)) --> unop X
3628-
if (match(Vec, m_OneUse(m_UnOp(m_VPReverse(X))))) {
3601+
if (match(Vec, m_OneUse(m_UnOp(m_Intrinsic<Intrinsic::experimental_vp_reverse>(
3602+
m_Value(X), m_AllOnes(), m_Specific(EVL)))))) {
36293603
auto *OldUnOp = cast<UnaryOperator>(Vec);
36303604
auto *NewUnOp = UnaryOperator::CreateWithCopiedFlags(
36313605
OldUnOp->getOpcode(), X, OldUnOp, OldUnOp->getName(),

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,39 @@ Instruction *InstCombinerImpl::foldVectorBinop(BinaryOperator &Inst) {
22312231
else if (isSplatValue(LHS) && match(RHS, m_OneUse(m_VecReverse(m_Value(V2)))))
22322232
return createBinOpReverse(LHS, V2);
22332233

2234+
auto createBinOpVPReverse = [&](Value *X, Value *Y, Value *EVL) {
2235+
Value *V = Builder.CreateBinOp(Opcode, X, Y, Inst.getName());
2236+
if (auto *BO = dyn_cast<BinaryOperator>(V))
2237+
BO->copyIRFlags(&Inst);
2238+
2239+
ElementCount EC = cast<VectorType>(V->getType())->getElementCount();
2240+
Value *AllTrueMask = Builder.CreateVectorSplat(EC, Builder.getTrue());
2241+
Module *M = Inst.getModule();
2242+
Function *F = Intrinsic::getOrInsertDeclaration(
2243+
M, Intrinsic::experimental_vp_reverse, V->getType());
2244+
return CallInst::Create(F, {V, AllTrueMask, EVL});
2245+
};
2246+
2247+
Value *EVL;
2248+
if (match(LHS, m_Intrinsic<Intrinsic::experimental_vp_reverse>(
2249+
m_Value(V1), m_AllOnes(), m_Value(EVL)))) {
2250+
// Op(rev(V1), rev(V2)) -> rev(Op(V1, V2))
2251+
if (match(RHS, m_Intrinsic<Intrinsic::experimental_vp_reverse>(
2252+
m_Value(V2), m_AllOnes(), m_Specific(EVL))) &&
2253+
(LHS->hasOneUse() || RHS->hasOneUse() ||
2254+
(LHS == RHS && LHS->hasNUses(2))))
2255+
return createBinOpVPReverse(V1, V2, EVL);
2256+
2257+
// Op(rev(V1), RHSSplat)) -> rev(Op(V1, RHSSplat))
2258+
if (LHS->hasOneUse() && isSplatValue(RHS))
2259+
return createBinOpVPReverse(V1, RHS, EVL);
2260+
}
2261+
// Op(LHSSplat, rev(V2)) -> rev(Op(LHSSplat, V2))
2262+
else if (isSplatValue(LHS) &&
2263+
match(RHS, m_Intrinsic<Intrinsic::experimental_vp_reverse>(
2264+
m_Value(V2), m_AllOnes(), m_Value(EVL))))
2265+
return createBinOpVPReverse(LHS, V2, EVL);
2266+
22342267
// It may not be safe to reorder shuffles and things like div, urem, etc.
22352268
// because we may trap when executing those ops on unknown vector elements.
22362269
// See PR20059.

llvm/test/Transforms/InstCombine/vp-reverse.ll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,9 @@ define <vscale x 4 x i32> @binop_reverse_elim_diffmask(<vscale x 4 x i32> %a, <v
4747

4848
define <vscale x 4 x i32> @binop_reverse_elim_diffevl(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, i32 %evl) {
4949
; CHECK-LABEL: @binop_reverse_elim_diffevl(
50-
; CHECK-NEXT: [[A_REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[A:%.*]], <vscale x 4 x i1> splat (i1 true), i32 [[EVL:%.*]])
51-
; CHECK-NEXT: [[B_REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[B:%.*]], <vscale x 4 x i1> splat (i1 true), i32 [[EVL]])
52-
; CHECK-NEXT: [[ADD:%.*]] = add nsw <vscale x 4 x i32> [[A_REV]], [[B_REV]]
53-
; CHECK-NEXT: [[ADD_REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[ADD]], <vscale x 4 x i1> splat (i1 true), i32 10)
50+
; CHECK-NEXT: [[ADD:%.*]] = add nsw <vscale x 4 x i32> [[A_REV:%.*]], [[B_REV:%.*]]
51+
; CHECK-NEXT: [[ADD1:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[ADD]], <vscale x 4 x i1> splat (i1 true), i32 [[EVL:%.*]])
52+
; CHECK-NEXT: [[ADD_REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[ADD1]], <vscale x 4 x i1> splat (i1 true), i32 10)
5453
; CHECK-NEXT: ret <vscale x 4 x i32> [[ADD_REV]]
5554
;
5655
%a.rev = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse(<vscale x 4 x i32> %a, <vscale x 4 x i1> splat (i1 true), i32 %evl)

0 commit comments

Comments
 (0)