xref: /llvm-project/llvm/test/CodeGen/ARM/shift-combine.ll (revision 6c52f82d77a1b8d9d9f8b585c73f94e58191b5a9)
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
897define i64 @or_tree_with_shifts_i64(i64 %a, i64 %b, i64 %c, i64 %d) {
898; CHECK-ARM-LABEL: or_tree_with_shifts_i64:
899; CHECK-ARM:       @ %bb.0:
900; CHECK-ARM-NEXT:    .save {r11, lr}
901; CHECK-ARM-NEXT:    push {r11, lr}
902; CHECK-ARM-NEXT:    ldr lr, [sp, #16]
903; CHECK-ARM-NEXT:    lsl r3, r3, #16
904; CHECK-ARM-NEXT:    ldr r12, [sp, #8]
905; CHECK-ARM-NEXT:    orr r3, r3, r2, lsr #16
906; CHECK-ARM-NEXT:    orr r0, r0, r2, lsl #16
907; CHECK-ARM-NEXT:    orr r1, r1, lr, lsl #16
908; CHECK-ARM-NEXT:    orr r1, r1, r3
909; CHECK-ARM-NEXT:    orr r1, r1, r12
910; CHECK-ARM-NEXT:    pop {r11, pc}
911;
912; CHECK-BE-LABEL: or_tree_with_shifts_i64:
913; CHECK-BE:       @ %bb.0:
914; CHECK-BE-NEXT:    .save {r11, lr}
915; CHECK-BE-NEXT:    push {r11, lr}
916; CHECK-BE-NEXT:    ldr lr, [sp, #20]
917; CHECK-BE-NEXT:    lsl r2, r2, #16
918; CHECK-BE-NEXT:    ldr r12, [sp, #12]
919; CHECK-BE-NEXT:    orr r2, r2, r3, lsr #16
920; CHECK-BE-NEXT:    orr r1, r1, r3, lsl #16
921; CHECK-BE-NEXT:    orr r0, r0, lr, lsl #16
922; CHECK-BE-NEXT:    orr r0, r0, r2
923; CHECK-BE-NEXT:    orr r0, r0, r12
924; CHECK-BE-NEXT:    pop {r11, pc}
925;
926; CHECK-ALIGN-LABEL: or_tree_with_shifts_i64:
927; CHECK-ALIGN:       @ %bb.0:
928; CHECK-ALIGN-NEXT:    ldr.w r12, [sp, #8]
929; CHECK-ALIGN-NEXT:    lsls r3, r3, #16
930; CHECK-ALIGN-NEXT:    orr.w r3, r3, r2, lsr #16
931; CHECK-ALIGN-NEXT:    orr.w r0, r0, r2, lsl #16
932; CHECK-ALIGN-NEXT:    orr.w r1, r1, r12, lsl #16
933; CHECK-ALIGN-NEXT:    orrs r1, r3
934; CHECK-ALIGN-NEXT:    ldr r3, [sp]
935; CHECK-ALIGN-NEXT:    orrs r1, r3
936; CHECK-ALIGN-NEXT:    bx lr
937;
938; CHECK-V6M-LABEL: or_tree_with_shifts_i64:
939; CHECK-V6M:       @ %bb.0:
940; CHECK-V6M-NEXT:    push {r4, lr}
941; CHECK-V6M-NEXT:    lsrs r4, r2, #16
942; CHECK-V6M-NEXT:    lsls r3, r3, #16
943; CHECK-V6M-NEXT:    adds r3, r3, r4
944; CHECK-V6M-NEXT:    ldr r4, [sp, #16]
945; CHECK-V6M-NEXT:    lsls r4, r4, #16
946; CHECK-V6M-NEXT:    orrs r1, r4
947; CHECK-V6M-NEXT:    orrs r1, r3
948; CHECK-V6M-NEXT:    ldr r3, [sp, #8]
949; CHECK-V6M-NEXT:    orrs r1, r3
950; CHECK-V6M-NEXT:    lsls r2, r2, #16
951; CHECK-V6M-NEXT:    orrs r0, r2
952; CHECK-V6M-NEXT:    pop {r4, pc}
953  %b.shifted = shl i64 %b, 16
954  %c.shifted = shl i64 %c, 32
955  %d.shifted = shl i64 %d, 48
956  %or.ad = or i64 %a, %d.shifted
957  %or.adb = or i64 %or.ad, %b.shifted
958  %or.adbc = or i64 %or.adb, %c.shifted
959  ret i64 %or.adbc
960}
961
962define i32 @or_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
963; CHECK-ARM-LABEL: or_tree_with_shifts_i32:
964; CHECK-ARM:       @ %bb.0:
965; CHECK-ARM-NEXT:    orr r2, r3, r2, lsl #16
966; CHECK-ARM-NEXT:    orr r0, r1, r0, lsl #16
967; CHECK-ARM-NEXT:    orr r0, r0, r2
968; CHECK-ARM-NEXT:    bx lr
969;
970; CHECK-BE-LABEL: or_tree_with_shifts_i32:
971; CHECK-BE:       @ %bb.0:
972; CHECK-BE-NEXT:    orr r2, r3, r2, lsl #16
973; CHECK-BE-NEXT:    orr r0, r1, r0, lsl #16
974; CHECK-BE-NEXT:    orr r0, r0, r2
975; CHECK-BE-NEXT:    bx lr
976;
977; CHECK-THUMB-LABEL: or_tree_with_shifts_i32:
978; CHECK-THUMB:       @ %bb.0:
979; CHECK-THUMB-NEXT:    orr.w r2, r3, r2, lsl #16
980; CHECK-THUMB-NEXT:    orr.w r0, r1, r0, lsl #16
981; CHECK-THUMB-NEXT:    orrs r0, r2
982; CHECK-THUMB-NEXT:    bx lr
983;
984; CHECK-ALIGN-LABEL: or_tree_with_shifts_i32:
985; CHECK-ALIGN:       @ %bb.0:
986; CHECK-ALIGN-NEXT:    orr.w r2, r3, r2, lsl #16
987; CHECK-ALIGN-NEXT:    orr.w r0, r1, r0, lsl #16
988; CHECK-ALIGN-NEXT:    orrs r0, r2
989; CHECK-ALIGN-NEXT:    bx lr
990;
991; CHECK-V6M-LABEL: or_tree_with_shifts_i32:
992; CHECK-V6M:       @ %bb.0:
993; CHECK-V6M-NEXT:    lsls r2, r2, #16
994; CHECK-V6M-NEXT:    orrs r2, r3
995; CHECK-V6M-NEXT:    lsls r0, r0, #16
996; CHECK-V6M-NEXT:    orrs r0, r1
997; CHECK-V6M-NEXT:    orrs r0, r2
998; CHECK-V6M-NEXT:    bx lr
999  %a.shifted = shl i32 %a, 16
1000  %c.shifted = shl i32 %c, 16
1001  %or.ab = or i32 %a.shifted, %b
1002  %or.cd = or i32 %c.shifted, %d
1003  %r = or i32 %or.ab, %or.cd
1004  ret i32 %r
1005}
1006
1007define i32 @xor_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
1008; CHECK-ARM-LABEL: xor_tree_with_shifts_i32:
1009; CHECK-ARM:       @ %bb.0:
1010; CHECK-ARM-NEXT:    eor r2, r3, r2, lsr #16
1011; CHECK-ARM-NEXT:    eor r0, r1, r0, lsr #16
1012; CHECK-ARM-NEXT:    eor r0, r0, r2
1013; CHECK-ARM-NEXT:    bx lr
1014;
1015; CHECK-BE-LABEL: xor_tree_with_shifts_i32:
1016; CHECK-BE:       @ %bb.0:
1017; CHECK-BE-NEXT:    eor r2, r3, r2, lsr #16
1018; CHECK-BE-NEXT:    eor r0, r1, r0, lsr #16
1019; CHECK-BE-NEXT:    eor r0, r0, r2
1020; CHECK-BE-NEXT:    bx lr
1021;
1022; CHECK-THUMB-LABEL: xor_tree_with_shifts_i32:
1023; CHECK-THUMB:       @ %bb.0:
1024; CHECK-THUMB-NEXT:    eor.w r2, r3, r2, lsr #16
1025; CHECK-THUMB-NEXT:    eor.w r0, r1, r0, lsr #16
1026; CHECK-THUMB-NEXT:    eors r0, r2
1027; CHECK-THUMB-NEXT:    bx lr
1028;
1029; CHECK-ALIGN-LABEL: xor_tree_with_shifts_i32:
1030; CHECK-ALIGN:       @ %bb.0:
1031; CHECK-ALIGN-NEXT:    eor.w r2, r3, r2, lsr #16
1032; CHECK-ALIGN-NEXT:    eor.w r0, r1, r0, lsr #16
1033; CHECK-ALIGN-NEXT:    eors r0, r2
1034; CHECK-ALIGN-NEXT:    bx lr
1035;
1036; CHECK-V6M-LABEL: xor_tree_with_shifts_i32:
1037; CHECK-V6M:       @ %bb.0:
1038; CHECK-V6M-NEXT:    lsrs r2, r2, #16
1039; CHECK-V6M-NEXT:    eors r2, r3
1040; CHECK-V6M-NEXT:    lsrs r0, r0, #16
1041; CHECK-V6M-NEXT:    eors r0, r1
1042; CHECK-V6M-NEXT:    eors r0, r2
1043; CHECK-V6M-NEXT:    bx lr
1044  %a.shifted = lshr i32 %a, 16
1045  %c.shifted = lshr i32 %c, 16
1046  %xor.ab = xor i32 %a.shifted, %b
1047  %xor.cd = xor i32 %c.shifted, %d
1048  %r = xor i32 %xor.ab, %xor.cd
1049  ret i32 %r
1050}
1051
1052define i32 @and_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
1053; CHECK-ARM-LABEL: and_tree_with_shifts_i32:
1054; CHECK-ARM:       @ %bb.0:
1055; CHECK-ARM-NEXT:    and r2, r3, r2, asr #16
1056; CHECK-ARM-NEXT:    and r0, r1, r0, asr #16
1057; CHECK-ARM-NEXT:    and r0, r0, r2
1058; CHECK-ARM-NEXT:    bx lr
1059;
1060; CHECK-BE-LABEL: and_tree_with_shifts_i32:
1061; CHECK-BE:       @ %bb.0:
1062; CHECK-BE-NEXT:    and r2, r3, r2, asr #16
1063; CHECK-BE-NEXT:    and r0, r1, r0, asr #16
1064; CHECK-BE-NEXT:    and r0, r0, r2
1065; CHECK-BE-NEXT:    bx lr
1066;
1067; CHECK-THUMB-LABEL: and_tree_with_shifts_i32:
1068; CHECK-THUMB:       @ %bb.0:
1069; CHECK-THUMB-NEXT:    and.w r2, r3, r2, asr #16
1070; CHECK-THUMB-NEXT:    and.w r0, r1, r0, asr #16
1071; CHECK-THUMB-NEXT:    ands r0, r2
1072; CHECK-THUMB-NEXT:    bx lr
1073;
1074; CHECK-ALIGN-LABEL: and_tree_with_shifts_i32:
1075; CHECK-ALIGN:       @ %bb.0:
1076; CHECK-ALIGN-NEXT:    and.w r2, r3, r2, asr #16
1077; CHECK-ALIGN-NEXT:    and.w r0, r1, r0, asr #16
1078; CHECK-ALIGN-NEXT:    ands r0, r2
1079; CHECK-ALIGN-NEXT:    bx lr
1080;
1081; CHECK-V6M-LABEL: and_tree_with_shifts_i32:
1082; CHECK-V6M:       @ %bb.0:
1083; CHECK-V6M-NEXT:    asrs r2, r2, #16
1084; CHECK-V6M-NEXT:    ands r2, r3
1085; CHECK-V6M-NEXT:    asrs r0, r0, #16
1086; CHECK-V6M-NEXT:    ands r0, r1
1087; CHECK-V6M-NEXT:    ands r0, r2
1088; CHECK-V6M-NEXT:    bx lr
1089  %a.shifted = ashr i32 %a, 16
1090  %c.shifted = ashr i32 %c, 16
1091  %and.ab = and i32 %a.shifted, %b
1092  %and.cd = and i32 %c.shifted, %d
1093  %r = and i32 %and.ab, %and.cd
1094  ret i32 %r
1095}
1096
1097define i32 @logic_tree_with_shifts_var_i32(i32 %a, i32 %b, i32 %c, i32 %d, i32 %s) {
1098; CHECK-ARM-LABEL: logic_tree_with_shifts_var_i32:
1099; CHECK-ARM:       @ %bb.0:
1100; CHECK-ARM-NEXT:    ldr r12, [sp]
1101; CHECK-ARM-NEXT:    orr r2, r3, r2, lsl r12
1102; CHECK-ARM-NEXT:    orr r0, r1, r0, lsl r12
1103; CHECK-ARM-NEXT:    orr r0, r0, r2
1104; CHECK-ARM-NEXT:    bx lr
1105;
1106; CHECK-BE-LABEL: logic_tree_with_shifts_var_i32:
1107; CHECK-BE:       @ %bb.0:
1108; CHECK-BE-NEXT:    ldr r12, [sp]
1109; CHECK-BE-NEXT:    orr r2, r3, r2, lsl r12
1110; CHECK-BE-NEXT:    orr r0, r1, r0, lsl r12
1111; CHECK-BE-NEXT:    orr r0, r0, r2
1112; CHECK-BE-NEXT:    bx lr
1113;
1114; CHECK-THUMB-LABEL: logic_tree_with_shifts_var_i32:
1115; CHECK-THUMB:       @ %bb.0:
1116; CHECK-THUMB-NEXT:    ldr.w r12, [sp]
1117; CHECK-THUMB-NEXT:    lsl.w r2, r2, r12
1118; CHECK-THUMB-NEXT:    lsl.w r0, r0, r12
1119; CHECK-THUMB-NEXT:    orrs r2, r3
1120; CHECK-THUMB-NEXT:    orrs r0, r1
1121; CHECK-THUMB-NEXT:    orrs r0, r2
1122; CHECK-THUMB-NEXT:    bx lr
1123;
1124; CHECK-ALIGN-LABEL: logic_tree_with_shifts_var_i32:
1125; CHECK-ALIGN:       @ %bb.0:
1126; CHECK-ALIGN-NEXT:    ldr.w r12, [sp]
1127; CHECK-ALIGN-NEXT:    lsl.w r2, r2, r12
1128; CHECK-ALIGN-NEXT:    lsl.w r0, r0, r12
1129; CHECK-ALIGN-NEXT:    orrs r2, r3
1130; CHECK-ALIGN-NEXT:    orrs r0, r1
1131; CHECK-ALIGN-NEXT:    orrs r0, r2
1132; CHECK-ALIGN-NEXT:    bx lr
1133;
1134; CHECK-V6M-LABEL: logic_tree_with_shifts_var_i32:
1135; CHECK-V6M:       @ %bb.0:
1136; CHECK-V6M-NEXT:    push {r4, lr}
1137; CHECK-V6M-NEXT:    ldr r4, [sp, #8]
1138; CHECK-V6M-NEXT:    lsls r2, r4
1139; CHECK-V6M-NEXT:    orrs r2, r3
1140; CHECK-V6M-NEXT:    lsls r0, r4
1141; CHECK-V6M-NEXT:    orrs r0, r1
1142; CHECK-V6M-NEXT:    orrs r0, r2
1143; CHECK-V6M-NEXT:    pop {r4, pc}
1144  %a.shifted = shl i32 %a, %s
1145  %c.shifted = shl i32 %c, %s
1146  %or.ab = or i32 %a.shifted, %b
1147  %or.cd = or i32 %c.shifted, %d
1148  %r = or i32 %or.ab, %or.cd
1149  ret i32 %r
1150}
1151
1152define i32 @logic_tree_with_mismatching_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
1153; CHECK-ARM-LABEL: logic_tree_with_mismatching_shifts_i32:
1154; CHECK-ARM:       @ %bb.0:
1155; CHECK-ARM-NEXT:    orr r2, r3, r2, lsl #16
1156; CHECK-ARM-NEXT:    orr r0, r1, r0, lsl #15
1157; CHECK-ARM-NEXT:    orr r0, r0, r2
1158; CHECK-ARM-NEXT:    bx lr
1159;
1160; CHECK-BE-LABEL: logic_tree_with_mismatching_shifts_i32:
1161; CHECK-BE:       @ %bb.0:
1162; CHECK-BE-NEXT:    orr r2, r3, r2, lsl #16
1163; CHECK-BE-NEXT:    orr r0, r1, r0, lsl #15
1164; CHECK-BE-NEXT:    orr r0, r0, r2
1165; CHECK-BE-NEXT:    bx lr
1166;
1167; CHECK-THUMB-LABEL: logic_tree_with_mismatching_shifts_i32:
1168; CHECK-THUMB:       @ %bb.0:
1169; CHECK-THUMB-NEXT:    orr.w r2, r3, r2, lsl #16
1170; CHECK-THUMB-NEXT:    orr.w r0, r1, r0, lsl #15
1171; CHECK-THUMB-NEXT:    orrs r0, r2
1172; CHECK-THUMB-NEXT:    bx lr
1173;
1174; CHECK-ALIGN-LABEL: logic_tree_with_mismatching_shifts_i32:
1175; CHECK-ALIGN:       @ %bb.0:
1176; CHECK-ALIGN-NEXT:    orr.w r2, r3, r2, lsl #16
1177; CHECK-ALIGN-NEXT:    orr.w r0, r1, r0, lsl #15
1178; CHECK-ALIGN-NEXT:    orrs r0, r2
1179; CHECK-ALIGN-NEXT:    bx lr
1180;
1181; CHECK-V6M-LABEL: logic_tree_with_mismatching_shifts_i32:
1182; CHECK-V6M:       @ %bb.0:
1183; CHECK-V6M-NEXT:    lsls r2, r2, #16
1184; CHECK-V6M-NEXT:    orrs r2, r3
1185; CHECK-V6M-NEXT:    lsls r0, r0, #15
1186; CHECK-V6M-NEXT:    orrs r0, r1
1187; CHECK-V6M-NEXT:    orrs r0, r2
1188; CHECK-V6M-NEXT:    bx lr
1189  %a.shifted = shl i32 %a, 15
1190  %c.shifted = shl i32 %c, 16
1191  %or.ab = or i32 %a.shifted, %b
1192  %or.cd = or i32 %c.shifted, %d
1193  %r = or i32 %or.ab, %or.cd
1194  ret i32 %r
1195}
1196
1197define i32 @logic_tree_with_mismatching_shifts2_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
1198; CHECK-ARM-LABEL: logic_tree_with_mismatching_shifts2_i32:
1199; CHECK-ARM:       @ %bb.0:
1200; CHECK-ARM-NEXT:    orr r2, r3, r2, lsr #16
1201; CHECK-ARM-NEXT:    orr r0, r1, r0, lsl #16
1202; CHECK-ARM-NEXT:    orr r0, r0, r2
1203; CHECK-ARM-NEXT:    bx lr
1204;
1205; CHECK-BE-LABEL: logic_tree_with_mismatching_shifts2_i32:
1206; CHECK-BE:       @ %bb.0:
1207; CHECK-BE-NEXT:    orr r2, r3, r2, lsr #16
1208; CHECK-BE-NEXT:    orr r0, r1, r0, lsl #16
1209; CHECK-BE-NEXT:    orr r0, r0, r2
1210; CHECK-BE-NEXT:    bx lr
1211;
1212; CHECK-THUMB-LABEL: logic_tree_with_mismatching_shifts2_i32:
1213; CHECK-THUMB:       @ %bb.0:
1214; CHECK-THUMB-NEXT:    orr.w r2, r3, r2, lsr #16
1215; CHECK-THUMB-NEXT:    orr.w r0, r1, r0, lsl #16
1216; CHECK-THUMB-NEXT:    orrs r0, r2
1217; CHECK-THUMB-NEXT:    bx lr
1218;
1219; CHECK-ALIGN-LABEL: logic_tree_with_mismatching_shifts2_i32:
1220; CHECK-ALIGN:       @ %bb.0:
1221; CHECK-ALIGN-NEXT:    orr.w r2, r3, r2, lsr #16
1222; CHECK-ALIGN-NEXT:    orr.w r0, r1, r0, lsl #16
1223; CHECK-ALIGN-NEXT:    orrs r0, r2
1224; CHECK-ALIGN-NEXT:    bx lr
1225;
1226; CHECK-V6M-LABEL: logic_tree_with_mismatching_shifts2_i32:
1227; CHECK-V6M:       @ %bb.0:
1228; CHECK-V6M-NEXT:    lsrs r2, r2, #16
1229; CHECK-V6M-NEXT:    orrs r2, r3
1230; CHECK-V6M-NEXT:    lsls r0, r0, #16
1231; CHECK-V6M-NEXT:    orrs r0, r1
1232; CHECK-V6M-NEXT:    orrs r0, r2
1233; CHECK-V6M-NEXT:    bx lr
1234  %a.shifted = shl i32 %a, 16
1235  %c.shifted = lshr i32 %c, 16
1236  %or.ab = or i32 %a.shifted, %b
1237  %or.cd = or i32 %c.shifted, %d
1238  %r = or i32 %or.ab, %or.cd
1239  ret i32 %r
1240}
1241
1242define <4 x i32> @or_tree_with_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {
1243; CHECK-ARM-LABEL: or_tree_with_shifts_vec_i32:
1244; CHECK-ARM:       @ %bb.0:
1245; CHECK-ARM-NEXT:    vshl.i32 q8, q2, #16
1246; CHECK-ARM-NEXT:    vshl.i32 q9, q0, #16
1247; CHECK-ARM-NEXT:    vorr q8, q8, q3
1248; CHECK-ARM-NEXT:    vorr q9, q9, q1
1249; CHECK-ARM-NEXT:    vorr q0, q9, q8
1250; CHECK-ARM-NEXT:    bx lr
1251;
1252; CHECK-BE-LABEL: or_tree_with_shifts_vec_i32:
1253; CHECK-BE:       @ %bb.0:
1254; CHECK-BE-NEXT:    vrev64.32 q8, q2
1255; CHECK-BE-NEXT:    vrev64.32 q9, q0
1256; CHECK-BE-NEXT:    vshl.i32 q8, q8, #16
1257; CHECK-BE-NEXT:    vrev64.32 q10, q3
1258; CHECK-BE-NEXT:    vshl.i32 q9, q9, #16
1259; CHECK-BE-NEXT:    vrev64.32 q11, q1
1260; CHECK-BE-NEXT:    vorr q8, q8, q10
1261; CHECK-BE-NEXT:    vorr q9, q9, q11
1262; CHECK-BE-NEXT:    vorr q8, q9, q8
1263; CHECK-BE-NEXT:    vrev64.32 q0, q8
1264; CHECK-BE-NEXT:    bx lr
1265  %a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
1266  %c.shifted = shl <4 x i32> %c, <i32 16, i32 16, i32 16, i32 16>
1267  %or.ab = or <4 x i32> %a.shifted, %b
1268  %or.cd = or <4 x i32> %c.shifted, %d
1269  %r = or <4 x i32> %or.ab, %or.cd
1270  ret <4 x i32> %r
1271}
1272
1273define <4 x i32> @or_tree_with_mismatching_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {
1274; CHECK-ARM-LABEL: or_tree_with_mismatching_shifts_vec_i32:
1275; CHECK-ARM:       @ %bb.0:
1276; CHECK-ARM-NEXT:    vshl.i32 q8, q2, #17
1277; CHECK-ARM-NEXT:    vshl.i32 q9, q0, #16
1278; CHECK-ARM-NEXT:    vorr q8, q8, q3
1279; CHECK-ARM-NEXT:    vorr q9, q9, q1
1280; CHECK-ARM-NEXT:    vorr q0, q9, q8
1281; CHECK-ARM-NEXT:    bx lr
1282;
1283; CHECK-BE-LABEL: or_tree_with_mismatching_shifts_vec_i32:
1284; CHECK-BE:       @ %bb.0:
1285; CHECK-BE-NEXT:    vrev64.32 q8, q2
1286; CHECK-BE-NEXT:    vrev64.32 q9, q0
1287; CHECK-BE-NEXT:    vshl.i32 q8, q8, #17
1288; CHECK-BE-NEXT:    vrev64.32 q10, q3
1289; CHECK-BE-NEXT:    vshl.i32 q9, q9, #16
1290; CHECK-BE-NEXT:    vrev64.32 q11, q1
1291; CHECK-BE-NEXT:    vorr q8, q8, q10
1292; CHECK-BE-NEXT:    vorr q9, q9, q11
1293; CHECK-BE-NEXT:    vorr q8, q9, q8
1294; CHECK-BE-NEXT:    vrev64.32 q0, q8
1295; CHECK-BE-NEXT:    bx lr
1296  %a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
1297  %c.shifted = shl <4 x i32> %c, <i32 17, i32 17, i32 17, i32 17>
1298  %or.ab = or <4 x i32> %a.shifted, %b
1299  %or.cd = or <4 x i32> %c.shifted, %d
1300  %r = or <4 x i32> %or.ab, %or.cd
1301  ret <4 x i32> %r
1302}
1303