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 i32 @ashr_demand_bottom3(i64 %X) {
8; CHECK-LABEL: ashr_demand_bottom3:
9; CHECK:       @ %bb.0: @ %entry
10; CHECK-NEXT:    asrl r0, r1, #3
11; CHECK-NEXT:    bx lr
12entry:
13  %0 = lshr i64 %X, 32
14  %1 = trunc i64 %0 to i32
15  %2 = trunc i64 %X to i32
16  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 3)
17  %4 = extractvalue { i32, i32 } %3, 1
18  %5 = zext i32 %4 to i64
19  %6 = shl nuw i64 %5, 32
20  %7 = extractvalue { i32, i32 } %3, 0
21  %8 = zext i32 %7 to i64
22  %shr = or i64 %6, %8
23  %t = trunc i64 %shr to i32
24  ret i32 %t
25}
26
27define i32 @lsll_demand_bottom3(i64 %X) {
28; CHECK-LABEL: lsll_demand_bottom3:
29; CHECK:       @ %bb.0: @ %entry
30; CHECK-NEXT:    lsll r0, r1, #3
31; CHECK-NEXT:    bx lr
32entry:
33  %0 = lshr i64 %X, 32
34  %1 = trunc i64 %0 to i32
35  %2 = trunc i64 %X to i32
36  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 3)
37  %4 = extractvalue { i32, i32 } %3, 1
38  %5 = zext i32 %4 to i64
39  %6 = shl nuw i64 %5, 32
40  %7 = extractvalue { i32, i32 } %3, 0
41  %8 = zext i32 %7 to i64
42  %shr = or i64 %6, %8
43  %t = trunc i64 %shr to i32
44  ret i32 %t
45}
46
47define i32 @ashr_demand_bottomm3(i64 %X) {
48; CHECK-LABEL: ashr_demand_bottomm3:
49; CHECK:       @ %bb.0: @ %entry
50; CHECK-NEXT:    lsll r0, r1, #3
51; CHECK-NEXT:    bx lr
52entry:
53  %0 = lshr i64 %X, 32
54  %1 = trunc i64 %0 to i32
55  %2 = trunc i64 %X to i32
56  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -3)
57  %4 = extractvalue { i32, i32 } %3, 1
58  %5 = zext i32 %4 to i64
59  %6 = shl nuw i64 %5, 32
60  %7 = extractvalue { i32, i32 } %3, 0
61  %8 = zext i32 %7 to i64
62  %shr = or i64 %6, %8
63  %t = trunc i64 %shr to i32
64  ret i32 %t
65}
66
67define i32 @lsll_demand_bottomm3(i64 %X) {
68; CHECK-LABEL: lsll_demand_bottomm3:
69; CHECK:       @ %bb.0: @ %entry
70; CHECK-NEXT:    lsrl r0, r1, #3
71; CHECK-NEXT:    bx lr
72entry:
73  %0 = lshr i64 %X, 32
74  %1 = trunc i64 %0 to i32
75  %2 = trunc i64 %X to i32
76  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -3)
77  %4 = extractvalue { i32, i32 } %3, 1
78  %5 = zext i32 %4 to i64
79  %6 = shl nuw i64 %5, 32
80  %7 = extractvalue { i32, i32 } %3, 0
81  %8 = zext i32 %7 to i64
82  %shr = or i64 %6, %8
83  %t = trunc i64 %shr to i32
84  ret i32 %t
85}
86
87
88define i32 @ashr_demand_bottom31(i64 %X) {
89; CHECK-LABEL: ashr_demand_bottom31:
90; CHECK:       @ %bb.0: @ %entry
91; CHECK-NEXT:    asrl r0, r1, #31
92; CHECK-NEXT:    bx lr
93entry:
94  %0 = lshr i64 %X, 32
95  %1 = trunc i64 %0 to i32
96  %2 = trunc i64 %X to i32
97  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 31)
98  %4 = extractvalue { i32, i32 } %3, 1
99  %5 = zext i32 %4 to i64
100  %6 = shl nuw i64 %5, 32
101  %7 = extractvalue { i32, i32 } %3, 0
102  %8 = zext i32 %7 to i64
103  %shr = or i64 %6, %8
104  %t = trunc i64 %shr to i32
105  ret i32 %t
106}
107
108define i32 @lsll_demand_bottom31(i64 %X) {
109; CHECK-LABEL: lsll_demand_bottom31:
110; CHECK:       @ %bb.0: @ %entry
111; CHECK-NEXT:    lsll r0, r1, #31
112; CHECK-NEXT:    bx lr
113entry:
114  %0 = lshr i64 %X, 32
115  %1 = trunc i64 %0 to i32
116  %2 = trunc i64 %X to i32
117  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 31)
118  %4 = extractvalue { i32, i32 } %3, 1
119  %5 = zext i32 %4 to i64
120  %6 = shl nuw i64 %5, 32
121  %7 = extractvalue { i32, i32 } %3, 0
122  %8 = zext i32 %7 to i64
123  %shr = or i64 %6, %8
124  %t = trunc i64 %shr to i32
125  ret i32 %t
126}
127
128define i32 @ashr_demand_bottomm31(i64 %X) {
129; CHECK-LABEL: ashr_demand_bottomm31:
130; CHECK:       @ %bb.0: @ %entry
131; CHECK-NEXT:    lsll r0, r1, #31
132; CHECK-NEXT:    bx lr
133entry:
134  %0 = lshr i64 %X, 32
135  %1 = trunc i64 %0 to i32
136  %2 = trunc i64 %X to i32
137  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -31)
138  %4 = extractvalue { i32, i32 } %3, 1
139  %5 = zext i32 %4 to i64
140  %6 = shl nuw i64 %5, 32
141  %7 = extractvalue { i32, i32 } %3, 0
142  %8 = zext i32 %7 to i64
143  %shr = or i64 %6, %8
144  %t = trunc i64 %shr to i32
145  ret i32 %t
146}
147
148define i32 @lsll_demand_bottomm31(i64 %X) {
149; CHECK-LABEL: lsll_demand_bottomm31:
150; CHECK:       @ %bb.0: @ %entry
151; CHECK-NEXT:    lsrl r0, r1, #31
152; CHECK-NEXT:    bx lr
153entry:
154  %0 = lshr i64 %X, 32
155  %1 = trunc i64 %0 to i32
156  %2 = trunc i64 %X to i32
157  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -31)
158  %4 = extractvalue { i32, i32 } %3, 1
159  %5 = zext i32 %4 to i64
160  %6 = shl nuw i64 %5, 32
161  %7 = extractvalue { i32, i32 } %3, 0
162  %8 = zext i32 %7 to i64
163  %shr = or i64 %6, %8
164  %t = trunc i64 %shr to i32
165  ret i32 %t
166}
167
168
169define i32 @ashr_demand_bottom32(i64 %X) {
170; CHECK-LABEL: ashr_demand_bottom32:
171; CHECK:       @ %bb.0: @ %entry
172; CHECK-NEXT:    asrl r0, r1, #32
173; CHECK-NEXT:    bx lr
174entry:
175  %0 = lshr i64 %X, 32
176  %1 = trunc i64 %0 to i32
177  %2 = trunc i64 %X to i32
178  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 32)
179  %4 = extractvalue { i32, i32 } %3, 1
180  %5 = zext i32 %4 to i64
181  %6 = shl nuw i64 %5, 32
182  %7 = extractvalue { i32, i32 } %3, 0
183  %8 = zext i32 %7 to i64
184  %shr = or i64 %6, %8
185  %t = trunc i64 %shr to i32
186  ret i32 %t
187}
188
189define i32 @lsll_demand_bottom32(i64 %X) {
190; CHECK-LABEL: lsll_demand_bottom32:
191; CHECK:       @ %bb.0: @ %entry
192; CHECK-NEXT:    lsll r0, r1, #32
193; CHECK-NEXT:    bx lr
194entry:
195  %0 = lshr i64 %X, 32
196  %1 = trunc i64 %0 to i32
197  %2 = trunc i64 %X to i32
198  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 32)
199  %4 = extractvalue { i32, i32 } %3, 1
200  %5 = zext i32 %4 to i64
201  %6 = shl nuw i64 %5, 32
202  %7 = extractvalue { i32, i32 } %3, 0
203  %8 = zext i32 %7 to i64
204  %shr = or i64 %6, %8
205  %t = trunc i64 %shr to i32
206  ret i32 %t
207}
208
209define i32 @ashr_demand_bottomm32(i64 %X) {
210; CHECK-LABEL: ashr_demand_bottomm32:
211; CHECK:       @ %bb.0: @ %entry
212; CHECK-NEXT:    lsll r0, r1, #32
213; CHECK-NEXT:    bx lr
214entry:
215  %0 = lshr i64 %X, 32
216  %1 = trunc i64 %0 to i32
217  %2 = trunc i64 %X to i32
218  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -32)
219  %4 = extractvalue { i32, i32 } %3, 1
220  %5 = zext i32 %4 to i64
221  %6 = shl nuw i64 %5, 32
222  %7 = extractvalue { i32, i32 } %3, 0
223  %8 = zext i32 %7 to i64
224  %shr = or i64 %6, %8
225  %t = trunc i64 %shr to i32
226  ret i32 %t
227}
228
229define i32 @lsll_demand_bottomm32(i64 %X) {
230; CHECK-LABEL: lsll_demand_bottomm32:
231; CHECK:       @ %bb.0: @ %entry
232; CHECK-NEXT:    lsrl r0, r1, #32
233; CHECK-NEXT:    bx lr
234entry:
235  %0 = lshr i64 %X, 32
236  %1 = trunc i64 %0 to i32
237  %2 = trunc i64 %X to i32
238  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -32)
239  %4 = extractvalue { i32, i32 } %3, 1
240  %5 = zext i32 %4 to i64
241  %6 = shl nuw i64 %5, 32
242  %7 = extractvalue { i32, i32 } %3, 0
243  %8 = zext i32 %7 to i64
244  %shr = or i64 %6, %8
245  %t = trunc i64 %shr to i32
246  ret i32 %t
247}
248
249
250define i32 @ashr_demand_bottom44(i64 %X) {
251; CHECK-LABEL: ashr_demand_bottom44:
252; CHECK:       @ %bb.0: @ %entry
253; CHECK-NEXT:    movs r2, #44
254; CHECK-NEXT:    asrl r0, r1, r2
255; CHECK-NEXT:    bx lr
256entry:
257  %0 = lshr i64 %X, 32
258  %1 = trunc i64 %0 to i32
259  %2 = trunc i64 %X to i32
260  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 44)
261  %4 = extractvalue { i32, i32 } %3, 1
262  %5 = zext i32 %4 to i64
263  %6 = shl nuw i64 %5, 32
264  %7 = extractvalue { i32, i32 } %3, 0
265  %8 = zext i32 %7 to i64
266  %shr = or i64 %6, %8
267  %t = trunc i64 %shr to i32
268  ret i32 %t
269}
270
271define i32 @lsll_demand_bottom44(i64 %X) {
272; CHECK-LABEL: lsll_demand_bottom44:
273; CHECK:       @ %bb.0: @ %entry
274; CHECK-NEXT:    movs r2, #44
275; CHECK-NEXT:    lsll r0, r1, r2
276; CHECK-NEXT:    bx lr
277entry:
278  %0 = lshr i64 %X, 32
279  %1 = trunc i64 %0 to i32
280  %2 = trunc i64 %X to i32
281  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 44)
282  %4 = extractvalue { i32, i32 } %3, 1
283  %5 = zext i32 %4 to i64
284  %6 = shl nuw i64 %5, 32
285  %7 = extractvalue { i32, i32 } %3, 0
286  %8 = zext i32 %7 to i64
287  %shr = or i64 %6, %8
288  %t = trunc i64 %shr to i32
289  ret i32 %t
290}
291
292define i32 @ashr_demand_bottomm44(i64 %X) {
293; CHECK-LABEL: ashr_demand_bottomm44:
294; CHECK:       @ %bb.0: @ %entry
295; CHECK-NEXT:    mvn r2, #43
296; CHECK-NEXT:    asrl r0, r1, r2
297; CHECK-NEXT:    bx lr
298entry:
299  %0 = lshr i64 %X, 32
300  %1 = trunc i64 %0 to i32
301  %2 = trunc i64 %X to i32
302  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -44)
303  %4 = extractvalue { i32, i32 } %3, 1
304  %5 = zext i32 %4 to i64
305  %6 = shl nuw i64 %5, 32
306  %7 = extractvalue { i32, i32 } %3, 0
307  %8 = zext i32 %7 to i64
308  %shr = or i64 %6, %8
309  %t = trunc i64 %shr to i32
310  ret i32 %t
311}
312
313define i32 @lsll_demand_bottomm44(i64 %X) {
314; CHECK-LABEL: lsll_demand_bottomm44:
315; CHECK:       @ %bb.0: @ %entry
316; CHECK-NEXT:    mvn r2, #43
317; CHECK-NEXT:    lsll r0, r1, r2
318; CHECK-NEXT:    bx lr
319entry:
320  %0 = lshr i64 %X, 32
321  %1 = trunc i64 %0 to i32
322  %2 = trunc i64 %X to i32
323  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -44)
324  %4 = extractvalue { i32, i32 } %3, 1
325  %5 = zext i32 %4 to i64
326  %6 = shl nuw i64 %5, 32
327  %7 = extractvalue { i32, i32 } %3, 0
328  %8 = zext i32 %7 to i64
329  %shr = or i64 %6, %8
330  %t = trunc i64 %shr to i32
331  ret i32 %t
332}
333
334
335
336
337
338
339
340define i32 @ashr_demand_top3(i64 %X) {
341; CHECK-LABEL: ashr_demand_top3:
342; CHECK:       @ %bb.0: @ %entry
343; CHECK-NEXT:    asrl r0, r1, #3
344; CHECK-NEXT:    mov r0, r1
345; CHECK-NEXT:    bx lr
346entry:
347  %0 = lshr i64 %X, 32
348  %1 = trunc i64 %0 to i32
349  %2 = trunc i64 %X to i32
350  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 3)
351  %4 = extractvalue { i32, i32 } %3, 1
352  %5 = zext i32 %4 to i64
353  %6 = shl nuw i64 %5, 32
354  %7 = extractvalue { i32, i32 } %3, 0
355  %8 = zext i32 %7 to i64
356  %shr = or i64 %6, %8
357  %sm = lshr i64 %shr, 32
358  %t = trunc i64 %sm to i32
359  ret i32 %t
360}
361
362define i32 @lsll_demand_top3(i64 %X) {
363; CHECK-LABEL: lsll_demand_top3:
364; CHECK:       @ %bb.0: @ %entry
365; CHECK-NEXT:    lsll r0, r1, #3
366; CHECK-NEXT:    mov r0, r1
367; CHECK-NEXT:    bx lr
368entry:
369  %0 = lshr i64 %X, 32
370  %1 = trunc i64 %0 to i32
371  %2 = trunc i64 %X to i32
372  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 3)
373  %4 = extractvalue { i32, i32 } %3, 1
374  %5 = zext i32 %4 to i64
375  %6 = shl nuw i64 %5, 32
376  %7 = extractvalue { i32, i32 } %3, 0
377  %8 = zext i32 %7 to i64
378  %shr = or i64 %6, %8
379  %sm = lshr i64 %shr, 32
380  %t = trunc i64 %sm to i32
381  ret i32 %t
382}
383
384define i32 @ashr_demand_topm3(i64 %X) {
385; CHECK-LABEL: ashr_demand_topm3:
386; CHECK:       @ %bb.0: @ %entry
387; CHECK-NEXT:    lsll r0, r1, #3
388; CHECK-NEXT:    mov r0, r1
389; CHECK-NEXT:    bx lr
390entry:
391  %0 = lshr i64 %X, 32
392  %1 = trunc i64 %0 to i32
393  %2 = trunc i64 %X to i32
394  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -3)
395  %4 = extractvalue { i32, i32 } %3, 1
396  %5 = zext i32 %4 to i64
397  %6 = shl nuw i64 %5, 32
398  %7 = extractvalue { i32, i32 } %3, 0
399  %8 = zext i32 %7 to i64
400  %shr = or i64 %6, %8
401  %sm = lshr i64 %shr, 32
402  %t = trunc i64 %sm to i32
403  ret i32 %t
404}
405
406define i32 @lsll_demand_topm3(i64 %X) {
407; CHECK-LABEL: lsll_demand_topm3:
408; CHECK:       @ %bb.0: @ %entry
409; CHECK-NEXT:    lsrl r0, r1, #3
410; CHECK-NEXT:    mov r0, r1
411; CHECK-NEXT:    bx lr
412entry:
413  %0 = lshr i64 %X, 32
414  %1 = trunc i64 %0 to i32
415  %2 = trunc i64 %X to i32
416  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -3)
417  %4 = extractvalue { i32, i32 } %3, 1
418  %5 = zext i32 %4 to i64
419  %6 = shl nuw i64 %5, 32
420  %7 = extractvalue { i32, i32 } %3, 0
421  %8 = zext i32 %7 to i64
422  %shr = or i64 %6, %8
423  %sm = lshr i64 %shr, 32
424  %t = trunc i64 %sm to i32
425  ret i32 %t
426}
427
428
429define i32 @ashr_demand_top31(i64 %X) {
430; CHECK-LABEL: ashr_demand_top31:
431; CHECK:       @ %bb.0: @ %entry
432; CHECK-NEXT:    asrl r0, r1, #31
433; CHECK-NEXT:    mov r0, r1
434; CHECK-NEXT:    bx lr
435entry:
436  %0 = lshr i64 %X, 32
437  %1 = trunc i64 %0 to i32
438  %2 = trunc i64 %X to i32
439  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 31)
440  %4 = extractvalue { i32, i32 } %3, 1
441  %5 = zext i32 %4 to i64
442  %6 = shl nuw i64 %5, 32
443  %7 = extractvalue { i32, i32 } %3, 0
444  %8 = zext i32 %7 to i64
445  %shr = or i64 %6, %8
446  %sm = lshr i64 %shr, 32
447  %t = trunc i64 %sm to i32
448  ret i32 %t
449}
450
451define i32 @lsll_demand_top31(i64 %X) {
452; CHECK-LABEL: lsll_demand_top31:
453; CHECK:       @ %bb.0: @ %entry
454; CHECK-NEXT:    lsll r0, r1, #31
455; CHECK-NEXT:    mov r0, r1
456; CHECK-NEXT:    bx lr
457entry:
458  %0 = lshr i64 %X, 32
459  %1 = trunc i64 %0 to i32
460  %2 = trunc i64 %X to i32
461  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 31)
462  %4 = extractvalue { i32, i32 } %3, 1
463  %5 = zext i32 %4 to i64
464  %6 = shl nuw i64 %5, 32
465  %7 = extractvalue { i32, i32 } %3, 0
466  %8 = zext i32 %7 to i64
467  %shr = or i64 %6, %8
468  %sm = lshr i64 %shr, 32
469  %t = trunc i64 %sm to i32
470  ret i32 %t
471}
472
473define i32 @ashr_demand_topm31(i64 %X) {
474; CHECK-LABEL: ashr_demand_topm31:
475; CHECK:       @ %bb.0: @ %entry
476; CHECK-NEXT:    lsll r0, r1, #31
477; CHECK-NEXT:    mov r0, r1
478; CHECK-NEXT:    bx lr
479entry:
480  %0 = lshr i64 %X, 32
481  %1 = trunc i64 %0 to i32
482  %2 = trunc i64 %X to i32
483  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -31)
484  %4 = extractvalue { i32, i32 } %3, 1
485  %5 = zext i32 %4 to i64
486  %6 = shl nuw i64 %5, 32
487  %7 = extractvalue { i32, i32 } %3, 0
488  %8 = zext i32 %7 to i64
489  %shr = or i64 %6, %8
490  %sm = lshr i64 %shr, 32
491  %t = trunc i64 %sm to i32
492  ret i32 %t
493}
494
495define i32 @lsll_demand_topm31(i64 %X) {
496; CHECK-LABEL: lsll_demand_topm31:
497; CHECK:       @ %bb.0: @ %entry
498; CHECK-NEXT:    lsrl r0, r1, #31
499; CHECK-NEXT:    mov r0, r1
500; CHECK-NEXT:    bx lr
501entry:
502  %0 = lshr i64 %X, 32
503  %1 = trunc i64 %0 to i32
504  %2 = trunc i64 %X to i32
505  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -31)
506  %4 = extractvalue { i32, i32 } %3, 1
507  %5 = zext i32 %4 to i64
508  %6 = shl nuw i64 %5, 32
509  %7 = extractvalue { i32, i32 } %3, 0
510  %8 = zext i32 %7 to i64
511  %shr = or i64 %6, %8
512  %sm = lshr i64 %shr, 32
513  %t = trunc i64 %sm to i32
514  ret i32 %t
515}
516
517
518define i32 @ashr_demand_top32(i64 %X) {
519; CHECK-LABEL: ashr_demand_top32:
520; CHECK:       @ %bb.0: @ %entry
521; CHECK-NEXT:    asrl r0, r1, #32
522; CHECK-NEXT:    mov r0, r1
523; CHECK-NEXT:    bx lr
524entry:
525  %0 = lshr i64 %X, 32
526  %1 = trunc i64 %0 to i32
527  %2 = trunc i64 %X to i32
528  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 32)
529  %4 = extractvalue { i32, i32 } %3, 1
530  %5 = zext i32 %4 to i64
531  %6 = shl nuw i64 %5, 32
532  %7 = extractvalue { i32, i32 } %3, 0
533  %8 = zext i32 %7 to i64
534  %shr = or i64 %6, %8
535  %sm = lshr i64 %shr, 32
536  %t = trunc i64 %sm to i32
537  ret i32 %t
538}
539
540define i32 @lsll_demand_top32(i64 %X) {
541; CHECK-LABEL: lsll_demand_top32:
542; CHECK:       @ %bb.0: @ %entry
543; CHECK-NEXT:    lsll r0, r1, #32
544; CHECK-NEXT:    mov r0, r1
545; CHECK-NEXT:    bx lr
546entry:
547  %0 = lshr i64 %X, 32
548  %1 = trunc i64 %0 to i32
549  %2 = trunc i64 %X to i32
550  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 32)
551  %4 = extractvalue { i32, i32 } %3, 1
552  %5 = zext i32 %4 to i64
553  %6 = shl nuw i64 %5, 32
554  %7 = extractvalue { i32, i32 } %3, 0
555  %8 = zext i32 %7 to i64
556  %shr = or i64 %6, %8
557  %sm = lshr i64 %shr, 32
558  %t = trunc i64 %sm to i32
559  ret i32 %t
560}
561
562define i32 @ashr_demand_topm32(i64 %X) {
563; CHECK-LABEL: ashr_demand_topm32:
564; CHECK:       @ %bb.0: @ %entry
565; CHECK-NEXT:    lsll r0, r1, #32
566; CHECK-NEXT:    mov r0, r1
567; CHECK-NEXT:    bx lr
568entry:
569  %0 = lshr i64 %X, 32
570  %1 = trunc i64 %0 to i32
571  %2 = trunc i64 %X to i32
572  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -32)
573  %4 = extractvalue { i32, i32 } %3, 1
574  %5 = zext i32 %4 to i64
575  %6 = shl nuw i64 %5, 32
576  %7 = extractvalue { i32, i32 } %3, 0
577  %8 = zext i32 %7 to i64
578  %shr = or i64 %6, %8
579  %sm = lshr i64 %shr, 32
580  %t = trunc i64 %sm to i32
581  ret i32 %t
582}
583
584define i32 @lsll_demand_topm32(i64 %X) {
585; CHECK-LABEL: lsll_demand_topm32:
586; CHECK:       @ %bb.0: @ %entry
587; CHECK-NEXT:    lsrl r0, r1, #32
588; CHECK-NEXT:    mov r0, r1
589; CHECK-NEXT:    bx lr
590entry:
591  %0 = lshr i64 %X, 32
592  %1 = trunc i64 %0 to i32
593  %2 = trunc i64 %X to i32
594  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -32)
595  %4 = extractvalue { i32, i32 } %3, 1
596  %5 = zext i32 %4 to i64
597  %6 = shl nuw i64 %5, 32
598  %7 = extractvalue { i32, i32 } %3, 0
599  %8 = zext i32 %7 to i64
600  %shr = or i64 %6, %8
601  %sm = lshr i64 %shr, 32
602  %t = trunc i64 %sm to i32
603  ret i32 %t
604}
605
606
607define i32 @ashr_demand_top44(i64 %X) {
608; CHECK-LABEL: ashr_demand_top44:
609; CHECK:       @ %bb.0: @ %entry
610; CHECK-NEXT:    movs r2, #44
611; CHECK-NEXT:    asrl r0, r1, r2
612; CHECK-NEXT:    mov r0, r1
613; CHECK-NEXT:    bx lr
614entry:
615  %0 = lshr i64 %X, 32
616  %1 = trunc i64 %0 to i32
617  %2 = trunc i64 %X to i32
618  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 44)
619  %4 = extractvalue { i32, i32 } %3, 1
620  %5 = zext i32 %4 to i64
621  %6 = shl nuw i64 %5, 32
622  %7 = extractvalue { i32, i32 } %3, 0
623  %8 = zext i32 %7 to i64
624  %shr = or i64 %6, %8
625  %sm = lshr i64 %shr, 32
626  %t = trunc i64 %sm to i32
627  ret i32 %t
628}
629
630define i32 @lsll_demand_top44(i64 %X) {
631; CHECK-LABEL: lsll_demand_top44:
632; CHECK:       @ %bb.0: @ %entry
633; CHECK-NEXT:    movs r2, #44
634; CHECK-NEXT:    lsll r0, r1, r2
635; CHECK-NEXT:    mov r0, r1
636; CHECK-NEXT:    bx lr
637entry:
638  %0 = lshr i64 %X, 32
639  %1 = trunc i64 %0 to i32
640  %2 = trunc i64 %X to i32
641  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 44)
642  %4 = extractvalue { i32, i32 } %3, 1
643  %5 = zext i32 %4 to i64
644  %6 = shl nuw i64 %5, 32
645  %7 = extractvalue { i32, i32 } %3, 0
646  %8 = zext i32 %7 to i64
647  %shr = or i64 %6, %8
648  %sm = lshr i64 %shr, 32
649  %t = trunc i64 %sm to i32
650  ret i32 %t
651}
652
653define i32 @ashr_demand_topm44(i64 %X) {
654; CHECK-LABEL: ashr_demand_topm44:
655; CHECK:       @ %bb.0: @ %entry
656; CHECK-NEXT:    mvn r2, #43
657; CHECK-NEXT:    asrl r0, r1, r2
658; CHECK-NEXT:    mov r0, r1
659; CHECK-NEXT:    bx lr
660entry:
661  %0 = lshr i64 %X, 32
662  %1 = trunc i64 %0 to i32
663  %2 = trunc i64 %X to i32
664  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -44)
665  %4 = extractvalue { i32, i32 } %3, 1
666  %5 = zext i32 %4 to i64
667  %6 = shl nuw i64 %5, 32
668  %7 = extractvalue { i32, i32 } %3, 0
669  %8 = zext i32 %7 to i64
670  %shr = or i64 %6, %8
671  %sm = lshr i64 %shr, 32
672  %t = trunc i64 %sm to i32
673  ret i32 %t
674}
675
676define i32 @lsll_demand_topm44(i64 %X) {
677; CHECK-LABEL: lsll_demand_topm44:
678; CHECK:       @ %bb.0: @ %entry
679; CHECK-NEXT:    mvn r2, #43
680; CHECK-NEXT:    lsll r0, r1, r2
681; CHECK-NEXT:    mov r0, r1
682; CHECK-NEXT:    bx lr
683entry:
684  %0 = lshr i64 %X, 32
685  %1 = trunc i64 %0 to i32
686  %2 = trunc i64 %X to i32
687  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -44)
688  %4 = extractvalue { i32, i32 } %3, 1
689  %5 = zext i32 %4 to i64
690  %6 = shl nuw i64 %5, 32
691  %7 = extractvalue { i32, i32 } %3, 0
692  %8 = zext i32 %7 to i64
693  %shr = or i64 %6, %8
694  %sm = lshr i64 %shr, 32
695  %t = trunc i64 %sm to i32
696  ret i32 %t
697}
698
699
700
701define i32 @ashr_demand_bottommask3(i64 %X) {
702; CHECK-LABEL: ashr_demand_bottommask3:
703; CHECK:       @ %bb.0: @ %entry
704; CHECK-NEXT:    asrl r0, r1, #3
705; CHECK-NEXT:    bic r0, r0, #1
706; CHECK-NEXT:    bx lr
707entry:
708  %0 = lshr i64 %X, 32
709  %1 = trunc i64 %0 to i32
710  %2 = trunc i64 %X to i32
711  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 3)
712  %4 = extractvalue { i32, i32 } %3, 1
713  %5 = zext i32 %4 to i64
714  %6 = shl nuw i64 %5, 32
715  %7 = extractvalue { i32, i32 } %3, 0
716  %8 = zext i32 %7 to i64
717  %shr = or i64 %6, %8
718  %t = trunc i64 %shr to i32
719  %a = and i32 %t, -2
720  ret i32 %a
721}
722
723define i32 @lsll_demand_bottommask3(i64 %X) {
724; CHECK-LABEL: lsll_demand_bottommask3:
725; CHECK:       @ %bb.0: @ %entry
726; CHECK-NEXT:    lsll r0, r1, #3
727; CHECK-NEXT:    bic r0, r0, #1
728; CHECK-NEXT:    bx lr
729entry:
730  %0 = lshr i64 %X, 32
731  %1 = trunc i64 %0 to i32
732  %2 = trunc i64 %X to i32
733  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 3)
734  %4 = extractvalue { i32, i32 } %3, 1
735  %5 = zext i32 %4 to i64
736  %6 = shl nuw i64 %5, 32
737  %7 = extractvalue { i32, i32 } %3, 0
738  %8 = zext i32 %7 to i64
739  %shr = or i64 %6, %8
740  %t = trunc i64 %shr to i32
741  %a = and i32 %t, -2
742  ret i32 %a
743}
744
745define i32 @ashr_demand_bottommaskm3(i64 %X) {
746; CHECK-LABEL: ashr_demand_bottommaskm3:
747; CHECK:       @ %bb.0: @ %entry
748; CHECK-NEXT:    lsll r0, r1, #3
749; CHECK-NEXT:    bic r0, r0, #1
750; CHECK-NEXT:    bx lr
751entry:
752  %0 = lshr i64 %X, 32
753  %1 = trunc i64 %0 to i32
754  %2 = trunc i64 %X to i32
755  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -3)
756  %4 = extractvalue { i32, i32 } %3, 1
757  %5 = zext i32 %4 to i64
758  %6 = shl nuw i64 %5, 32
759  %7 = extractvalue { i32, i32 } %3, 0
760  %8 = zext i32 %7 to i64
761  %shr = or i64 %6, %8
762  %t = trunc i64 %shr to i32
763  %a = and i32 %t, -2
764  ret i32 %a
765}
766
767define i32 @lsll_demand_bottommaskm3(i64 %X) {
768; CHECK-LABEL: lsll_demand_bottommaskm3:
769; CHECK:       @ %bb.0: @ %entry
770; CHECK-NEXT:    lsrl r0, r1, #3
771; CHECK-NEXT:    bic r0, r0, #1
772; CHECK-NEXT:    bx lr
773entry:
774  %0 = lshr i64 %X, 32
775  %1 = trunc i64 %0 to i32
776  %2 = trunc i64 %X to i32
777  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -3)
778  %4 = extractvalue { i32, i32 } %3, 1
779  %5 = zext i32 %4 to i64
780  %6 = shl nuw i64 %5, 32
781  %7 = extractvalue { i32, i32 } %3, 0
782  %8 = zext i32 %7 to i64
783  %shr = or i64 %6, %8
784  %t = trunc i64 %shr to i32
785  %a = and i32 %t, -2
786  ret i32 %a
787}
788
789
790define i32 @ashr_demand_bottommask32(i64 %X) {
791; CHECK-LABEL: ashr_demand_bottommask32:
792; CHECK:       @ %bb.0: @ %entry
793; CHECK-NEXT:    asrl r0, r1, #32
794; CHECK-NEXT:    bic r0, r0, #1
795; CHECK-NEXT:    bx lr
796entry:
797  %0 = lshr i64 %X, 32
798  %1 = trunc i64 %0 to i32
799  %2 = trunc i64 %X to i32
800  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 32)
801  %4 = extractvalue { i32, i32 } %3, 1
802  %5 = zext i32 %4 to i64
803  %6 = shl nuw i64 %5, 32
804  %7 = extractvalue { i32, i32 } %3, 0
805  %8 = zext i32 %7 to i64
806  %shr = or i64 %6, %8
807  %t = trunc i64 %shr to i32
808  %a = and i32 %t, -2
809  ret i32 %a
810}
811
812define i32 @lsll_demand_bottommask32(i64 %X) {
813; CHECK-LABEL: lsll_demand_bottommask32:
814; CHECK:       @ %bb.0: @ %entry
815; CHECK-NEXT:    lsll r0, r1, #32
816; CHECK-NEXT:    bic r0, r0, #1
817; CHECK-NEXT:    bx lr
818entry:
819  %0 = lshr i64 %X, 32
820  %1 = trunc i64 %0 to i32
821  %2 = trunc i64 %X to i32
822  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 32)
823  %4 = extractvalue { i32, i32 } %3, 1
824  %5 = zext i32 %4 to i64
825  %6 = shl nuw i64 %5, 32
826  %7 = extractvalue { i32, i32 } %3, 0
827  %8 = zext i32 %7 to i64
828  %shr = or i64 %6, %8
829  %t = trunc i64 %shr to i32
830  %a = and i32 %t, -2
831  ret i32 %a
832}
833
834define i32 @ashr_demand_bottommaskm32(i64 %X) {
835; CHECK-LABEL: ashr_demand_bottommaskm32:
836; CHECK:       @ %bb.0: @ %entry
837; CHECK-NEXT:    lsll r0, r1, #32
838; CHECK-NEXT:    bic r0, r0, #1
839; CHECK-NEXT:    bx lr
840entry:
841  %0 = lshr i64 %X, 32
842  %1 = trunc i64 %0 to i32
843  %2 = trunc i64 %X to i32
844  %3 = call { i32, i32 } @llvm.arm.mve.asrl(i32 %2, i32 %1, i32 -32)
845  %4 = extractvalue { i32, i32 } %3, 1
846  %5 = zext i32 %4 to i64
847  %6 = shl nuw i64 %5, 32
848  %7 = extractvalue { i32, i32 } %3, 0
849  %8 = zext i32 %7 to i64
850  %shr = or i64 %6, %8
851  %t = trunc i64 %shr to i32
852  %a = and i32 %t, -2
853  ret i32 %a
854}
855
856define i32 @lsll_demand_bottommaskm32(i64 %X) {
857; CHECK-LABEL: lsll_demand_bottommaskm32:
858; CHECK:       @ %bb.0: @ %entry
859; CHECK-NEXT:    lsrl r0, r1, #32
860; CHECK-NEXT:    bic r0, r0, #1
861; CHECK-NEXT:    bx lr
862entry:
863  %0 = lshr i64 %X, 32
864  %1 = trunc i64 %0 to i32
865  %2 = trunc i64 %X to i32
866  %3 = call { i32, i32 } @llvm.arm.mve.lsll(i32 %2, i32 %1, i32 -32)
867  %4 = extractvalue { i32, i32 } %3, 1
868  %5 = zext i32 %4 to i64
869  %6 = shl nuw i64 %5, 32
870  %7 = extractvalue { i32, i32 } %3, 0
871  %8 = zext i32 %7 to i64
872  %shr = or i64 %6, %8
873  %t = trunc i64 %shr to i32
874  %a = and i32 %t, -2
875  ret i32 %a
876}
877