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 r1, [r0]
306; CHECK-BE-NEXT:    ldrh r0, [r0, #4]
307; CHECK-BE-NEXT:    orr r0, r0, r1, lsl #16
308; CHECK-BE-NEXT:    bx lr
309;
310; CHECK-THUMB-LABEL: test_lshr_load64_4_unaligned:
311; CHECK-THUMB:       @ %bb.0: @ %entry
312; CHECK-THUMB-NEXT:    ldr.w r0, [r0, #2]
313; CHECK-THUMB-NEXT:    bx lr
314;
315; CHECK-ALIGN-LABEL: test_lshr_load64_4_unaligned:
316; CHECK-ALIGN:       @ %bb.0: @ %entry
317; CHECK-ALIGN-NEXT:    ldr r1, [r0, #4]
318; CHECK-ALIGN-NEXT:    ldrh r0, [r0, #2]
319; CHECK-ALIGN-NEXT:    orr.w r0, r0, r1, lsl #16
320; CHECK-ALIGN-NEXT:    bx lr
321;
322; CHECK-V6M-LABEL: test_lshr_load64_4_unaligned:
323; CHECK-V6M:       @ %bb.0: @ %entry
324; CHECK-V6M-NEXT:    ldrh r1, [r0, #2]
325; CHECK-V6M-NEXT:    ldr r0, [r0, #4]
326; CHECK-V6M-NEXT:    lsls r0, r0, #16
327; CHECK-V6M-NEXT:    adds r0, r1, r0
328; CHECK-V6M-NEXT:    bx lr
329entry:
330  %0 = load i64, i64* %a, align 8
331  %1 = lshr i64 %0, 16
332  %conv = trunc i64 %1 to i32
333  ret i32 %conv
334}
335
336define arm_aapcscc i32 @test_lshr_load64_1_lsb(i64* %a) {
337; CHECK-ARM-LABEL: test_lshr_load64_1_lsb:
338; CHECK-ARM:       @ %bb.0: @ %entry
339; CHECK-ARM-NEXT:    ldr r0, [r0, #3]
340; CHECK-ARM-NEXT:    bx lr
341;
342; CHECK-BE-LABEL: test_lshr_load64_1_lsb:
343; CHECK-BE:       @ %bb.0: @ %entry
344; CHECK-BE-NEXT:    ldr r1, [r0]
345; CHECK-BE-NEXT:    ldrb r0, [r0, #4]
346; CHECK-BE-NEXT:    orr r0, r0, r1, lsl #8
347; CHECK-BE-NEXT:    bx lr
348;
349; CHECK-THUMB-LABEL: test_lshr_load64_1_lsb:
350; CHECK-THUMB:       @ %bb.0: @ %entry
351; CHECK-THUMB-NEXT:    ldr.w r0, [r0, #3]
352; CHECK-THUMB-NEXT:    bx lr
353;
354; CHECK-ALIGN-LABEL: test_lshr_load64_1_lsb:
355; CHECK-ALIGN:       @ %bb.0: @ %entry
356; CHECK-ALIGN-NEXT:    ldr r1, [r0, #4]
357; CHECK-ALIGN-NEXT:    ldrb r0, [r0, #3]
358; CHECK-ALIGN-NEXT:    orr.w r0, r0, r1, lsl #8
359; CHECK-ALIGN-NEXT:    bx lr
360;
361; CHECK-V6M-LABEL: test_lshr_load64_1_lsb:
362; CHECK-V6M:       @ %bb.0: @ %entry
363; CHECK-V6M-NEXT:    ldrb r1, [r0, #3]
364; CHECK-V6M-NEXT:    ldr r0, [r0, #4]
365; CHECK-V6M-NEXT:    lsls r0, r0, #8
366; CHECK-V6M-NEXT:    adds r0, r1, r0
367; CHECK-V6M-NEXT:    bx lr
368entry:
369  %0 = load i64, i64* %a, align 8
370  %1 = lshr i64 %0, 24
371  %conv = trunc i64 %1 to i32
372  ret i32 %conv
373}
374
375define arm_aapcscc i32 @test_lshr_load64_1_msb(i64* %a) {
376; CHECK-COMMON-LABEL: test_lshr_load64_1_msb:
377; CHECK-COMMON:       @ %bb.0: @ %entry
378; CHECK-COMMON-NEXT:    ldrb r0, [r0, #7]
379; CHECK-COMMON-NEXT:    bx lr
380;
381; CHECK-BE-LABEL: test_lshr_load64_1_msb:
382; CHECK-BE:       @ %bb.0: @ %entry
383; CHECK-BE-NEXT:    ldrb r0, [r0]
384; CHECK-BE-NEXT:    bx lr
385;
386; CHECK-V6M-LABEL: test_lshr_load64_1_msb:
387; CHECK-V6M:       @ %bb.0: @ %entry
388; CHECK-V6M-NEXT:    ldrb r0, [r0, #7]
389; CHECK-V6M-NEXT:    bx lr
390entry:
391  %0 = load i64, i64* %a, align 8
392  %1 = lshr i64 %0, 56
393  %conv = trunc i64 %1 to i32
394  ret i32 %conv
395}
396
397define arm_aapcscc i32 @test_lshr_load64_4(i64* %a) {
398; CHECK-COMMON-LABEL: test_lshr_load64_4:
399; CHECK-COMMON:       @ %bb.0: @ %entry
400; CHECK-COMMON-NEXT:    ldr r0, [r0, #4]
401; CHECK-COMMON-NEXT:    bx lr
402;
403; CHECK-BE-LABEL: test_lshr_load64_4:
404; CHECK-BE:       @ %bb.0: @ %entry
405; CHECK-BE-NEXT:    ldr r0, [r0]
406; CHECK-BE-NEXT:    bx lr
407;
408; CHECK-V6M-LABEL: test_lshr_load64_4:
409; CHECK-V6M:       @ %bb.0: @ %entry
410; CHECK-V6M-NEXT:    ldr r0, [r0, #4]
411; CHECK-V6M-NEXT:    bx lr
412entry:
413  %0 = load i64, i64* %a, align 8
414  %1 = lshr i64 %0, 32
415  %conv = trunc i64 %1 to i32
416  ret i32 %conv
417}
418
419define arm_aapcscc i32 @test_lshr_load64_2(i64* %a) {
420; CHECK-COMMON-LABEL: test_lshr_load64_2:
421; CHECK-COMMON:       @ %bb.0: @ %entry
422; CHECK-COMMON-NEXT:    ldrh r0, [r0, #6]
423; CHECK-COMMON-NEXT:    bx lr
424;
425; CHECK-BE-LABEL: test_lshr_load64_2:
426; CHECK-BE:       @ %bb.0: @ %entry
427; CHECK-BE-NEXT:    ldrh r0, [r0]
428; CHECK-BE-NEXT:    bx lr
429;
430; CHECK-V6M-LABEL: test_lshr_load64_2:
431; CHECK-V6M:       @ %bb.0: @ %entry
432; CHECK-V6M-NEXT:    ldrh r0, [r0, #6]
433; CHECK-V6M-NEXT:    bx lr
434entry:
435  %0 = load i64, i64* %a, align 8
436  %1 = lshr i64 %0, 48
437  %conv = trunc i64 %1 to i32
438  ret i32 %conv
439}
440
441define arm_aapcscc i32 @test_lshr_load4_fail(i64* %a) {
442; CHECK-ARM-LABEL: test_lshr_load4_fail:
443; CHECK-ARM:       @ %bb.0: @ %entry
444; CHECK-ARM-NEXT:    ldrd r0, r1, [r0]
445; CHECK-ARM-NEXT:    lsr r0, r0, #8
446; CHECK-ARM-NEXT:    orr r0, r0, r1, lsl #24
447; CHECK-ARM-NEXT:    bx lr
448;
449; CHECK-BE-LABEL: test_lshr_load4_fail:
450; CHECK-BE:       @ %bb.0: @ %entry
451; CHECK-BE-NEXT:    ldrd r0, r1, [r0]
452; CHECK-BE-NEXT:    lsr r1, r1, #8
453; CHECK-BE-NEXT:    orr r0, r1, r0, lsl #24
454; CHECK-BE-NEXT:    bx lr
455;
456; CHECK-THUMB-LABEL: test_lshr_load4_fail:
457; CHECK-THUMB:       @ %bb.0: @ %entry
458; CHECK-THUMB-NEXT:    ldrd r0, r1, [r0]
459; CHECK-THUMB-NEXT:    lsrs r0, r0, #8
460; CHECK-THUMB-NEXT:    orr.w r0, r0, r1, lsl #24
461; CHECK-THUMB-NEXT:    bx lr
462;
463; CHECK-ALIGN-LABEL: test_lshr_load4_fail:
464; CHECK-ALIGN:       @ %bb.0: @ %entry
465; CHECK-ALIGN-NEXT:    ldrd r0, r1, [r0]
466; CHECK-ALIGN-NEXT:    lsrs r0, r0, #8
467; CHECK-ALIGN-NEXT:    orr.w r0, r0, r1, lsl #24
468; CHECK-ALIGN-NEXT:    bx lr
469;
470; CHECK-V6M-LABEL: test_lshr_load4_fail:
471; CHECK-V6M:       @ %bb.0: @ %entry
472; CHECK-V6M-NEXT:    ldr r1, [r0]
473; CHECK-V6M-NEXT:    ldr r0, [r0, #4]
474; CHECK-V6M-NEXT:    lsls r0, r0, #24
475; CHECK-V6M-NEXT:    lsrs r1, r1, #8
476; CHECK-V6M-NEXT:    adds r0, r1, r0
477; CHECK-V6M-NEXT:    bx lr
478entry:
479  %0 = load i64, i64* %a, align 8
480  %1 = lshr i64 %0, 8
481  %conv = trunc i64 %1 to i32
482  ret i32 %conv
483}
484
485define arm_aapcscc void @test_shift7_mask8(i32* nocapture %p) {
486; CHECK-COMMON-LABEL: test_shift7_mask8:
487; CHECK-COMMON:       @ %bb.0: @ %entry
488; CHECK-COMMON-NEXT:    ldr r1, [r0]
489; CHECK-COMMON-NEXT:    ubfx r1, r1, #7, #8
490; CHECK-COMMON-NEXT:    str r1, [r0]
491; CHECK-COMMON-NEXT:    bx lr
492;
493; CHECK-BE-LABEL: test_shift7_mask8:
494; CHECK-BE:       @ %bb.0: @ %entry
495; CHECK-BE-NEXT:    ldr r1, [r0]
496; CHECK-BE-NEXT:    ubfx r1, r1, #7, #8
497; CHECK-BE-NEXT:    str r1, [r0]
498; CHECK-BE-NEXT:    bx lr
499;
500; CHECK-V6M-LABEL: test_shift7_mask8:
501; CHECK-V6M:       @ %bb.0: @ %entry
502; CHECK-V6M-NEXT:    ldr r1, [r0]
503; CHECK-V6M-NEXT:    lsrs r1, r1, #7
504; CHECK-V6M-NEXT:    uxtb r1, r1
505; CHECK-V6M-NEXT:    str r1, [r0]
506; CHECK-V6M-NEXT:    bx lr
507entry:
508  %0 = load i32, i32* %p, align 4
509  %shl = lshr i32 %0, 7
510  %and = and i32 %shl, 255
511  store i32 %and, i32* %p, align 4
512  ret void
513}
514
515define arm_aapcscc void @test_shift8_mask8(i32* nocapture %p) {
516; CHECK-COMMON-LABEL: test_shift8_mask8:
517; CHECK-COMMON:       @ %bb.0: @ %entry
518; CHECK-COMMON-NEXT:    ldrb r1, [r0, #1]
519; CHECK-COMMON-NEXT:    str r1, [r0]
520; CHECK-COMMON-NEXT:    bx lr
521;
522; CHECK-BE-LABEL: test_shift8_mask8:
523; CHECK-BE:       @ %bb.0: @ %entry
524; CHECK-BE-NEXT:    ldrb r1, [r0, #2]
525; CHECK-BE-NEXT:    str r1, [r0]
526; CHECK-BE-NEXT:    bx lr
527;
528; CHECK-V6M-LABEL: test_shift8_mask8:
529; CHECK-V6M:       @ %bb.0: @ %entry
530; CHECK-V6M-NEXT:    ldrb r1, [r0, #1]
531; CHECK-V6M-NEXT:    str r1, [r0]
532; CHECK-V6M-NEXT:    bx lr
533entry:
534  %0 = load i32, i32* %p, align 4
535  %shl = lshr i32 %0, 8
536  %and = and i32 %shl, 255
537  store i32 %and, i32* %p, align 4
538  ret void
539}
540
541define arm_aapcscc void @test_shift8_mask7(i32* nocapture %p) {
542; CHECK-COMMON-LABEL: test_shift8_mask7:
543; CHECK-COMMON:       @ %bb.0: @ %entry
544; CHECK-COMMON-NEXT:    ldr r1, [r0]
545; CHECK-COMMON-NEXT:    ubfx r1, r1, #8, #7
546; CHECK-COMMON-NEXT:    str r1, [r0]
547; CHECK-COMMON-NEXT:    bx lr
548;
549; CHECK-BE-LABEL: test_shift8_mask7:
550; CHECK-BE:       @ %bb.0: @ %entry
551; CHECK-BE-NEXT:    ldr r1, [r0]
552; CHECK-BE-NEXT:    ubfx r1, r1, #8, #7
553; CHECK-BE-NEXT:    str r1, [r0]
554; CHECK-BE-NEXT:    bx lr
555;
556; CHECK-V6M-LABEL: test_shift8_mask7:
557; CHECK-V6M:       @ %bb.0: @ %entry
558; CHECK-V6M-NEXT:    ldr r1, [r0]
559; CHECK-V6M-NEXT:    lsls r1, r1, #17
560; CHECK-V6M-NEXT:    lsrs r1, r1, #25
561; CHECK-V6M-NEXT:    str r1, [r0]
562; CHECK-V6M-NEXT:    bx lr
563entry:
564  %0 = load i32, i32* %p, align 4
565  %shl = lshr i32 %0, 8
566  %and = and i32 %shl, 127
567  store i32 %and, i32* %p, align 4
568  ret void
569}
570
571define arm_aapcscc void @test_shift9_mask8(i32* nocapture %p) {
572; CHECK-COMMON-LABEL: test_shift9_mask8:
573; CHECK-COMMON:       @ %bb.0: @ %entry
574; CHECK-COMMON-NEXT:    ldr r1, [r0]
575; CHECK-COMMON-NEXT:    ubfx r1, r1, #9, #8
576; CHECK-COMMON-NEXT:    str r1, [r0]
577; CHECK-COMMON-NEXT:    bx lr
578;
579; CHECK-BE-LABEL: test_shift9_mask8:
580; CHECK-BE:       @ %bb.0: @ %entry
581; CHECK-BE-NEXT:    ldr r1, [r0]
582; CHECK-BE-NEXT:    ubfx r1, r1, #9, #8
583; CHECK-BE-NEXT:    str r1, [r0]
584; CHECK-BE-NEXT:    bx lr
585;
586; CHECK-V6M-LABEL: test_shift9_mask8:
587; CHECK-V6M:       @ %bb.0: @ %entry
588; CHECK-V6M-NEXT:    ldr r1, [r0]
589; CHECK-V6M-NEXT:    lsrs r1, r1, #9
590; CHECK-V6M-NEXT:    uxtb r1, r1
591; CHECK-V6M-NEXT:    str r1, [r0]
592; CHECK-V6M-NEXT:    bx lr
593entry:
594  %0 = load i32, i32* %p, align 4
595  %shl = lshr i32 %0, 9
596  %and = and i32 %shl, 255
597  store i32 %and, i32* %p, align 4
598  ret void
599}
600
601define arm_aapcscc void @test_shift8_mask16(i32* nocapture %p) {
602; CHECK-ARM-LABEL: test_shift8_mask16:
603; CHECK-ARM:       @ %bb.0: @ %entry
604; CHECK-ARM-NEXT:    ldrh r1, [r0, #1]
605; CHECK-ARM-NEXT:    str r1, [r0]
606; CHECK-ARM-NEXT:    bx lr
607;
608; CHECK-BE-LABEL: test_shift8_mask16:
609; CHECK-BE:       @ %bb.0: @ %entry
610; CHECK-BE-NEXT:    ldrh r1, [r0, #1]
611; CHECK-BE-NEXT:    str r1, [r0]
612; CHECK-BE-NEXT:    bx lr
613;
614; CHECK-THUMB-LABEL: test_shift8_mask16:
615; CHECK-THUMB:       @ %bb.0: @ %entry
616; CHECK-THUMB-NEXT:    ldrh.w r1, [r0, #1]
617; CHECK-THUMB-NEXT:    str r1, [r0]
618; CHECK-THUMB-NEXT:    bx lr
619;
620; CHECK-ALIGN-LABEL: test_shift8_mask16:
621; CHECK-ALIGN:       @ %bb.0: @ %entry
622; CHECK-ALIGN-NEXT:    ldr r1, [r0]
623; CHECK-ALIGN-NEXT:    ubfx r1, r1, #8, #16
624; CHECK-ALIGN-NEXT:    str r1, [r0]
625; CHECK-ALIGN-NEXT:    bx lr
626;
627; CHECK-V6M-LABEL: test_shift8_mask16:
628; CHECK-V6M:       @ %bb.0: @ %entry
629; CHECK-V6M-NEXT:    ldr r1, [r0]
630; CHECK-V6M-NEXT:    lsrs r1, r1, #8
631; CHECK-V6M-NEXT:    uxth r1, r1
632; CHECK-V6M-NEXT:    str r1, [r0]
633; CHECK-V6M-NEXT:    bx lr
634entry:
635  %0 = load i32, i32* %p, align 4
636  %shl = lshr i32 %0, 8
637  %and = and i32 %shl, 65535
638  store i32 %and, i32* %p, align 4
639  ret void
640}
641
642define arm_aapcscc void @test_shift15_mask16(i32* nocapture %p) {
643; CHECK-COMMON-LABEL: test_shift15_mask16:
644; CHECK-COMMON:       @ %bb.0: @ %entry
645; CHECK-COMMON-NEXT:    ldr r1, [r0]
646; CHECK-COMMON-NEXT:    ubfx r1, r1, #15, #16
647; CHECK-COMMON-NEXT:    str r1, [r0]
648; CHECK-COMMON-NEXT:    bx lr
649;
650; CHECK-BE-LABEL: test_shift15_mask16:
651; CHECK-BE:       @ %bb.0: @ %entry
652; CHECK-BE-NEXT:    ldr r1, [r0]
653; CHECK-BE-NEXT:    ubfx r1, r1, #15, #16
654; CHECK-BE-NEXT:    str r1, [r0]
655; CHECK-BE-NEXT:    bx lr
656;
657; CHECK-V6M-LABEL: test_shift15_mask16:
658; CHECK-V6M:       @ %bb.0: @ %entry
659; CHECK-V6M-NEXT:    ldr r1, [r0]
660; CHECK-V6M-NEXT:    lsrs r1, r1, #15
661; CHECK-V6M-NEXT:    uxth r1, r1
662; CHECK-V6M-NEXT:    str r1, [r0]
663; CHECK-V6M-NEXT:    bx lr
664entry:
665  %0 = load i32, i32* %p, align 4
666  %shl = lshr i32 %0, 15
667  %and = and i32 %shl, 65535
668  store i32 %and, i32* %p, align 4
669  ret void
670}
671
672define arm_aapcscc void @test_shift16_mask15(i32* nocapture %p) {
673; CHECK-COMMON-LABEL: test_shift16_mask15:
674; CHECK-COMMON:       @ %bb.0: @ %entry
675; CHECK-COMMON-NEXT:    ldrh r1, [r0, #2]
676; CHECK-COMMON-NEXT:    bfc r1, #15, #17
677; CHECK-COMMON-NEXT:    str r1, [r0]
678; CHECK-COMMON-NEXT:    bx lr
679;
680; CHECK-BE-LABEL: test_shift16_mask15:
681; CHECK-BE:       @ %bb.0: @ %entry
682; CHECK-BE-NEXT:    ldrh r1, [r0]
683; CHECK-BE-NEXT:    bfc r1, #15, #17
684; CHECK-BE-NEXT:    str r1, [r0]
685; CHECK-BE-NEXT:    bx lr
686;
687; CHECK-V6M-LABEL: test_shift16_mask15:
688; CHECK-V6M:       @ %bb.0: @ %entry
689; CHECK-V6M-NEXT:    ldrh r1, [r0, #2]
690; CHECK-V6M-NEXT:    ldr r2, .LCPI21_0
691; CHECK-V6M-NEXT:    ands r2, r1
692; CHECK-V6M-NEXT:    str r2, [r0]
693; CHECK-V6M-NEXT:    bx lr
694; CHECK-V6M-NEXT:    .p2align 2
695; CHECK-V6M-NEXT:  @ %bb.1:
696; CHECK-V6M-NEXT:  .LCPI21_0:
697; CHECK-V6M-NEXT:    .long 32767 @ 0x7fff
698entry:
699  %0 = load i32, i32* %p, align 4
700  %shl = lshr i32 %0, 16
701  %and = and i32 %shl, 32767
702  store i32 %and, i32* %p, align 4
703  ret void
704}
705
706define arm_aapcscc void @test_shift8_mask24(i32* nocapture %p) {
707; CHECK-ARM-LABEL: test_shift8_mask24:
708; CHECK-ARM:       @ %bb.0: @ %entry
709; CHECK-ARM-NEXT:    ldr r1, [r0]
710; CHECK-ARM-NEXT:    lsr r1, r1, #8
711; CHECK-ARM-NEXT:    str r1, [r0]
712; CHECK-ARM-NEXT:    bx lr
713;
714; CHECK-BE-LABEL: test_shift8_mask24:
715; CHECK-BE:       @ %bb.0: @ %entry
716; CHECK-BE-NEXT:    ldr r1, [r0]
717; CHECK-BE-NEXT:    lsr r1, r1, #8
718; CHECK-BE-NEXT:    str r1, [r0]
719; CHECK-BE-NEXT:    bx lr
720;
721; CHECK-THUMB-LABEL: test_shift8_mask24:
722; CHECK-THUMB:       @ %bb.0: @ %entry
723; CHECK-THUMB-NEXT:    ldr r1, [r0]
724; CHECK-THUMB-NEXT:    lsrs r1, r1, #8
725; CHECK-THUMB-NEXT:    str r1, [r0]
726; CHECK-THUMB-NEXT:    bx lr
727;
728; CHECK-ALIGN-LABEL: test_shift8_mask24:
729; CHECK-ALIGN:       @ %bb.0: @ %entry
730; CHECK-ALIGN-NEXT:    ldr r1, [r0]
731; CHECK-ALIGN-NEXT:    lsrs r1, r1, #8
732; CHECK-ALIGN-NEXT:    str r1, [r0]
733; CHECK-ALIGN-NEXT:    bx lr
734;
735; CHECK-V6M-LABEL: test_shift8_mask24:
736; CHECK-V6M:       @ %bb.0: @ %entry
737; CHECK-V6M-NEXT:    ldr r1, [r0]
738; CHECK-V6M-NEXT:    lsrs r1, r1, #8
739; CHECK-V6M-NEXT:    str r1, [r0]
740; CHECK-V6M-NEXT:    bx lr
741entry:
742  %0 = load i32, i32* %p, align 4
743  %shl = lshr i32 %0, 8
744  %and = and i32 %shl, 16777215
745  store i32 %and, i32* %p, align 4
746  ret void
747}
748
749define arm_aapcscc void @test_shift24_mask16(i32* nocapture %p) {
750; CHECK-COMMON-LABEL: test_shift24_mask16:
751; CHECK-COMMON:       @ %bb.0: @ %entry
752; CHECK-COMMON-NEXT:    ldrb r1, [r0, #3]
753; CHECK-COMMON-NEXT:    str r1, [r0]
754; CHECK-COMMON-NEXT:    bx lr
755;
756; CHECK-BE-LABEL: test_shift24_mask16:
757; CHECK-BE:       @ %bb.0: @ %entry
758; CHECK-BE-NEXT:    ldrb r1, [r0]
759; CHECK-BE-NEXT:    str r1, [r0]
760; CHECK-BE-NEXT:    bx lr
761;
762; CHECK-V6M-LABEL: test_shift24_mask16:
763; CHECK-V6M:       @ %bb.0: @ %entry
764; CHECK-V6M-NEXT:    ldrb r1, [r0, #3]
765; CHECK-V6M-NEXT:    str r1, [r0]
766; CHECK-V6M-NEXT:    bx lr
767entry:
768  %0 = load i32, i32* %p, align 4
769  %shl = lshr i32 %0, 24
770  %and = and i32 %shl, 65535
771  store i32 %and, i32* %p, align 4
772  ret void
773}
774
775define arm_aapcscc void @test_sext_shift8_mask8(i16* %p, i32* %q) {
776; CHECK-COMMON-LABEL: test_sext_shift8_mask8:
777; CHECK-COMMON:       @ %bb.0: @ %entry
778; CHECK-COMMON-NEXT:    ldrb r0, [r0, #1]
779; CHECK-COMMON-NEXT:    str r0, [r1]
780; CHECK-COMMON-NEXT:    bx lr
781;
782; CHECK-BE-LABEL: test_sext_shift8_mask8:
783; CHECK-BE:       @ %bb.0: @ %entry
784; CHECK-BE-NEXT:    ldrb r0, [r0]
785; CHECK-BE-NEXT:    str r0, [r1]
786; CHECK-BE-NEXT:    bx lr
787;
788; CHECK-V6M-LABEL: test_sext_shift8_mask8:
789; CHECK-V6M:       @ %bb.0: @ %entry
790; CHECK-V6M-NEXT:    ldrb r0, [r0, #1]
791; CHECK-V6M-NEXT:    str r0, [r1]
792; CHECK-V6M-NEXT:    bx lr
793entry:
794  %0 = load i16, i16* %p, align 4
795  %1 = sext i16 %0 to i32
796  %shl = lshr i32 %1, 8
797  %and = and i32 %shl, 255
798  store i32 %and, i32* %q, align 4
799  ret void
800}
801
802define arm_aapcscc void @test_sext_shift8_mask16(i16* %p, i32* %q) {
803; CHECK-ARM-LABEL: test_sext_shift8_mask16:
804; CHECK-ARM:       @ %bb.0: @ %entry
805; CHECK-ARM-NEXT:    ldrsh r0, [r0]
806; CHECK-ARM-NEXT:    ubfx r0, r0, #8, #16
807; CHECK-ARM-NEXT:    str r0, [r1]
808; CHECK-ARM-NEXT:    bx lr
809;
810; CHECK-BE-LABEL: test_sext_shift8_mask16:
811; CHECK-BE:       @ %bb.0: @ %entry
812; CHECK-BE-NEXT:    ldrsh r0, [r0]
813; CHECK-BE-NEXT:    ubfx r0, r0, #8, #16
814; CHECK-BE-NEXT:    str r0, [r1]
815; CHECK-BE-NEXT:    bx lr
816;
817; CHECK-THUMB-LABEL: test_sext_shift8_mask16:
818; CHECK-THUMB:       @ %bb.0: @ %entry
819; CHECK-THUMB-NEXT:    ldrsh.w r0, [r0]
820; CHECK-THUMB-NEXT:    ubfx r0, r0, #8, #16
821; CHECK-THUMB-NEXT:    str r0, [r1]
822; CHECK-THUMB-NEXT:    bx lr
823;
824; CHECK-ALIGN-LABEL: test_sext_shift8_mask16:
825; CHECK-ALIGN:       @ %bb.0: @ %entry
826; CHECK-ALIGN-NEXT:    ldrsh.w r0, [r0]
827; CHECK-ALIGN-NEXT:    ubfx r0, r0, #8, #16
828; CHECK-ALIGN-NEXT:    str r0, [r1]
829; CHECK-ALIGN-NEXT:    bx lr
830;
831; CHECK-V6M-LABEL: test_sext_shift8_mask16:
832; CHECK-V6M:       @ %bb.0: @ %entry
833; CHECK-V6M-NEXT:    movs r2, #0
834; CHECK-V6M-NEXT:    ldrsh r0, [r0, r2]
835; CHECK-V6M-NEXT:    lsrs r0, r0, #8
836; CHECK-V6M-NEXT:    uxth r0, r0
837; CHECK-V6M-NEXT:    str r0, [r1]
838; CHECK-V6M-NEXT:    bx lr
839entry:
840  %0 = load i16, i16* %p, align 4
841  %1 = sext i16 %0 to i32
842  %shl = lshr i32 %1, 8
843  %and = and i32 %shl, 65535
844  store i32 %and, i32* %q, align 4
845  ret void
846}
847
848define i1 @trunc_i64_mask_srl(i32 zeroext %AttrArgNo, i64* %ptr) {
849; CHECK-ARM-LABEL: trunc_i64_mask_srl:
850; CHECK-ARM:       @ %bb.0: @ %entry
851; CHECK-ARM-NEXT:    ldrh r2, [r1, #4]
852; CHECK-ARM-NEXT:    mov r1, #0
853; CHECK-ARM-NEXT:    cmp r2, r0
854; CHECK-ARM-NEXT:    movwhi r1, #1
855; CHECK-ARM-NEXT:    mov r0, r1
856; CHECK-ARM-NEXT:    bx lr
857;
858; CHECK-BE-LABEL: trunc_i64_mask_srl:
859; CHECK-BE:       @ %bb.0: @ %entry
860; CHECK-BE-NEXT:    ldrh r2, [r1, #2]
861; CHECK-BE-NEXT:    mov r1, #0
862; CHECK-BE-NEXT:    cmp r2, r0
863; CHECK-BE-NEXT:    movwhi r1, #1
864; CHECK-BE-NEXT:    mov r0, r1
865; CHECK-BE-NEXT:    bx lr
866;
867; CHECK-THUMB-LABEL: trunc_i64_mask_srl:
868; CHECK-THUMB:       @ %bb.0: @ %entry
869; CHECK-THUMB-NEXT:    ldrh r2, [r1, #4]
870; CHECK-THUMB-NEXT:    movs r1, #0
871; CHECK-THUMB-NEXT:    cmp r2, r0
872; CHECK-THUMB-NEXT:    it hi
873; CHECK-THUMB-NEXT:    movhi r1, #1
874; CHECK-THUMB-NEXT:    mov r0, r1
875; CHECK-THUMB-NEXT:    bx lr
876;
877; CHECK-ALIGN-LABEL: trunc_i64_mask_srl:
878; CHECK-ALIGN:       @ %bb.0: @ %entry
879; CHECK-ALIGN-NEXT:    ldrh r2, [r1, #4]
880; CHECK-ALIGN-NEXT:    movs r1, #0
881; CHECK-ALIGN-NEXT:    cmp r2, r0
882; CHECK-ALIGN-NEXT:    it hi
883; CHECK-ALIGN-NEXT:    movhi r1, #1
884; CHECK-ALIGN-NEXT:    mov r0, r1
885; CHECK-ALIGN-NEXT:    bx lr
886;
887; CHECK-V6M-LABEL: trunc_i64_mask_srl:
888; CHECK-V6M:       @ %bb.0: @ %entry
889; CHECK-V6M-NEXT:    ldrh r1, [r1, #4]
890; CHECK-V6M-NEXT:    cmp r1, r0
891; CHECK-V6M-NEXT:    bhi .LBB26_2
892; CHECK-V6M-NEXT:  @ %bb.1: @ %entry
893; CHECK-V6M-NEXT:    movs r0, #0
894; CHECK-V6M-NEXT:    bx lr
895; CHECK-V6M-NEXT:  .LBB26_2:
896; CHECK-V6M-NEXT:    movs r0, #1
897; CHECK-V6M-NEXT:    bx lr
898entry:
899  %bf.load.i = load i64, i64* %ptr, align 8
900  %bf.lshr.i = lshr i64 %bf.load.i, 32
901  %0 = trunc i64 %bf.lshr.i to i32
902  %bf.cast.i = and i32 %0, 65535
903  %cmp.i = icmp ugt i32 %bf.cast.i, %AttrArgNo
904  ret i1 %cmp.i
905}
906