Skip to content

Commit 6f9cd79

Browse files
authored
[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.
1 parent c62a613 commit 6f9cd79

File tree

2 files changed

+23
-13
lines changed

2 files changed

+23
-13
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6969,6 +6969,23 @@ static Value *simplifyIntrinsic(CallBase *Call, Value *Callee,
69696969
}
69706970
return nullptr;
69716971
}
6972+
case Intrinsic::experimental_vp_reverse: {
6973+
Value *Vec = Call->getArgOperand(0);
6974+
Value *Mask = Call->getArgOperand(1);
6975+
Value *EVL = Call->getArgOperand(2);
6976+
6977+
Value *X;
6978+
// vp.reverse(vp.reverse(X)) == X (with all ones mask and matching EVL)
6979+
if (match(Mask, m_AllOnes()) &&
6980+
match(Vec, m_Intrinsic<Intrinsic::experimental_vp_reverse>(
6981+
m_Value(X), m_AllOnes(), m_Specific(EVL))))
6982+
return X;
6983+
6984+
// vp.reverse(splat(X)) -> splat(X) (regardless of mask and EVL)
6985+
if (isSplatValue(Vec))
6986+
return Vec;
6987+
return nullptr;
6988+
}
69726989
default:
69736990
return nullptr;
69746991
}

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

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
define <vscale x 4 x i32> @rev_of_rev(<vscale x 4 x i32> %a, i32 %evl) {
55
; CHECK-LABEL: @rev_of_rev(
6-
; 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:%.*]])
7-
; 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]])
8-
; CHECK-NEXT: ret <vscale x 4 x i32> [[RES]]
6+
; CHECK-NEXT: ret <vscale x 4 x i32> [[A:%.*]]
97
;
108
%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)
119
%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,26 +23,23 @@ define <vscale x 4 x i32> @rev_of_rev_diffevl(<vscale x 4 x i32> %a, i32 %evl) {
2523

2624
define <vscale x 4 x i32> @rev_of_poison(i32 %evl) {
2725
; CHECK-LABEL: @rev_of_poison(
28-
; 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:%.*]])
29-
; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]]
26+
; CHECK-NEXT: ret <vscale x 4 x i32> poison
3027
;
3128
%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)
3229
ret <vscale x 4 x i32> %rev
3330
}
3431

3532
define <vscale x 4 x i32> @rev_of_undef(i32 %evl) {
3633
; CHECK-LABEL: @rev_of_undef(
37-
; 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:%.*]])
38-
; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]]
34+
; CHECK-NEXT: ret <vscale x 4 x i32> undef
3935
;
4036
%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)
4137
ret <vscale x 4 x i32> %rev
4238
}
4339

4440
define <vscale x 4 x i32> @rev_of_zero(i32 %evl) {
4541
; CHECK-LABEL: @rev_of_zero(
46-
; 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:%.*]])
47-
; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]]
42+
; CHECK-NEXT: ret <vscale x 4 x i32> zeroinitializer
4843
;
4944
%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)
5045
ret <vscale x 4 x i32> %rev
@@ -54,8 +49,7 @@ define <vscale x 4 x i32> @rev_of_splat(i32 %a, i32 %evl) {
5449
; CHECK-LABEL: @rev_of_splat(
5550
; CHECK-NEXT: [[A_INS:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[A:%.*]], i32 0
5651
; CHECK-NEXT: [[A_VEC:%.*]] = shufflevector <vscale x 4 x i32> [[A_INS]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
57-
; 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:%.*]])
58-
; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]]
52+
; CHECK-NEXT: ret <vscale x 4 x i32> [[A_VEC]]
5953
;
6054
%a.ins = insertelement <vscale x 4 x i32> poison, i32 %a, i32 0
6155
%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)
6761
; CHECK-LABEL: @rev_of_splat2(
6862
; CHECK-NEXT: [[A_INS:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[A:%.*]], i32 0
6963
; CHECK-NEXT: [[A_VEC:%.*]] = shufflevector <vscale x 4 x i32> [[A_INS]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
70-
; 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:%.*]])
71-
; CHECK-NEXT: ret <vscale x 4 x i32> [[REV]]
64+
; CHECK-NEXT: ret <vscale x 4 x i32> [[A_VEC]]
7265
;
7366
%a.ins = insertelement <vscale x 4 x i32> poison, i32 %a, i32 0
7467
%a.vec = shufflevector <vscale x 4 x i32> %a.ins, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer

0 commit comments

Comments
 (0)