xref: /llvm-project/llvm/test/CodeGen/ARM/bfi.ll (revision e0ed0333f0fed2e73f805afd58b61176a87aa3ad)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm -mattr=+v6t2 | FileCheck %s
3
4%struct.F = type { [3 x i8], i8 }
5
6@X = common global %struct.F zeroinitializer, align 4 ; <ptr> [#uses=1]
7
8define void @f1([1 x i32] %f.coerce0) nounwind {
9; CHECK-LABEL: f1:
10; CHECK:       @ %bb.0: @ %entry
11; CHECK-NEXT:    movw r0, :lower16:X
12; CHECK-NEXT:    mov r2, #10
13; CHECK-NEXT:    movt r0, :upper16:X
14; CHECK-NEXT:    ldr r1, [r0]
15; CHECK-NEXT:    bfi r1, r2, #22, #4
16; CHECK-NEXT:    str r1, [r0]
17; CHECK-NEXT:    bx lr
18entry:
19  %0 = load i32, ptr @X, align 4 ; <i32> [#uses=1]
20  %1 = and i32 %0, -62914561                      ; <i32> [#uses=1]
21  %2 = or i32 %1, 41943040                        ; <i32> [#uses=1]
22  store i32 %2, ptr @X, align 4
23  ret void
24}
25
26define i32 @f2(i32 %A, i32 %B) nounwind {
27; CHECK-LABEL: f2:
28; CHECK:       @ %bb.0: @ %entry
29; CHECK-NEXT:    lsr r1, r1, #7
30; CHECK-NEXT:    bfi r0, r1, #7, #16
31; CHECK-NEXT:    bx lr
32entry:
33  %and = and i32 %A, -8388481                     ; <i32> [#uses=1]
34  %and2 = and i32 %B, 8388480                     ; <i32> [#uses=1]
35  %or = or i32 %and2, %and                        ; <i32> [#uses=1]
36  ret i32 %or
37}
38
39define i32 @f3(i32 %A, i32 %B) nounwind {
40; CHECK-LABEL: f3:
41; CHECK:       @ %bb.0: @ %entry
42; CHECK-NEXT:    lsr r0, r0, #7
43; CHECK-NEXT:    bfi r1, r0, #7, #16
44; CHECK-NEXT:    mov r0, r1
45; CHECK-NEXT:    bx lr
46entry:
47  %and = and i32 %A, 8388480                      ; <i32> [#uses=1]
48  %and2 = and i32 %B, -8388481                    ; <i32> [#uses=1]
49  %or = or i32 %and2, %and                        ; <i32> [#uses=1]
50  ret i32 %or
51}
52
53; rdar://8752056
54define i32 @f4(i32 %a) nounwind {
55; CHECK-LABEL: f4:
56; CHECK:       @ %bb.0:
57; CHECK-NEXT:    movw r1, #3137
58; CHECK-NEXT:    bfi r1, r0, #15, #5
59; CHECK-NEXT:    mov r0, r1
60; CHECK-NEXT:    bx lr
61  %1 = shl i32 %a, 15
62  %ins7 = and i32 %1, 1015808
63  %ins12 = or i32 %ins7, 3137
64  ret i32 %ins12
65}
66
67; rdar://8458663
68define i32 @f5(i32 %a, i32 %b) nounwind {
69; CHECK-LABEL: f5:
70; CHECK:       @ %bb.0: @ %entry
71; CHECK-NEXT:    bfi r0, r1, #20, #4
72; CHECK-NEXT:    bx lr
73entry:
74  %0 = and i32 %a, -15728641
75  %1 = shl i32 %b, 20
76  %2 = and i32 %1, 15728640
77  %3 = or i32 %2, %0
78  ret i32 %3
79}
80
81; rdar://9609030
82define i32 @f6(i32 %a, i32 %b) nounwind readnone {
83; CHECK-LABEL: f6:
84; CHECK:       @ %bb.0: @ %entry
85; CHECK-NEXT:    bfi r0, r1, #8, #9
86; CHECK-NEXT:    bx lr
87entry:
88  %and = and i32 %a, -130817
89  %and2 = shl i32 %b, 8
90  %shl = and i32 %and2, 130816
91  %or = or i32 %shl, %and
92  ret i32 %or
93}
94
95define i32 @f7(i32 %x, i32 %y) {
96; CHECK-LABEL: f7:
97; CHECK:       @ %bb.0:
98; CHECK-NEXT:    lsr r2, r0, #2
99; CHECK-NEXT:    bic r0, r1, #255
100; CHECK-NEXT:    bfi r0, r2, #4, #1
101; CHECK-NEXT:    bx lr
102  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
103  %and = and i32 %x, 4
104  %or = or i32 %y2, 16
105  %cmp = icmp ne i32 %and, 0
106  %sel = select i1 %cmp, i32 %or, i32 %y2
107  ret i32 %sel
108}
109
110define i32 @f8(i32 %x, i32 %y) {
111; CHECK-LABEL: f8:
112; CHECK:       @ %bb.0:
113; CHECK-NEXT:    lsr r2, r0, #2
114; CHECK-NEXT:    bic r0, r1, #255
115; CHECK-NEXT:    bfi r0, r2, #4, #1
116; CHECK-NEXT:    bfi r0, r2, #5, #1
117; CHECK-NEXT:    bx lr
118  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
119  %and = and i32 %x, 4
120  %or = or i32 %y2, 48
121  %cmp = icmp ne i32 %and, 0
122  %sel = select i1 %cmp, i32 %or, i32 %y2
123  ret i32 %sel
124}
125
126define i32 @f9(i32 %x, i32 %y) {
127; CHECK-LABEL: f9:
128; CHECK:       @ %bb.0:
129; CHECK-NEXT:    bic r1, r1, #255
130; CHECK-NEXT:    tst r0, #4
131; CHECK-NEXT:    orreq r1, r1, #48
132; CHECK-NEXT:    mov r0, r1
133; CHECK-NEXT:    bx lr
134  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
135  %and = and i32 %x, 4
136  %or = or i32 %y2, 48
137  %cmp = icmp ne i32 %and, 0
138  %sel = select i1 %cmp, i32 %y2, i32 %or
139  ret i32 %sel
140}
141
142define i32 @f10(i32 %x, i32 %y) {
143; CHECK-LABEL: f10:
144; CHECK:       @ %bb.0:
145; CHECK-NEXT:    lsr r2, r0, #1
146; CHECK-NEXT:    bic r0, r1, #255
147; CHECK-NEXT:    bfi r0, r2, #4, #2
148; CHECK-NEXT:    bx lr
149  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
150  %and = and i32 %x, 4
151  %or = or i32 %y2, 32
152  %cmp = icmp ne i32 %and, 0
153  %sel = select i1 %cmp, i32 %or, i32 %y2
154
155  %aand = and i32 %x, 2
156  %aor = or i32 %sel, 16
157  %acmp = icmp ne i32 %aand, 0
158  %asel = select i1 %acmp, i32 %aor, i32 %sel
159
160  ret i32 %asel
161}
162
163define i32 @f11(i32 %x, i32 %y) {
164; CHECK-LABEL: f11:
165; CHECK:       @ %bb.0:
166; CHECK-NEXT:    lsr r2, r0, #1
167; CHECK-NEXT:    bic r0, r1, #255
168; CHECK-NEXT:    bfi r0, r2, #4, #3
169; CHECK-NEXT:    bx lr
170  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
171  %and = and i32 %x, 4
172  %or = or i32 %y2, 32
173  %cmp = icmp ne i32 %and, 0
174  %sel = select i1 %cmp, i32 %or, i32 %y2
175
176  %aand = and i32 %x, 2
177  %aor = or i32 %sel, 16
178  %acmp = icmp ne i32 %aand, 0
179  %asel = select i1 %acmp, i32 %aor, i32 %sel
180
181  %band = and i32 %x, 8
182  %bor = or i32 %asel, 64
183  %bcmp = icmp ne i32 %band, 0
184  %bsel = select i1 %bcmp, i32 %bor, i32 %asel
185
186  ret i32 %bsel
187}
188
189define i32 @f12(i32 %x, i32 %y) {
190; CHECK-LABEL: f12:
191; CHECK:       @ %bb.0:
192; CHECK-NEXT:    lsr r2, r0, #2
193; CHECK-NEXT:    bic r0, r1, #255
194; CHECK-NEXT:    bfi r0, r2, #4, #1
195; CHECK-NEXT:    bx lr
196  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
197  %and = and i32 %x, 4
198  %or = or i32 %y2, 16
199  %cmp = icmp eq i32 %and, 0
200  %sel = select i1 %cmp, i32 %y2, i32 %or
201  ret i32 %sel
202}
203
204define i32 @f13(i32 %x, i32 %y) {
205; CHECK-LABEL: f13:
206; CHECK:       @ %bb.0:
207; CHECK-NEXT:    and r0, r0, #4
208; CHECK-NEXT:    bic r1, r1, #255
209; CHECK-NEXT:    cmp r0, #42
210; CHECK-NEXT:    orrne r1, r1, #16
211; CHECK-NEXT:    mov r0, r1
212; CHECK-NEXT:    bx lr
213  %y2 = and i32 %y, 4294967040 ; 0xFFFFFF00
214  %and = and i32 %x, 4
215  %or = or i32 %y2, 16
216  %cmp = icmp eq i32 %and, 42 ; Not comparing against zero!
217  %sel = select i1 %cmp, i32 %y2, i32 %or
218  ret i32 %sel
219}
220
221define i32 @bfi1(i32 %a, i32 %b) {
222; CHECK-LABEL: bfi1:
223; CHECK:       @ %bb.0:
224; CHECK-NEXT:    and r2, r0, #1
225; CHECK-NEXT:    bic r1, r1, #19
226; CHECK-NEXT:    orr r1, r1, r2
227; CHECK-NEXT:    and r2, r0, #16
228; CHECK-NEXT:    orr r1, r1, r2
229; CHECK-NEXT:    and r0, r0, #2
230; CHECK-NEXT:    orr r0, r1, r0
231; CHECK-NEXT:    bx lr
232  %x1 = and i32 %a, 1
233  %y1 = and i32 %b, 4294967294
234  %z1 = or i32 %y1, %x1
235  %x2 = and i32 %a, 16
236  %y2 = and i32 %z1, 4294967279
237  %z2 = or i32 %y2, %x2
238  %x3 = and i32 %a, 2
239  %y3 = and i32 %z2, 4294967293
240  %z3 = or i32 %y3, %x3
241  ret i32 %z3
242}
243
244define void @bfi1_use(i32 %a, i32 %b) {
245; CHECK-LABEL: bfi1_use:
246; CHECK:       @ %bb.0:
247; CHECK-NEXT:    push {r11, lr}
248; CHECK-NEXT:    mov r2, r1
249; CHECK-NEXT:    lsr r3, r0, #4
250; CHECK-NEXT:    bfi r2, r0, #0, #1
251; CHECK-NEXT:    lsr r0, r0, #1
252; CHECK-NEXT:    mov r1, r2
253; CHECK-NEXT:    bfi r1, r3, #4, #1
254; CHECK-NEXT:    mov r3, r1
255; CHECK-NEXT:    bfi r3, r0, #1, #1
256; CHECK-NEXT:    mov r0, r2
257; CHECK-NEXT:    mov r2, r3
258; CHECK-NEXT:    bl use
259; CHECK-NEXT:    pop {r11, pc}
260  %x1 = and i32 %a, 1
261  %y1 = and i32 %b, 4294967294
262  %z1 = or i32 %y1, %x1
263  %x2 = and i32 %a, 16
264  %y2 = and i32 %z1, 4294967279
265  %z2 = or i32 %y2, %x2
266  %x3 = and i32 %a, 2
267  %y3 = and i32 %z2, 4294967293
268  %z3 = or i32 %y3, %x3
269  call void @use(i32 %z1, i32 %z2, i32 %z3, i32 %z3)
270  ret void
271}
272
273define i32 @bfi2(i32 %a, i32 %b) {
274; CHECK-LABEL: bfi2:
275; CHECK:       @ %bb.0:
276; CHECK-NEXT:    movw r2, #65148
277; CHECK-NEXT:    movt r2, #65535
278; CHECK-NEXT:    and r1, r1, r2
279; CHECK-NEXT:    and r2, r0, #1
280; CHECK-NEXT:    orr r1, r1, r2
281; CHECK-NEXT:    and r2, r0, #2
282; CHECK-NEXT:    orr r1, r1, r2
283; CHECK-NEXT:    and r2, r0, #128
284; CHECK-NEXT:    orr r1, r1, r2
285; CHECK-NEXT:    and r0, r0, #256
286; CHECK-NEXT:    orr r0, r1, r0
287; CHECK-NEXT:    bx lr
288  %x1 = and i32 %a, 1
289  %y1 = and i32 %b, 4294967294
290  %z1 = or i32 %y1, %x1
291  %x2 = and i32 %a, 2
292  %y2 = and i32 %z1, 4294967293
293  %z2 = or i32 %y2, %x2
294  %x3 = and i32 %a, 128
295  %y3 = and i32 %z2, 4294967167
296  %z3 = or i32 %y3, %x3
297  %x4 = and i32 %a, 256
298  %y4 = and i32 %z3, 4294967039
299  %z4 = or i32 %y4, %x4
300  ret i32 %z4
301}
302
303define void @bfi2_uses(i32 %a, i32 %b) {
304; CHECK-LABEL: bfi2_uses:
305; CHECK:       @ %bb.0:
306; CHECK-NEXT:    push {r11, lr}
307; CHECK-NEXT:    mov r12, r1
308; CHECK-NEXT:    bfi r1, r0, #0, #2
309; CHECK-NEXT:    bfi r12, r0, #0, #1
310; CHECK-NEXT:    lsr r0, r0, #7
311; CHECK-NEXT:    mov r2, r1
312; CHECK-NEXT:    mov r3, r1
313; CHECK-NEXT:    bfi r2, r0, #7, #1
314; CHECK-NEXT:    bfi r3, r0, #7, #2
315; CHECK-NEXT:    mov r0, r12
316; CHECK-NEXT:    bl use
317; CHECK-NEXT:    pop {r11, pc}
318  %x1 = and i32 %a, 1
319  %y1 = and i32 %b, 4294967294
320  %z1 = or i32 %y1, %x1
321  %x2 = and i32 %a, 2
322  %y2 = and i32 %z1, 4294967293
323  %z2 = or i32 %y2, %x2
324  %x3 = and i32 %a, 128
325  %y3 = and i32 %z2, 4294967167
326  %z3 = or i32 %y3, %x3
327  %x4 = and i32 %a, 256
328  %y4 = and i32 %z3, 4294967039
329  %z4 = or i32 %y4, %x4
330  call void @use(i32 %z1, i32 %z2, i32 %z3, i32 %z4)
331  ret void
332}
333
334define i32 @bfi3(i32 %a, i32 %b) {
335; CHECK-LABEL: bfi3:
336; CHECK:       @ %bb.0:
337; CHECK-NEXT:    movw r2, #65148
338; CHECK-NEXT:    movt r2, #65535
339; CHECK-NEXT:    and r1, r1, r2
340; CHECK-NEXT:    and r2, r0, #1
341; CHECK-NEXT:    orr r1, r1, r2
342; CHECK-NEXT:    and r2, r0, #128
343; CHECK-NEXT:    orr r1, r1, r2
344; CHECK-NEXT:    and r2, r0, #2
345; CHECK-NEXT:    orr r1, r1, r2
346; CHECK-NEXT:    and r0, r0, #256
347; CHECK-NEXT:    orr r0, r1, r0
348; CHECK-NEXT:    bx lr
349  %x1 = and i32 %a, 1
350  %y1 = and i32 %b, 4294967294
351  %z1 = or i32 %y1, %x1
352  %x2 = and i32 %a, 128
353  %y2 = and i32 %z1, 4294967167
354  %z2 = or i32 %y2, %x2
355  %x3 = and i32 %a, 2
356  %y3 = and i32 %z2, 4294967293
357  %z3 = or i32 %y3, %x3
358  %x4 = and i32 %a, 256
359  %y4 = and i32 %z3, 4294967039
360  %z4 = or i32 %y4, %x4
361  ret i32 %z4
362}
363
364define void @bfi3_uses(i32 %a, i32 %b) {
365; CHECK-LABEL: bfi3_uses:
366; CHECK:       @ %bb.0:
367; CHECK-NEXT:    push {r11, lr}
368; CHECK-NEXT:    mov r12, r1
369; CHECK-NEXT:    lsr r2, r0, #7
370; CHECK-NEXT:    bfi r12, r0, #0, #1
371; CHECK-NEXT:    lsr r3, r0, #1
372; CHECK-NEXT:    lsr r0, r0, #8
373; CHECK-NEXT:    mov r1, r12
374; CHECK-NEXT:    bfi r1, r2, #7, #1
375; CHECK-NEXT:    mov r2, r1
376; CHECK-NEXT:    bfi r2, r3, #1, #1
377; CHECK-NEXT:    mov r3, r2
378; CHECK-NEXT:    bfi r3, r0, #8, #1
379; CHECK-NEXT:    mov r0, r12
380; CHECK-NEXT:    bl use
381; CHECK-NEXT:    pop {r11, pc}
382  %x1 = and i32 %a, 1
383  %y1 = and i32 %b, 4294967294
384  %z1 = or i32 %y1, %x1
385  %x2 = and i32 %a, 128
386  %y2 = and i32 %z1, 4294967167
387  %z2 = or i32 %y2, %x2
388  %x3 = and i32 %a, 2
389  %y3 = and i32 %z2, 4294967293
390  %z3 = or i32 %y3, %x3
391  %x4 = and i32 %a, 256
392  %y4 = and i32 %z3, 4294967039
393  %z4 = or i32 %y4, %x4
394  call void @use(i32 %z1, i32 %z2, i32 %z3, i32 %z4)
395  ret void
396}
397
398define i32 @bfi4(i32 %A, i2 zeroext %BB, ptr %d) {
399; CHECK-LABEL: bfi4:
400; CHECK:       @ %bb.0: @ %entry
401; CHECK-NEXT:    push {r11, lr}
402; CHECK-NEXT:    lsr r12, r0, #1
403; CHECK-NEXT:    and r3, r0, #8
404; CHECK-NEXT:    bfi r1, r12, #2, #2
405; CHECK-NEXT:    mov lr, #96
406; CHECK-NEXT:    tst r0, #32
407; CHECK-NEXT:    bfi r1, r12, #9, #2
408; CHECK-NEXT:    movweq lr, #32
409; CHECK-NEXT:    orr r1, r1, r3, lsl #8
410; CHECK-NEXT:    and r3, r0, #64
411; CHECK-NEXT:    and r0, r0, #128
412; CHECK-NEXT:    orr r1, r1, lr
413; CHECK-NEXT:    orr r1, r1, r3, lsl #1
414; CHECK-NEXT:    str r1, [r2]
415; CHECK-NEXT:    pop {r11, pc}
416entry:
417  %B = zext i2 %BB to i32
418  %and = and i32 %A, 2
419  %tobool12.not = icmp eq i32 %and, 0
420  %or17 = or i32 %B, 516
421  %spec.select112 = select i1 %tobool12.not, i32 %B, i32 %or17
422  %and20 = and i32 %A, 4
423  %tobool21.not = icmp eq i32 %and20, 0
424  %or26 = or i32 %spec.select112, 1032
425  %spec.select114 = select i1 %tobool21.not, i32 %spec.select112, i32 %or26
426  store i32 %spec.select114, ptr %d, align 4
427  %and29 = shl i32 %A, 8
428  %l2 = and i32 %and29, 2048
429  %l3 = or i32 %l2, %spec.select114
430  %and38 = and i32 %A, 32
431  %tobool39.not = icmp eq i32 %and38, 0
432  %spec.select.v = select i1 %tobool39.not, i32 32, i32 96
433  %spec.select = or i32 %l3, %spec.select.v
434  %and45 = shl i32 %A, 1
435  %l4 = and i32 %and45, 128
436  %l5 = or i32 %l4, %spec.select
437  store i32 %l5, ptr %d, align 4
438  %and52 = and i32 %A, 128
439  ret i32 %and52
440}
441
442declare void @use(i32, i32, i32, i32)
443