Skip to content

Commit 8830525

Browse files
authored
[ConstantFolding] Add constant folding for scalable vector interleave intrinsics. (#168668)
We can constant fold interleave of identical splat vectors to a larger splat vector.
1 parent db1e73e commit 8830525

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4313,6 +4313,22 @@ static Constant *ConstantFoldScalableVectorCall(
43134313
return ConstantVector::getNullValue(SVTy);
43144314
break;
43154315
}
4316+
case Intrinsic::vector_interleave2:
4317+
case Intrinsic::vector_interleave3:
4318+
case Intrinsic::vector_interleave4:
4319+
case Intrinsic::vector_interleave5:
4320+
case Intrinsic::vector_interleave6:
4321+
case Intrinsic::vector_interleave7:
4322+
case Intrinsic::vector_interleave8: {
4323+
Constant *SplatVal = Operands[0]->getSplatValue();
4324+
if (!SplatVal)
4325+
return nullptr;
4326+
4327+
if (!llvm::all_equal(Operands))
4328+
return nullptr;
4329+
4330+
return ConstantVector::getSplat(SVTy->getElementCount(), SplatVal);
4331+
}
43164332
default:
43174333
break;
43184334
}

llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,32 @@ define <8 x i32> @fold_vector_interleave2() {
5151
ret <8 x i32> %1
5252
}
5353

54+
define <vscale x 8 x i32> @fold_scalable_vector_interleave2() {
55+
; CHECK-LABEL: define <vscale x 8 x i32> @fold_scalable_vector_interleave2() {
56+
; CHECK-NEXT: ret <vscale x 8 x i32> zeroinitializer
57+
;
58+
%1 = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
59+
ret <vscale x 8 x i32> %1
60+
}
61+
62+
define <vscale x 8 x i32> @fold_scalable_vector_interleave2_splat() {
63+
; CHECK-LABEL: define <vscale x 8 x i32> @fold_scalable_vector_interleave2_splat() {
64+
; CHECK-NEXT: ret <vscale x 8 x i32> splat (i32 1)
65+
;
66+
%1 = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
67+
ret <vscale x 8 x i32> %1
68+
}
69+
70+
; Negative test.
71+
define <vscale x 8 x i32> @fold_scalable_vector_interleave2_mismatch_splat() {
72+
; CHECK-LABEL: define <vscale x 8 x i32> @fold_scalable_vector_interleave2_mismatch_splat() {
73+
; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 2))
74+
; CHECK-NEXT: ret <vscale x 8 x i32> [[TMP1]]
75+
;
76+
%1 = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 2))
77+
ret <vscale x 8 x i32> %1
78+
}
79+
5480
define <12 x i32> @fold_vector_interleave3() {
5581
; CHECK-LABEL: define <12 x i32> @fold_vector_interleave3() {
5682
; CHECK-NEXT: ret <12 x i32> <i32 1, i32 5, i32 9, i32 2, i32 6, i32 10, i32 3, i32 7, i32 11, i32 4, i32 8, i32 12>
@@ -59,6 +85,22 @@ define <12 x i32> @fold_vector_interleave3() {
5985
ret <12 x i32> %1
6086
}
6187

88+
define <vscale x 12 x i32> @fold_scalable_vector_interleave3() {
89+
; CHECK-LABEL: define <vscale x 12 x i32> @fold_scalable_vector_interleave3() {
90+
; CHECK-NEXT: ret <vscale x 12 x i32> zeroinitializer
91+
;
92+
%1 = call <vscale x 12 x i32> @llvm.vector.interleave3.nxv8i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
93+
ret <vscale x 12 x i32> %1
94+
}
95+
96+
define <vscale x 12 x i32> @fold_scalable_vector_interleave3_splat() {
97+
; CHECK-LABEL: define <vscale x 12 x i32> @fold_scalable_vector_interleave3_splat() {
98+
; CHECK-NEXT: ret <vscale x 12 x i32> splat (i32 1)
99+
;
100+
%1 = call <vscale x 12 x i32> @llvm.vector.interleave3.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
101+
ret <vscale x 12 x i32> %1
102+
}
103+
62104
define <16 x i32> @fold_vector_interleave4() {
63105
; CHECK-LABEL: define <16 x i32> @fold_vector_interleave4() {
64106
; CHECK-NEXT: ret <16 x i32> <i32 1, i32 5, i32 9, i32 13, i32 2, i32 6, i32 10, i32 14, i32 3, i32 7, i32 11, i32 15, i32 4, i32 8, i32 12, i32 16>
@@ -67,6 +109,22 @@ define <16 x i32> @fold_vector_interleave4() {
67109
ret <16 x i32> %1
68110
}
69111

112+
define <vscale x 16 x i32> @fold_scalable_vector_interleave4() {
113+
; CHECK-LABEL: define <vscale x 16 x i32> @fold_scalable_vector_interleave4() {
114+
; CHECK-NEXT: ret <vscale x 16 x i32> zeroinitializer
115+
;
116+
%1 = call <vscale x 16 x i32> @llvm.vector.interleave4.nxv16i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
117+
ret <vscale x 16 x i32> %1
118+
}
119+
120+
define <vscale x 16 x i32> @fold_scalable_vector_interleave4_splat() {
121+
; CHECK-LABEL: define <vscale x 16 x i32> @fold_scalable_vector_interleave4_splat() {
122+
; CHECK-NEXT: ret <vscale x 16 x i32> splat (i32 1)
123+
;
124+
%1 = call <vscale x 16 x i32> @llvm.vector.interleave4.nxv16i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
125+
ret <vscale x 16 x i32> %1
126+
}
127+
70128
define <20 x i32> @fold_vector_interleave5() {
71129
; CHECK-LABEL: define <20 x i32> @fold_vector_interleave5() {
72130
; CHECK-NEXT: ret <20 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 2, i32 6, i32 10, i32 14, i32 18, i32 3, i32 7, i32 11, i32 15, i32 19, i32 4, i32 8, i32 12, i32 16, i32 20>
@@ -75,6 +133,22 @@ define <20 x i32> @fold_vector_interleave5() {
75133
ret <20 x i32> %1
76134
}
77135

136+
define <vscale x 20 x i32> @fold_scalable_vector_interleave5() {
137+
; CHECK-LABEL: define <vscale x 20 x i32> @fold_scalable_vector_interleave5() {
138+
; CHECK-NEXT: ret <vscale x 20 x i32> zeroinitializer
139+
;
140+
%1 = call <vscale x 20 x i32> @llvm.vector.interleave5.nxv20i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
141+
ret <vscale x 20 x i32> %1
142+
}
143+
144+
define <vscale x 20 x i32> @fold_scalable_vector_interleave5_splat() {
145+
; CHECK-LABEL: define <vscale x 20 x i32> @fold_scalable_vector_interleave5_splat() {
146+
; CHECK-NEXT: ret <vscale x 20 x i32> splat (i32 1)
147+
;
148+
%1 = call <vscale x 20 x i32> @llvm.vector.interleave5.nxv20i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
149+
ret <vscale x 20 x i32> %1
150+
}
151+
78152
define <24 x i32> @fold_vector_interleave6() {
79153
; CHECK-LABEL: define <24 x i32> @fold_vector_interleave6() {
80154
; CHECK-NEXT: ret <24 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24>
@@ -83,6 +157,22 @@ define <24 x i32> @fold_vector_interleave6() {
83157
ret <24 x i32> %1
84158
}
85159

160+
define <vscale x 24 x i32> @fold_scalable_vector_interleave6() {
161+
; CHECK-LABEL: define <vscale x 24 x i32> @fold_scalable_vector_interleave6() {
162+
; CHECK-NEXT: ret <vscale x 24 x i32> zeroinitializer
163+
;
164+
%1 = call <vscale x 24 x i32> @llvm.vector.interleave6.nxv24i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
165+
ret <vscale x 24 x i32> %1
166+
}
167+
168+
define <vscale x 24 x i32> @fold_scalable_vector_interleave6_splat() {
169+
; CHECK-LABEL: define <vscale x 24 x i32> @fold_scalable_vector_interleave6_splat() {
170+
; CHECK-NEXT: ret <vscale x 24 x i32> splat (i32 1)
171+
;
172+
%1 = call <vscale x 24 x i32> @llvm.vector.interleave6.nxv24i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
173+
ret <vscale x 24 x i32> %1
174+
}
175+
86176
define <28 x i32> @fold_vector_interleave7() {
87177
; CHECK-LABEL: define <28 x i32> @fold_vector_interleave7() {
88178
; CHECK-NEXT: ret <28 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28>
@@ -91,6 +181,22 @@ define <28 x i32> @fold_vector_interleave7() {
91181
ret <28 x i32> %1
92182
}
93183

184+
define <vscale x 28 x i32> @fold_scalable_vector_interleave7() {
185+
; CHECK-LABEL: define <vscale x 28 x i32> @fold_scalable_vector_interleave7() {
186+
; CHECK-NEXT: ret <vscale x 28 x i32> zeroinitializer
187+
;
188+
%1 = call <vscale x 28 x i32> @llvm.vector.interleave7.nxv28i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
189+
ret <vscale x 28 x i32> %1
190+
}
191+
192+
define <vscale x 28 x i32> @fold_scalable_vector_interleave7_splat() {
193+
; CHECK-LABEL: define <vscale x 28 x i32> @fold_scalable_vector_interleave7_splat() {
194+
; CHECK-NEXT: ret <vscale x 28 x i32> splat (i32 1)
195+
;
196+
%1 = call <vscale x 28 x i32> @llvm.vector.interleave7.nxv28i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
197+
ret <vscale x 28 x i32> %1
198+
}
199+
94200
define <32 x i32> @fold_vector_interleave8() {
95201
; CHECK-LABEL: define <32 x i32> @fold_vector_interleave8() {
96202
; CHECK-NEXT: ret <32 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 29, i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30, i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 31, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 32>
@@ -99,6 +205,22 @@ define <32 x i32> @fold_vector_interleave8() {
99205
ret <32 x i32> %1
100206
}
101207

208+
define <vscale x 32 x i32> @fold_scalable_vector_interleave8() {
209+
; CHECK-LABEL: define <vscale x 32 x i32> @fold_scalable_vector_interleave8() {
210+
; CHECK-NEXT: ret <vscale x 32 x i32> zeroinitializer
211+
;
212+
%1 = call <vscale x 32 x i32> @llvm.vector.interleave8.nxv32i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
213+
ret <vscale x 32 x i32> %1
214+
}
215+
216+
define <vscale x 32 x i32> @fold_scalable_vector_interleave8_splat() {
217+
; CHECK-LABEL: define <vscale x 32 x i32> @fold_scalable_vector_interleave8_splat() {
218+
; CHECK-NEXT: ret <vscale x 32 x i32> splat (i32 1)
219+
;
220+
%1 = call <vscale x 32 x i32> @llvm.vector.interleave8.nxv32i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
221+
ret <vscale x 32 x i32> %1
222+
}
223+
102224
define { <4 x i32>, <4 x i32> } @fold_vector_deinterleave2() {
103225
; CHECK-LABEL: define { <4 x i32>, <4 x i32> } @fold_vector_deinterleave2() {
104226
; CHECK-NEXT: ret { <4 x i32>, <4 x i32> } { <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32> <i32 5, i32 6, i32 7, i32 8> }

0 commit comments

Comments
 (0)