1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve -verify-machineinstrs %s -o - | FileCheck %s
3
4declare {i32, i32} @llvm.arm.mve.asrl(i32, i32, i32)
5declare {i32, i32} @llvm.arm.mve.lsll(i32, i32, i32)
6
7define i64 @asrl_0(i64 %X) {
8; CHECK-LABEL: asrl_0:
9; CHECK:       @ %bb.0: @ %entry
10; CHECK-NEXT:    bx lr
11entry:
12  %0 = lshr i64 %X, 32
13  %1 = trunc i64 %0 to i32
14  %2 = trunc i64 %X to i32
15  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 0)
16  %4 = extractvalue { i32, i32 } %3, 1
17  %5 = zext i32 %4 to i64
18  %6 = shl nuw i64 %5, 32
19  %7 = extractvalue { i32, i32 } %3, 0
20  %8 = zext i32 %7 to i64
21  %9 = or i64 %6, %8
22  ret i64 %9
23}
24
25define i64 @asrl_23(i64 %X) {
26; CHECK-LABEL: asrl_23:
27; CHECK:       @ %bb.0: @ %entry
28; CHECK-NEXT:    asrl r0, r1, #23
29; CHECK-NEXT:    bx lr
30entry:
31  %0 = lshr i64 %X, 32
32  %1 = trunc i64 %0 to i32
33  %2 = trunc i64 %X to i32
34  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 23)
35  %4 = extractvalue { i32, i32 } %3, 1
36  %5 = zext i32 %4 to i64
37  %6 = shl nuw i64 %5, 32
38  %7 = extractvalue { i32, i32 } %3, 0
39  %8 = zext i32 %7 to i64
40  %9 = or i64 %6, %8
41  ret i64 %9
42}
43
44define i64 @asrl_32(i64 %X) {
45; CHECK-LABEL: asrl_32:
46; CHECK:       @ %bb.0: @ %entry
47; CHECK-NEXT:    asrl r0, r1, #32
48; CHECK-NEXT:    bx lr
49entry:
50  %0 = lshr i64 %X, 32
51  %1 = trunc i64 %0 to i32
52  %2 = trunc i64 %X to i32
53  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 32)
54  %4 = extractvalue { i32, i32 } %3, 1
55  %5 = zext i32 %4 to i64
56  %6 = shl nuw i64 %5, 32
57  %7 = extractvalue { i32, i32 } %3, 0
58  %8 = zext i32 %7 to i64
59  %9 = or i64 %6, %8
60  ret i64 %9
61}
62
63define i64 @asrl_33(i64 %X) {
64; CHECK-LABEL: asrl_33:
65; CHECK:       @ %bb.0: @ %entry
66; CHECK-NEXT:    movs r2, #33
67; CHECK-NEXT:    asrl r0, r1, r2
68; CHECK-NEXT:    bx lr
69entry:
70  %0 = lshr i64 %X, 32
71  %1 = trunc i64 %0 to i32
72  %2 = trunc i64 %X to i32
73  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 33)
74  %4 = extractvalue { i32, i32 } %3, 1
75  %5 = zext i32 %4 to i64
76  %6 = shl nuw i64 %5, 32
77  %7 = extractvalue { i32, i32 } %3, 0
78  %8 = zext i32 %7 to i64
79  %9 = or i64 %6, %8
80  ret i64 %9
81}
82
83define i64 @asrl_63(i64 %X) {
84; CHECK-LABEL: asrl_63:
85; CHECK:       @ %bb.0: @ %entry
86; CHECK-NEXT:    movs r2, #63
87; CHECK-NEXT:    asrl r0, r1, r2
88; CHECK-NEXT:    bx lr
89entry:
90  %0 = lshr i64 %X, 32
91  %1 = trunc i64 %0 to i32
92  %2 = trunc i64 %X to i32
93  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 63)
94  %4 = extractvalue { i32, i32 } %3, 1
95  %5 = zext i32 %4 to i64
96  %6 = shl nuw i64 %5, 32
97  %7 = extractvalue { i32, i32 } %3, 0
98  %8 = zext i32 %7 to i64
99  %9 = or i64 %6, %8
100  ret i64 %9
101}
102
103define i64 @asrl_64(i64 %X) {
104; CHECK-LABEL: asrl_64:
105; CHECK:       @ %bb.0: @ %entry
106; CHECK-NEXT:    movs r2, #64
107; CHECK-NEXT:    asrl r0, r1, r2
108; CHECK-NEXT:    bx lr
109entry:
110  %0 = lshr i64 %X, 32
111  %1 = trunc i64 %0 to i32
112  %2 = trunc i64 %X to i32
113  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 64)
114  %4 = extractvalue { i32, i32 } %3, 1
115  %5 = zext i32 %4 to i64
116  %6 = shl nuw i64 %5, 32
117  %7 = extractvalue { i32, i32 } %3, 0
118  %8 = zext i32 %7 to i64
119  %9 = or i64 %6, %8
120  ret i64 %9
121}
122
123define i64 @asrl_m2(i64 %X) {
124; CHECK-LABEL: asrl_m2:
125; CHECK:       @ %bb.0: @ %entry
126; CHECK-NEXT:    lsll r0, r1, #2
127; CHECK-NEXT:    bx lr
128entry:
129  %0 = lshr i64 %X, 32
130  %1 = trunc i64 %0 to i32
131  %2 = trunc i64 %X to i32
132  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -2)
133  %4 = extractvalue { i32, i32 } %3, 1
134  %5 = zext i32 %4 to i64
135  %6 = shl nuw i64 %5, 32
136  %7 = extractvalue { i32, i32 } %3, 0
137  %8 = zext i32 %7 to i64
138  %9 = or i64 %6, %8
139  ret i64 %9
140}
141
142define i64 @asrl_m32(i64 %X) {
143; CHECK-LABEL: asrl_m32:
144; CHECK:       @ %bb.0: @ %entry
145; CHECK-NEXT:    lsll r0, r1, #32
146; CHECK-NEXT:    bx lr
147entry:
148  %0 = lshr i64 %X, 32
149  %1 = trunc i64 %0 to i32
150  %2 = trunc i64 %X to i32
151  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -32)
152  %4 = extractvalue { i32, i32 } %3, 1
153  %5 = zext i32 %4 to i64
154  %6 = shl nuw i64 %5, 32
155  %7 = extractvalue { i32, i32 } %3, 0
156  %8 = zext i32 %7 to i64
157  %9 = or i64 %6, %8
158  ret i64 %9
159}
160
161define i64 @asrl_m33(i64 %X) {
162; CHECK-LABEL: asrl_m33:
163; CHECK:       @ %bb.0: @ %entry
164; CHECK-NEXT:    mvn r2, #32
165; CHECK-NEXT:    asrl r0, r1, r2
166; CHECK-NEXT:    bx lr
167entry:
168  %0 = lshr i64 %X, 32
169  %1 = trunc i64 %0 to i32
170  %2 = trunc i64 %X to i32
171  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -33)
172  %4 = extractvalue { i32, i32 } %3, 1
173  %5 = zext i32 %4 to i64
174  %6 = shl nuw i64 %5, 32
175  %7 = extractvalue { i32, i32 } %3, 0
176  %8 = zext i32 %7 to i64
177  %9 = or i64 %6, %8
178  ret i64 %9
179}
180
181define i64 @asrl_m64(i64 %X) {
182; CHECK-LABEL: asrl_m64:
183; CHECK:       @ %bb.0: @ %entry
184; CHECK-NEXT:    mvn r2, #63
185; CHECK-NEXT:    asrl r0, r1, r2
186; CHECK-NEXT:    bx lr
187entry:
188  %0 = lshr i64 %X, 32
189  %1 = trunc i64 %0 to i32
190  %2 = trunc i64 %X to i32
191  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -64)
192  %4 = extractvalue { i32, i32 } %3, 1
193  %5 = zext i32 %4 to i64
194  %6 = shl nuw i64 %5, 32
195  %7 = extractvalue { i32, i32 } %3, 0
196  %8 = zext i32 %7 to i64
197  %9 = or i64 %6, %8
198  ret i64 %9
199}
200
201
202
203
204define i64 @lsll_0(i64 %X) {
205; CHECK-LABEL: lsll_0:
206; CHECK:       @ %bb.0: @ %entry
207; CHECK-NEXT:    bx lr
208entry:
209  %0 = lshr i64 %X, 32
210  %1 = trunc i64 %0 to i32
211  %2 = trunc i64 %X to i32
212  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 0)
213  %4 = extractvalue { i32, i32 } %3, 1
214  %5 = zext i32 %4 to i64
215  %6 = shl nuw i64 %5, 32
216  %7 = extractvalue { i32, i32 } %3, 0
217  %8 = zext i32 %7 to i64
218  %9 = or i64 %6, %8
219  ret i64 %9
220}
221
222define i64 @lsll_23(i64 %X) {
223; CHECK-LABEL: lsll_23:
224; CHECK:       @ %bb.0: @ %entry
225; CHECK-NEXT:    lsll r0, r1, #23
226; CHECK-NEXT:    bx lr
227entry:
228  %0 = lshr i64 %X, 32
229  %1 = trunc i64 %0 to i32
230  %2 = trunc i64 %X to i32
231  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 23)
232  %4 = extractvalue { i32, i32 } %3, 1
233  %5 = zext i32 %4 to i64
234  %6 = shl nuw i64 %5, 32
235  %7 = extractvalue { i32, i32 } %3, 0
236  %8 = zext i32 %7 to i64
237  %9 = or i64 %6, %8
238  ret i64 %9
239}
240
241define i64 @lsll_32(i64 %X) {
242; CHECK-LABEL: lsll_32:
243; CHECK:       @ %bb.0: @ %entry
244; CHECK-NEXT:    lsll r0, r1, #32
245; CHECK-NEXT:    bx lr
246entry:
247  %0 = lshr i64 %X, 32
248  %1 = trunc i64 %0 to i32
249  %2 = trunc i64 %X to i32
250  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 32)
251  %4 = extractvalue { i32, i32 } %3, 1
252  %5 = zext i32 %4 to i64
253  %6 = shl nuw i64 %5, 32
254  %7 = extractvalue { i32, i32 } %3, 0
255  %8 = zext i32 %7 to i64
256  %9 = or i64 %6, %8
257  ret i64 %9
258}
259
260define i64 @lsll_33(i64 %X) {
261; CHECK-LABEL: lsll_33:
262; CHECK:       @ %bb.0: @ %entry
263; CHECK-NEXT:    movs r2, #33
264; CHECK-NEXT:    lsll r0, r1, r2
265; CHECK-NEXT:    bx lr
266entry:
267  %0 = lshr i64 %X, 32
268  %1 = trunc i64 %0 to i32
269  %2 = trunc i64 %X to i32
270  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 33)
271  %4 = extractvalue { i32, i32 } %3, 1
272  %5 = zext i32 %4 to i64
273  %6 = shl nuw i64 %5, 32
274  %7 = extractvalue { i32, i32 } %3, 0
275  %8 = zext i32 %7 to i64
276  %9 = or i64 %6, %8
277  ret i64 %9
278}
279
280define i64 @lsll_63(i64 %X) {
281; CHECK-LABEL: lsll_63:
282; CHECK:       @ %bb.0: @ %entry
283; CHECK-NEXT:    movs r2, #63
284; CHECK-NEXT:    lsll r0, r1, r2
285; CHECK-NEXT:    bx lr
286entry:
287  %0 = lshr i64 %X, 32
288  %1 = trunc i64 %0 to i32
289  %2 = trunc i64 %X to i32
290  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 63)
291  %4 = extractvalue { i32, i32 } %3, 1
292  %5 = zext i32 %4 to i64
293  %6 = shl nuw i64 %5, 32
294  %7 = extractvalue { i32, i32 } %3, 0
295  %8 = zext i32 %7 to i64
296  %9 = or i64 %6, %8
297  ret i64 %9
298}
299
300define i64 @lsll_64(i64 %X) {
301; CHECK-LABEL: lsll_64:
302; CHECK:       @ %bb.0: @ %entry
303; CHECK-NEXT:    movs r2, #64
304; CHECK-NEXT:    lsll r0, r1, r2
305; CHECK-NEXT:    bx lr
306entry:
307  %0 = lshr i64 %X, 32
308  %1 = trunc i64 %0 to i32
309  %2 = trunc i64 %X to i32
310  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 64)
311  %4 = extractvalue { i32, i32 } %3, 1
312  %5 = zext i32 %4 to i64
313  %6 = shl nuw i64 %5, 32
314  %7 = extractvalue { i32, i32 } %3, 0
315  %8 = zext i32 %7 to i64
316  %9 = or i64 %6, %8
317  ret i64 %9
318}
319
320define i64 @lsll_m2(i64 %X) {
321; CHECK-LABEL: lsll_m2:
322; CHECK:       @ %bb.0: @ %entry
323; CHECK-NEXT:    lsrl r0, r1, #2
324; CHECK-NEXT:    bx lr
325entry:
326  %0 = lshr i64 %X, 32
327  %1 = trunc i64 %0 to i32
328  %2 = trunc i64 %X to i32
329  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -2)
330  %4 = extractvalue { i32, i32 } %3, 1
331  %5 = zext i32 %4 to i64
332  %6 = shl nuw i64 %5, 32
333  %7 = extractvalue { i32, i32 } %3, 0
334  %8 = zext i32 %7 to i64
335  %9 = or i64 %6, %8
336  ret i64 %9
337}
338
339define i64 @lsll_m32(i64 %X) {
340; CHECK-LABEL: lsll_m32:
341; CHECK:       @ %bb.0: @ %entry
342; CHECK-NEXT:    lsrl r0, r1, #32
343; CHECK-NEXT:    bx lr
344entry:
345  %0 = lshr i64 %X, 32
346  %1 = trunc i64 %0 to i32
347  %2 = trunc i64 %X to i32
348  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -32)
349  %4 = extractvalue { i32, i32 } %3, 1
350  %5 = zext i32 %4 to i64
351  %6 = shl nuw i64 %5, 32
352  %7 = extractvalue { i32, i32 } %3, 0
353  %8 = zext i32 %7 to i64
354  %9 = or i64 %6, %8
355  ret i64 %9
356}
357
358define i64 @lsll_m33(i64 %X) {
359; CHECK-LABEL: lsll_m33:
360; CHECK:       @ %bb.0: @ %entry
361; CHECK-NEXT:    mvn r2, #32
362; CHECK-NEXT:    lsll r0, r1, r2
363; CHECK-NEXT:    bx lr
364entry:
365  %0 = lshr i64 %X, 32
366  %1 = trunc i64 %0 to i32
367  %2 = trunc i64 %X to i32
368  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -33)
369  %4 = extractvalue { i32, i32 } %3, 1
370  %5 = zext i32 %4 to i64
371  %6 = shl nuw i64 %5, 32
372  %7 = extractvalue { i32, i32 } %3, 0
373  %8 = zext i32 %7 to i64
374  %9 = or i64 %6, %8
375  ret i64 %9
376}
377
378define i64 @lsll_m64(i64 %X) {
379; CHECK-LABEL: lsll_m64:
380; CHECK:       @ %bb.0: @ %entry
381; CHECK-NEXT:    mvn r2, #63
382; CHECK-NEXT:    lsll r0, r1, r2
383; CHECK-NEXT:    bx lr
384entry:
385  %0 = lshr i64 %X, 32
386  %1 = trunc i64 %0 to i32
387  %2 = trunc i64 %X to i32
388  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -64)
389  %4 = extractvalue { i32, i32 } %3, 1
390  %5 = zext i32 %4 to i64
391  %6 = shl nuw i64 %5, 32
392  %7 = extractvalue { i32, i32 } %3, 0
393  %8 = zext i32 %7 to i64
394  %9 = or i64 %6, %8
395  ret i64 %9
396}
397