1 ; RUN: opt < %s -instcombine -S | FileCheck %s
3 ; Check that instcombine rewrites multiply by a vector
4 ; of known constant power-of-2 elements with vector shift.
6 define <4 x i8> @Zero_i8(<4 x i8> %InVec) {
8 %mul = mul <4 x i8> %InVec, <i8 0, i8 0, i8 0, i8 0>
12 ; CHECK-LABEL: @Zero_i8(
13 ; CHECK: ret <4 x i8> zeroinitializer
15 define <4 x i8> @Identity_i8(<4 x i8> %InVec) {
17 %mul = mul <4 x i8> %InVec, <i8 1, i8 1, i8 1, i8 1>
21 ; CHECK-LABEL: @Identity_i8(
22 ; CHECK: ret <4 x i8> %InVec
24 define <4 x i8> @AddToSelf_i8(<4 x i8> %InVec) {
26 %mul = mul <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2>
30 ; CHECK-LABEL: @AddToSelf_i8(
31 ; CHECK: shl <4 x i8> %InVec, <i8 1, i8 1, i8 1, i8 1>
34 define <4 x i8> @SplatPow2Test1_i8(<4 x i8> %InVec) {
36 %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 4, i8 4>
40 ; CHECK-LABEL: @SplatPow2Test1_i8(
41 ; CHECK: shl <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2>
44 define <4 x i8> @SplatPow2Test2_i8(<4 x i8> %InVec) {
46 %mul = mul <4 x i8> %InVec, <i8 8, i8 8, i8 8, i8 8>
50 ; CHECK-LABEL: @SplatPow2Test2_i8(
51 ; CHECK: shl <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3>
54 define <4 x i8> @MulTest1_i8(<4 x i8> %InVec) {
56 %mul = mul <4 x i8> %InVec, <i8 1, i8 2, i8 4, i8 8>
60 ; CHECK-LABEL: @MulTest1_i8(
61 ; CHECK: shl <4 x i8> %InVec, <i8 0, i8 1, i8 2, i8 3>
64 define <4 x i8> @MulTest2_i8(<4 x i8> %InVec) {
66 %mul = mul <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3>
70 ; CHECK-LABEL: @MulTest2_i8(
71 ; CHECK: mul <4 x i8> %InVec, <i8 3, i8 3, i8 3, i8 3>
74 define <4 x i8> @MulTest3_i8(<4 x i8> %InVec) {
76 %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 2, i8 2>
80 ; CHECK-LABEL: @MulTest3_i8(
81 ; CHECK: shl <4 x i8> %InVec, <i8 2, i8 2, i8 1, i8 1>
85 define <4 x i8> @MulTest4_i8(<4 x i8> %InVec) {
87 %mul = mul <4 x i8> %InVec, <i8 4, i8 4, i8 0, i8 1>
91 ; CHECK-LABEL: @MulTest4_i8(
92 ; CHECK: mul <4 x i8> %InVec, <i8 4, i8 4, i8 0, i8 1>
95 define <4 x i16> @Zero_i16(<4 x i16> %InVec) {
97 %mul = mul <4 x i16> %InVec, <i16 0, i16 0, i16 0, i16 0>
101 ; CHECK-LABEL: @Zero_i16(
102 ; CHECK: ret <4 x i16> zeroinitializer
104 define <4 x i16> @Identity_i16(<4 x i16> %InVec) {
106 %mul = mul <4 x i16> %InVec, <i16 1, i16 1, i16 1, i16 1>
110 ; CHECK-LABEL: @Identity_i16(
111 ; CHECK: ret <4 x i16> %InVec
113 define <4 x i16> @AddToSelf_i16(<4 x i16> %InVec) {
115 %mul = mul <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2>
119 ; CHECK-LABEL: @AddToSelf_i16(
120 ; CHECK: shl <4 x i16> %InVec, <i16 1, i16 1, i16 1, i16 1>
123 define <4 x i16> @SplatPow2Test1_i16(<4 x i16> %InVec) {
125 %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 4, i16 4>
129 ; CHECK-LABEL: @SplatPow2Test1_i16(
130 ; CHECK: shl <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2>
133 define <4 x i16> @SplatPow2Test2_i16(<4 x i16> %InVec) {
135 %mul = mul <4 x i16> %InVec, <i16 8, i16 8, i16 8, i16 8>
139 ; CHECK-LABEL: @SplatPow2Test2_i16(
140 ; CHECK: shl <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3>
143 define <4 x i16> @MulTest1_i16(<4 x i16> %InVec) {
145 %mul = mul <4 x i16> %InVec, <i16 1, i16 2, i16 4, i16 8>
149 ; CHECK-LABEL: @MulTest1_i16(
150 ; CHECK: shl <4 x i16> %InVec, <i16 0, i16 1, i16 2, i16 3>
153 define <4 x i16> @MulTest2_i16(<4 x i16> %InVec) {
155 %mul = mul <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3>
159 ; CHECK-LABEL: @MulTest2_i16(
160 ; CHECK: mul <4 x i16> %InVec, <i16 3, i16 3, i16 3, i16 3>
163 define <4 x i16> @MulTest3_i16(<4 x i16> %InVec) {
165 %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 2, i16 2>
169 ; CHECK-LABEL: @MulTest3_i16(
170 ; CHECK: shl <4 x i16> %InVec, <i16 2, i16 2, i16 1, i16 1>
173 define <4 x i16> @MulTest4_i16(<4 x i16> %InVec) {
175 %mul = mul <4 x i16> %InVec, <i16 4, i16 4, i16 0, i16 2>
179 ; CHECK-LABEL: @MulTest4_i16(
180 ; CHECK: mul <4 x i16> %InVec, <i16 4, i16 4, i16 0, i16 2>
183 define <4 x i32> @Zero_i32(<4 x i32> %InVec) {
185 %mul = mul <4 x i32> %InVec, <i32 0, i32 0, i32 0, i32 0>
189 ; CHECK-LABEL: @Zero_i32(
190 ; CHECK: ret <4 x i32> zeroinitializer
192 define <4 x i32> @Identity_i32(<4 x i32> %InVec) {
194 %mul = mul <4 x i32> %InVec, <i32 1, i32 1, i32 1, i32 1>
198 ; CHECK-LABEL: @Identity_i32(
199 ; CHECK: ret <4 x i32> %InVec
201 define <4 x i32> @AddToSelf_i32(<4 x i32> %InVec) {
203 %mul = mul <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2>
207 ; CHECK-LABEL: @AddToSelf_i32(
208 ; CHECK: shl <4 x i32> %InVec, <i32 1, i32 1, i32 1, i32 1>
212 define <4 x i32> @SplatPow2Test1_i32(<4 x i32> %InVec) {
214 %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 4, i32 4>
218 ; CHECK-LABEL: @SplatPow2Test1_i32(
219 ; CHECK: shl <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2>
222 define <4 x i32> @SplatPow2Test2_i32(<4 x i32> %InVec) {
224 %mul = mul <4 x i32> %InVec, <i32 8, i32 8, i32 8, i32 8>
228 ; CHECK-LABEL: @SplatPow2Test2_i32(
229 ; CHECK: shl <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3>
232 define <4 x i32> @MulTest1_i32(<4 x i32> %InVec) {
234 %mul = mul <4 x i32> %InVec, <i32 1, i32 2, i32 4, i32 8>
238 ; CHECK-LABEL: @MulTest1_i32(
239 ; CHECK: shl <4 x i32> %InVec, <i32 0, i32 1, i32 2, i32 3>
242 define <4 x i32> @MulTest2_i32(<4 x i32> %InVec) {
244 %mul = mul <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3>
248 ; CHECK-LABEL: @MulTest2_i32(
249 ; CHECK: mul <4 x i32> %InVec, <i32 3, i32 3, i32 3, i32 3>
252 define <4 x i32> @MulTest3_i32(<4 x i32> %InVec) {
254 %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 2, i32 2>
258 ; CHECK-LABEL: @MulTest3_i32(
259 ; CHECK: shl <4 x i32> %InVec, <i32 2, i32 2, i32 1, i32 1>
263 define <4 x i32> @MulTest4_i32(<4 x i32> %InVec) {
265 %mul = mul <4 x i32> %InVec, <i32 4, i32 4, i32 0, i32 1>
269 ; CHECK-LABEL: @MulTest4_i32(
270 ; CHECK: mul <4 x i32> %InVec, <i32 4, i32 4, i32 0, i32 1>
273 define <4 x i64> @Zero_i64(<4 x i64> %InVec) {
275 %mul = mul <4 x i64> %InVec, <i64 0, i64 0, i64 0, i64 0>
279 ; CHECK-LABEL: @Zero_i64(
280 ; CHECK: ret <4 x i64> zeroinitializer
282 define <4 x i64> @Identity_i64(<4 x i64> %InVec) {
284 %mul = mul <4 x i64> %InVec, <i64 1, i64 1, i64 1, i64 1>
288 ; CHECK-LABEL: @Identity_i64(
289 ; CHECK: ret <4 x i64> %InVec
291 define <4 x i64> @AddToSelf_i64(<4 x i64> %InVec) {
293 %mul = mul <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2>
297 ; CHECK-LABEL: @AddToSelf_i64(
298 ; CHECK: shl <4 x i64> %InVec, <i64 1, i64 1, i64 1, i64 1>
301 define <4 x i64> @SplatPow2Test1_i64(<4 x i64> %InVec) {
303 %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 4, i64 4>
307 ; CHECK-LABEL: @SplatPow2Test1_i64(
308 ; CHECK: shl <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2>
311 define <4 x i64> @SplatPow2Test2_i64(<4 x i64> %InVec) {
313 %mul = mul <4 x i64> %InVec, <i64 8, i64 8, i64 8, i64 8>
317 ; CHECK-LABEL: @SplatPow2Test2_i64(
318 ; CHECK: shl <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3>
321 define <4 x i64> @MulTest1_i64(<4 x i64> %InVec) {
323 %mul = mul <4 x i64> %InVec, <i64 1, i64 2, i64 4, i64 8>
327 ; CHECK-LABEL: @MulTest1_i64(
328 ; CHECK: shl <4 x i64> %InVec, <i64 0, i64 1, i64 2, i64 3>
331 define <4 x i64> @MulTest2_i64(<4 x i64> %InVec) {
333 %mul = mul <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3>
337 ; CHECK-LABEL: @MulTest2_i64(
338 ; CHECK: mul <4 x i64> %InVec, <i64 3, i64 3, i64 3, i64 3>
341 define <4 x i64> @MulTest3_i64(<4 x i64> %InVec) {
343 %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 2, i64 2>
347 ; CHECK-LABEL: @MulTest3_i64(
348 ; CHECK: shl <4 x i64> %InVec, <i64 2, i64 2, i64 1, i64 1>
351 define <4 x i64> @MulTest4_i64(<4 x i64> %InVec) {
353 %mul = mul <4 x i64> %InVec, <i64 4, i64 4, i64 0, i64 1>
357 ; CHECK-LABEL: @MulTest4_i64(
358 ; CHECK: mul <4 x i64> %InVec, <i64 4, i64 4, i64 0, i64 1>
361 ; Test also that the following rewriting rule works with vectors
362 ; of integers as well:
363 ; ((X << C1)*C2) == (X * (C2 << C1))
365 define <4 x i8> @ShiftMulTest1(<4 x i8> %InVec) {
367 %shl = shl <4 x i8> %InVec, <i8 2, i8 2, i8 2, i8 2>
368 %mul = mul <4 x i8> %shl, <i8 3, i8 3, i8 3, i8 3>
372 ; CHECK-LABEL: @ShiftMulTest1(
373 ; CHECK: mul <4 x i8> %InVec, <i8 12, i8 12, i8 12, i8 12>
376 define <4 x i16> @ShiftMulTest2(<4 x i16> %InVec) {
378 %shl = shl <4 x i16> %InVec, <i16 2, i16 2, i16 2, i16 2>
379 %mul = mul <4 x i16> %shl, <i16 3, i16 3, i16 3, i16 3>
383 ; CHECK-LABEL: @ShiftMulTest2(
384 ; CHECK: mul <4 x i16> %InVec, <i16 12, i16 12, i16 12, i16 12>
387 define <4 x i32> @ShiftMulTest3(<4 x i32> %InVec) {
389 %shl = shl <4 x i32> %InVec, <i32 2, i32 2, i32 2, i32 2>
390 %mul = mul <4 x i32> %shl, <i32 3, i32 3, i32 3, i32 3>
394 ; CHECK-LABEL: @ShiftMulTest3(
395 ; CHECK: mul <4 x i32> %InVec, <i32 12, i32 12, i32 12, i32 12>
398 define <4 x i64> @ShiftMulTest4(<4 x i64> %InVec) {
400 %shl = shl <4 x i64> %InVec, <i64 2, i64 2, i64 2, i64 2>
401 %mul = mul <4 x i64> %shl, <i64 3, i64 3, i64 3, i64 3>
405 ; CHECK-LABEL: @ShiftMulTest4(
406 ; CHECK: mul <4 x i64> %InVec, <i64 12, i64 12, i64 12, i64 12>