diff options
author | Philip Reames <preames@rivosinc.com> | 2025-06-16 10:07:56 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-16 10:07:56 -0700 |
commit | 6f9cd79fa2f43b8128be3e4386ee182ad5a843cc (patch) | |
tree | 00e550bc83fd8a91ccbba1388195a04bf7cea557 | |
parent | c62a6138d9d02bcc0fb6660bbed78b4e979fc3dc (diff) | |
download | llvm-6f9cd79fa2f43b8128be3e4386ee182ad5a843cc.zip llvm-6f9cd79fa2f43b8128be3e4386ee182ad5a843cc.tar.gz llvm-6f9cd79fa2f43b8128be3e4386ee182ad5a843cc.tar.bz2 |
[InstSimplify] Add basic simplifications for vp.reverse (#144112)
Directly modeled after what we do for vector.reverse, but with
restrictions on EVL and mask added.
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 17 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/vp-reverse.ll | 19 |
2 files changed, 23 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index e397a22..d1ac8d9 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -6969,6 +6969,23 @@ static Value *simplifyIntrinsic(CallBase *Call, Value *Callee, } return nullptr; } + case Intrinsic::experimental_vp_reverse: { + Value *Vec = Call->getArgOperand(0); + Value *Mask = Call->getArgOperand(1); + Value *EVL = Call->getArgOperand(2); + + Value *X; + // vp.reverse(vp.reverse(X)) == X (with all ones mask and matching EVL) + if (match(Mask, m_AllOnes()) && + match(Vec, m_Intrinsic<Intrinsic::experimental_vp_reverse>( + m_Value(X), m_AllOnes(), m_Specific(EVL)))) + return X; + + // vp.reverse(splat(X)) -> splat(X) (regardless of mask and EVL) + if (isSplatValue(Vec)) + return Vec; + return nullptr; + } default: return nullptr; } diff --git a/llvm/test/Transforms/InstSimplify/vp-reverse.ll b/llvm/test/Transforms/InstSimplify/vp-reverse.ll index 3c3bb87..f19a2ac 100644 --- a/llvm/test/Transforms/InstSimplify/vp-reverse.ll +++ b/llvm/test/Transforms/InstSimplify/vp-reverse.ll @@ -3,9 +3,7 @@ define <vscale x 4 x i32> @rev_of_rev(<vscale x 4 x i32> %a, i32 %evl) { ; CHECK-LABEL: @rev_of_rev( -; 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:%.*]]) -; CHECK-NEXT: [[RES:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[A_REV]], <vscale x 4 x i1> splat (i1 true), i32 [[EVL]]) -; CHECK-NEXT: ret <vscale x 4 x i32> [[RES]] +; CHECK-NEXT: ret <vscale x 4 x i32> [[A:%.*]] ; %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) %res = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse(<vscale x 4 x i32> %a.rev, <vscale x 4 x i1> splat (i1 true), i32 %evl) @@ -25,8 +23,7 @@ define <vscale x 4 x i32> @rev_of_rev_diffevl(<vscale x 4 x i32> %a, i32 %evl) { define <vscale x 4 x i32> @rev_of_poison(i32 %evl) { ; CHECK-LABEL: @rev_of_poison( -; CHECK-NEXT: [[REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i1> splat (i1 true), i32 [[EVL:%.*]]) -; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]] +; CHECK-NEXT: ret <vscale x 4 x i32> poison ; %rev = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse(<vscale x 4 x i32> poison, <vscale x 4 x i1> splat (i1 true), i32 %evl) ret <vscale x 4 x i32> %rev @@ -34,8 +31,7 @@ define <vscale x 4 x i32> @rev_of_poison(i32 %evl) { define <vscale x 4 x i32> @rev_of_undef(i32 %evl) { ; CHECK-LABEL: @rev_of_undef( -; CHECK-NEXT: [[REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i1> splat (i1 true), i32 [[EVL:%.*]]) -; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]] +; CHECK-NEXT: ret <vscale x 4 x i32> undef ; %rev = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse(<vscale x 4 x i32> undef, <vscale x 4 x i1> splat (i1 true), i32 %evl) ret <vscale x 4 x i32> %rev @@ -43,8 +39,7 @@ define <vscale x 4 x i32> @rev_of_undef(i32 %evl) { define <vscale x 4 x i32> @rev_of_zero(i32 %evl) { ; CHECK-LABEL: @rev_of_zero( -; CHECK-NEXT: [[REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i1> splat (i1 true), i32 [[EVL:%.*]]) -; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]] +; CHECK-NEXT: ret <vscale x 4 x i32> zeroinitializer ; %rev = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i1> splat (i1 true), i32 %evl) ret <vscale x 4 x i32> %rev @@ -54,8 +49,7 @@ define <vscale x 4 x i32> @rev_of_splat(i32 %a, i32 %evl) { ; CHECK-LABEL: @rev_of_splat( ; CHECK-NEXT: [[A_INS:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[A:%.*]], i32 0 ; CHECK-NEXT: [[A_VEC:%.*]] = shufflevector <vscale x 4 x i32> [[A_INS]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer -; CHECK-NEXT: [[REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[A_VEC]], <vscale x 4 x i1> splat (i1 true), i32 [[EVL:%.*]]) -; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]] +; CHECK-NEXT: ret <vscale x 4 x i32> [[A_VEC]] ; %a.ins = insertelement <vscale x 4 x i32> poison, i32 %a, i32 0 %a.vec = shufflevector <vscale x 4 x i32> %a.ins, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer @@ -67,8 +61,7 @@ define <vscale x 4 x i32> @rev_of_splat2(i32 %a, <vscale x 4 x i1> %m, i32 %evl) ; CHECK-LABEL: @rev_of_splat2( ; CHECK-NEXT: [[A_INS:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[A:%.*]], i32 0 ; CHECK-NEXT: [[A_VEC:%.*]] = shufflevector <vscale x 4 x i32> [[A_INS]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer -; CHECK-NEXT: [[REV:%.*]] = tail call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[A_VEC]], <vscale x 4 x i1> [[M:%.*]], i32 [[EVL:%.*]]) -; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]] +; CHECK-NEXT: ret <vscale x 4 x i32> [[A_VEC]] ; %a.ins = insertelement <vscale x 4 x i32> poison, i32 %a, i32 0 %a.vec = shufflevector <vscale x 4 x i32> %a.ins, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |