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