xref: /llvm-project/llvm/test/CodeGen/ARM/and-cmp0-sink.ll (revision 4997af98a008e71a3df61707559710d1c2769839)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=thumbv7m-eabi  %s -o - | FileCheck %s --check-prefix V7M
3; RUN: llc -mtriple=armv7a-eabi  %s -o -   | FileCheck %s --check-prefix V7A
4; RUN: llc -mtriple=thumbv7a-eabi  %s -o -   | FileCheck %s --check-prefix V7A-T
5; RUN: llc -mtriple=armv6m-eabi  %s -o -   | FileCheck %s --check-prefix V6M
6
7target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
8
9; Test sink of `and` instructions to fold in to `tst`, `lsls`, do cmov-bfi combine, etc.
10define void @f(i32 %v, ptr noalias  %outp) {
11; V7M-LABEL: f:
12; V7M:       @ %bb.0: @ %entry
13; V7M-NEXT:    movs r2, #0
14; V7M-NEXT:    str r2, [r1]
15; V7M-NEXT:    lsls r2, r0, #31
16; V7M-NEXT:    bne .LBB0_3
17; V7M-NEXT:  @ %bb.1: @ %if.then
18; V7M-NEXT:    tst.w r0, #14
19; V7M-NEXT:    beq .LBB0_6
20; V7M-NEXT:  @ %bb.2:
21; V7M-NEXT:    lsls r2, r0, #30
22; V7M-NEXT:    mov.w r3, #33024
23; V7M-NEXT:    and.w r2, r3, r2, asr #31
24; V7M-NEXT:    lsrs r0, r0, #2
25; V7M-NEXT:    bfi r2, r0, #7, #1
26; V7M-NEXT:    bfi r2, r0, #14, #1
27; V7M-NEXT:    b .LBB0_5
28; V7M-NEXT:  .LBB0_3: @ %if.else
29; V7M-NEXT:    tst.w r0, #14
30; V7M-NEXT:    it eq
31; V7M-NEXT:    bxeq lr
32; V7M-NEXT:  .LBB0_4:
33; V7M-NEXT:    lsls r2, r0, #30
34; V7M-NEXT:    mov.w r3, #8256
35; V7M-NEXT:    and.w r2, r3, r2, asr #31
36; V7M-NEXT:    lsrs r0, r0, #2
37; V7M-NEXT:    bfi r2, r0, #5, #1
38; V7M-NEXT:    bfi r2, r0, #12, #1
39; V7M-NEXT:  .LBB0_5: @ %if.end
40; V7M-NEXT:    str r2, [r1]
41; V7M-NEXT:  .LBB0_6: @ %exit
42; V7M-NEXT:    bx lr
43;
44; V7A-LABEL: f:
45; V7A:       @ %bb.0: @ %entry
46; V7A-NEXT:    mov r2, #0
47; V7A-NEXT:    tst r0, #1
48; V7A-NEXT:    str r2, [r1]
49; V7A-NEXT:    bne .LBB0_3
50; V7A-NEXT:  @ %bb.1: @ %if.then
51; V7A-NEXT:    tst r0, #14
52; V7A-NEXT:    beq .LBB0_6
53; V7A-NEXT:  @ %bb.2:
54; V7A-NEXT:    lsl r2, r0, #30
55; V7A-NEXT:    mov r3, #33024
56; V7A-NEXT:    and r2, r3, r2, asr #31
57; V7A-NEXT:    lsr r0, r0, #2
58; V7A-NEXT:    bfi r2, r0, #7, #1
59; V7A-NEXT:    bfi r2, r0, #14, #1
60; V7A-NEXT:    b .LBB0_5
61; V7A-NEXT:  .LBB0_3: @ %if.else
62; V7A-NEXT:    tst r0, #14
63; V7A-NEXT:    bxeq lr
64; V7A-NEXT:  .LBB0_4:
65; V7A-NEXT:    lsl r2, r0, #30
66; V7A-NEXT:    mov r3, #8256
67; V7A-NEXT:    and r2, r3, r2, asr #31
68; V7A-NEXT:    lsr r0, r0, #2
69; V7A-NEXT:    bfi r2, r0, #5, #1
70; V7A-NEXT:    bfi r2, r0, #12, #1
71; V7A-NEXT:  .LBB0_5: @ %if.end
72; V7A-NEXT:    str r2, [r1]
73; V7A-NEXT:  .LBB0_6: @ %exit
74; V7A-NEXT:    bx lr
75;
76; V7A-T-LABEL: f:
77; V7A-T:       @ %bb.0: @ %entry
78; V7A-T-NEXT:    movs r2, #0
79; V7A-T-NEXT:    str r2, [r1]
80; V7A-T-NEXT:    lsls r2, r0, #31
81; V7A-T-NEXT:    bne .LBB0_3
82; V7A-T-NEXT:  @ %bb.1: @ %if.then
83; V7A-T-NEXT:    tst.w r0, #14
84; V7A-T-NEXT:    beq .LBB0_6
85; V7A-T-NEXT:  @ %bb.2:
86; V7A-T-NEXT:    lsls r2, r0, #30
87; V7A-T-NEXT:    mov.w r3, #33024
88; V7A-T-NEXT:    and.w r2, r3, r2, asr #31
89; V7A-T-NEXT:    lsrs r0, r0, #2
90; V7A-T-NEXT:    bfi r2, r0, #7, #1
91; V7A-T-NEXT:    bfi r2, r0, #14, #1
92; V7A-T-NEXT:    b .LBB0_5
93; V7A-T-NEXT:  .LBB0_3: @ %if.else
94; V7A-T-NEXT:    tst.w r0, #14
95; V7A-T-NEXT:    it eq
96; V7A-T-NEXT:    bxeq lr
97; V7A-T-NEXT:  .LBB0_4:
98; V7A-T-NEXT:    lsls r2, r0, #30
99; V7A-T-NEXT:    mov.w r3, #8256
100; V7A-T-NEXT:    and.w r2, r3, r2, asr #31
101; V7A-T-NEXT:    lsrs r0, r0, #2
102; V7A-T-NEXT:    bfi r2, r0, #5, #1
103; V7A-T-NEXT:    bfi r2, r0, #12, #1
104; V7A-T-NEXT:  .LBB0_5: @ %if.end
105; V7A-T-NEXT:    str r2, [r1]
106; V7A-T-NEXT:  .LBB0_6: @ %exit
107; V7A-T-NEXT:    bx lr
108;
109; V6M-LABEL: f:
110; V6M:       @ %bb.0: @ %entry
111; V6M-NEXT:    .save {r4, lr}
112; V6M-NEXT:    push {r4, lr}
113; V6M-NEXT:    movs r2, #0
114; V6M-NEXT:    str r2, [r1]
115; V6M-NEXT:    movs r3, #14
116; V6M-NEXT:    ands r3, r0
117; V6M-NEXT:    movs r4, #4
118; V6M-NEXT:    ands r4, r0
119; V6M-NEXT:    movs r2, #2
120; V6M-NEXT:    ands r2, r0
121; V6M-NEXT:    lsls r0, r0, #31
122; V6M-NEXT:    bne .LBB0_5
123; V6M-NEXT:  @ %bb.1: @ %if.then
124; V6M-NEXT:    movs r0, #129
125; V6M-NEXT:    cmp r2, #0
126; V6M-NEXT:    beq .LBB0_3
127; V6M-NEXT:  @ %bb.2:
128; V6M-NEXT:    lsls r2, r0, #8
129; V6M-NEXT:  .LBB0_3: @ %if.then
130; V6M-NEXT:    cmp r4, #0
131; V6M-NEXT:    beq .LBB0_10
132; V6M-NEXT:  @ %bb.4: @ %if.then
133; V6M-NEXT:    lsls r0, r0, #7
134; V6M-NEXT:    b .LBB0_9
135; V6M-NEXT:  .LBB0_5: @ %if.else
136; V6M-NEXT:    movs r0, #129
137; V6M-NEXT:    cmp r2, #0
138; V6M-NEXT:    beq .LBB0_7
139; V6M-NEXT:  @ %bb.6:
140; V6M-NEXT:    lsls r2, r0, #6
141; V6M-NEXT:  .LBB0_7: @ %if.else
142; V6M-NEXT:    cmp r4, #0
143; V6M-NEXT:    beq .LBB0_10
144; V6M-NEXT:  @ %bb.8: @ %if.else
145; V6M-NEXT:    lsls r0, r0, #5
146; V6M-NEXT:  .LBB0_9: @ %if.else
147; V6M-NEXT:    adds r2, r2, r0
148; V6M-NEXT:  .LBB0_10: @ %if.else
149; V6M-NEXT:    cmp r3, #0
150; V6M-NEXT:    beq .LBB0_12
151; V6M-NEXT:  @ %bb.11: @ %if.end
152; V6M-NEXT:    str r2, [r1]
153; V6M-NEXT:  .LBB0_12: @ %exit
154; V6M-NEXT:    pop {r4, pc}
155entry:
156  store i32 0, ptr %outp, align 4
157  %and = and i32 %v, 1
158  %cmp = icmp eq i32 %and, 0
159  %and1 = and i32 %v, 2
160  %tobool.not = icmp eq i32 %and1, 0
161  %and2 = and i32 %v, 4
162  %tobool1.not = icmp eq i32 %and2, 0
163  %and3 = and i32 %v, 14
164  %tobool2.not = icmp eq i32 %and3, 0
165  br i1 %cmp, label %if.then, label %if.else
166
167if.then:
168  %select = select i1 %tobool.not, i32 0, i32 33024
169  %or = or i32 %select, 16512
170  %spec.select = select i1 %tobool1.not, i32 %select, i32 %or
171  br i1 %tobool2.not, label %exit, label %if.end
172
173if.else:
174  %select1 = select i1 %tobool.not, i32 0, i32 8256
175  %or1 = or i32 %select1, 4128
176  %spec.select1 = select i1 %tobool1.not, i32 %select1, i32 %or1
177  br i1 %tobool2.not, label %exit, label %if.end
178
179if.end:
180  %spec.select.sink = phi i32 [ %spec.select, %if.then ], [ %spec.select1, %if.else ]
181  store i32 %spec.select.sink, ptr %outp, align 4
182  br label %exit
183
184exit:
185  ret void
186}
187
188; Test with a mask that can be encoded with T32 instruction set, but not with A32.
189define i32 @f0(i1 %c0, i32 %v, ptr %p) {
190; V7M-LABEL: f0:
191; V7M:       @ %bb.0: @ %E
192; V7M-NEXT:    lsls r0, r0, #31
193; V7M-NEXT:    beq .LBB1_2
194; V7M-NEXT:  @ %bb.1: @ %A
195; V7M-NEXT:    tst.w r1, #16843009
196; V7M-NEXT:    itt eq
197; V7M-NEXT:    moveq r0, #0
198; V7M-NEXT:    bxeq lr
199; V7M-NEXT:    b .LBB1_3
200; V7M-NEXT:  .LBB1_2: @ %B
201; V7M-NEXT:    movs r0, #1
202; V7M-NEXT:    tst.w r1, #16843009
203; V7M-NEXT:    str r0, [r2]
204; V7M-NEXT:    itt ne
205; V7M-NEXT:    movne r0, #0
206; V7M-NEXT:    bxne lr
207; V7M-NEXT:  .LBB1_3: @ %D
208; V7M-NEXT:    movs r0, #1
209; V7M-NEXT:    bx lr
210;
211; V7A-LABEL: f0:
212; V7A:       @ %bb.0: @ %E
213; V7A-NEXT:    movw r3, #257
214; V7A-NEXT:    tst r0, #1
215; V7A-NEXT:    movt r3, #257
216; V7A-NEXT:    and r1, r1, r3
217; V7A-NEXT:    beq .LBB1_3
218; V7A-NEXT:  @ %bb.1: @ %A
219; V7A-NEXT:    cmp r1, #0
220; V7A-NEXT:    moveq r0, #0
221; V7A-NEXT:    bxeq lr
222; V7A-NEXT:  .LBB1_2: @ %D
223; V7A-NEXT:    mov r0, #1
224; V7A-NEXT:    bx lr
225; V7A-NEXT:  .LBB1_3: @ %B
226; V7A-NEXT:    mov r0, #1
227; V7A-NEXT:    cmp r1, #0
228; V7A-NEXT:    str r0, [r2]
229; V7A-NEXT:    mov r0, #0
230; V7A-NEXT:    moveq r0, #1
231; V7A-NEXT:    bx lr
232;
233; V7A-T-LABEL: f0:
234; V7A-T:       @ %bb.0: @ %E
235; V7A-T-NEXT:    lsls r0, r0, #31
236; V7A-T-NEXT:    beq .LBB1_2
237; V7A-T-NEXT:  @ %bb.1: @ %A
238; V7A-T-NEXT:    tst.w r1, #16843009
239; V7A-T-NEXT:    itt eq
240; V7A-T-NEXT:    moveq r0, #0
241; V7A-T-NEXT:    bxeq lr
242; V7A-T-NEXT:    b .LBB1_3
243; V7A-T-NEXT:  .LBB1_2: @ %B
244; V7A-T-NEXT:    movs r0, #1
245; V7A-T-NEXT:    tst.w r1, #16843009
246; V7A-T-NEXT:    str r0, [r2]
247; V7A-T-NEXT:    itt ne
248; V7A-T-NEXT:    movne r0, #0
249; V7A-T-NEXT:    bxne lr
250; V7A-T-NEXT:  .LBB1_3: @ %D
251; V7A-T-NEXT:    movs r0, #1
252; V7A-T-NEXT:    bx lr
253;
254; V6M-LABEL: f0:
255; V6M:       @ %bb.0: @ %E
256; V6M-NEXT:    ldr r3, .LCPI1_0
257; V6M-NEXT:    ands r3, r1
258; V6M-NEXT:    lsls r0, r0, #31
259; V6M-NEXT:    beq .LBB1_3
260; V6M-NEXT:  @ %bb.1: @ %A
261; V6M-NEXT:    cmp r3, #0
262; V6M-NEXT:    bne .LBB1_5
263; V6M-NEXT:  @ %bb.2:
264; V6M-NEXT:    movs r0, #0
265; V6M-NEXT:    bx lr
266; V6M-NEXT:  .LBB1_3: @ %B
267; V6M-NEXT:    movs r0, #1
268; V6M-NEXT:    str r0, [r2]
269; V6M-NEXT:    cmp r3, #0
270; V6M-NEXT:    beq .LBB1_5
271; V6M-NEXT:  @ %bb.4:
272; V6M-NEXT:    movs r0, #0
273; V6M-NEXT:    bx lr
274; V6M-NEXT:  .LBB1_5: @ %D
275; V6M-NEXT:    movs r0, #1
276; V6M-NEXT:    bx lr
277; V6M-NEXT:    .p2align 2
278; V6M-NEXT:  @ %bb.6:
279; V6M-NEXT:  .LCPI1_0:
280; V6M-NEXT:    .long 16843009 @ 0x1010101
281E:
282  %a = and i32 %v, 16843009
283  br i1 %c0, label %A, label %B
284
285A:
286  %c1 = icmp eq i32 %a, 0
287  br i1 %c1, label %C, label %D
288
289B:
290  %c2 = icmp eq i32 %a, 0
291  store i32 1, ptr %p, align 4
292  br i1 %c2, label %D, label %C
293
294C:
295  br label %X
296
297D:
298  br label %X
299
300X:
301  %x = phi i32 [0, %C], [1, %D]
302  ret i32 %x
303}
304
305; Test with a mask that can be encoded both with T32 and A32 instruction sets.
306define i32 @f1(i1 %c0, i32 %v, ptr %p) {
307; V7M-LABEL: f1:
308; V7M:       @ %bb.0: @ %E
309; V7M-NEXT:    lsls r0, r0, #31
310; V7M-NEXT:    beq .LBB2_2
311; V7M-NEXT:  @ %bb.1: @ %A
312; V7M-NEXT:    tst.w r1, #100663296
313; V7M-NEXT:    itt eq
314; V7M-NEXT:    moveq r0, #0
315; V7M-NEXT:    bxeq lr
316; V7M-NEXT:    b .LBB2_3
317; V7M-NEXT:  .LBB2_2: @ %B
318; V7M-NEXT:    movs r0, #1
319; V7M-NEXT:    tst.w r1, #100663296
320; V7M-NEXT:    str r0, [r2]
321; V7M-NEXT:    itt ne
322; V7M-NEXT:    movne r0, #0
323; V7M-NEXT:    bxne lr
324; V7M-NEXT:  .LBB2_3: @ %D
325; V7M-NEXT:    movs r0, #1
326; V7M-NEXT:    bx lr
327;
328; V7A-LABEL: f1:
329; V7A:       @ %bb.0: @ %E
330; V7A-NEXT:    tst r0, #1
331; V7A-NEXT:    beq .LBB2_3
332; V7A-NEXT:  @ %bb.1: @ %A
333; V7A-NEXT:    tst r1, #100663296
334; V7A-NEXT:    moveq r0, #0
335; V7A-NEXT:    bxeq lr
336; V7A-NEXT:  .LBB2_2: @ %D
337; V7A-NEXT:    mov r0, #1
338; V7A-NEXT:    bx lr
339; V7A-NEXT:  .LBB2_3: @ %B
340; V7A-NEXT:    mov r0, #1
341; V7A-NEXT:    tst r1, #100663296
342; V7A-NEXT:    str r0, [r2]
343; V7A-NEXT:    mov r0, #0
344; V7A-NEXT:    moveq r0, #1
345; V7A-NEXT:    bx lr
346;
347; V7A-T-LABEL: f1:
348; V7A-T:       @ %bb.0: @ %E
349; V7A-T-NEXT:    lsls r0, r0, #31
350; V7A-T-NEXT:    beq .LBB2_2
351; V7A-T-NEXT:  @ %bb.1: @ %A
352; V7A-T-NEXT:    tst.w r1, #100663296
353; V7A-T-NEXT:    itt eq
354; V7A-T-NEXT:    moveq r0, #0
355; V7A-T-NEXT:    bxeq lr
356; V7A-T-NEXT:    b .LBB2_3
357; V7A-T-NEXT:  .LBB2_2: @ %B
358; V7A-T-NEXT:    movs r0, #1
359; V7A-T-NEXT:    tst.w r1, #100663296
360; V7A-T-NEXT:    str r0, [r2]
361; V7A-T-NEXT:    itt ne
362; V7A-T-NEXT:    movne r0, #0
363; V7A-T-NEXT:    bxne lr
364; V7A-T-NEXT:  .LBB2_3: @ %D
365; V7A-T-NEXT:    movs r0, #1
366; V7A-T-NEXT:    bx lr
367;
368; V6M-LABEL: f1:
369; V6M:       @ %bb.0: @ %E
370; V6M-NEXT:    movs r3, #3
371; V6M-NEXT:    lsls r3, r3, #25
372; V6M-NEXT:    ands r3, r1
373; V6M-NEXT:    lsls r0, r0, #31
374; V6M-NEXT:    beq .LBB2_3
375; V6M-NEXT:  @ %bb.1: @ %A
376; V6M-NEXT:    cmp r3, #0
377; V6M-NEXT:    bne .LBB2_5
378; V6M-NEXT:  @ %bb.2:
379; V6M-NEXT:    movs r0, #0
380; V6M-NEXT:    bx lr
381; V6M-NEXT:  .LBB2_3: @ %B
382; V6M-NEXT:    movs r0, #1
383; V6M-NEXT:    str r0, [r2]
384; V6M-NEXT:    cmp r3, #0
385; V6M-NEXT:    beq .LBB2_5
386; V6M-NEXT:  @ %bb.4:
387; V6M-NEXT:    movs r0, #0
388; V6M-NEXT:    bx lr
389; V6M-NEXT:  .LBB2_5: @ %D
390; V6M-NEXT:    movs r0, #1
391; V6M-NEXT:    bx lr
392E:
393  %a = and i32 %v, 100663296
394  br i1 %c0, label %A, label %B
395
396A:
397  %c1 = icmp eq i32 %a, 0
398  br i1 %c1, label %C, label %D
399
400B:
401  %c2 = icmp eq i32 %a, 0
402  store i32 1, ptr %p, align 4
403  br i1 %c2, label %D, label %C
404
405C:
406  br label %X
407
408D:
409  br label %X
410
411X:
412  %x = phi i32 [0, %C], [1, %D]
413  ret i32 %x
414}
415