xref: /llvm-project/llvm/test/CodeGen/ARM/add-like-or.ll (revision e0ed0333f0fed2e73f805afd58b61176a87aa3ad)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=thumbv6m-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-T1
3; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-T2
4; RUN: llc -mtriple=armv7a-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-A
5
6define i32 @test_add_i3(i1 %tst, i32 %a, i32 %b) {
7; CHECK-T1-LABEL: test_add_i3:
8; CHECK-T1:       @ %bb.0:
9; CHECK-T1-NEXT:    .save {r4, lr}
10; CHECK-T1-NEXT:    push {r4, lr}
11; CHECK-T1-NEXT:    lsls r0, r0, #31
12; CHECK-T1-NEXT:    bne .LBB0_2
13; CHECK-T1-NEXT:  @ %bb.1:
14; CHECK-T1-NEXT:    movs r0, #3
15; CHECK-T1-NEXT:    bics r2, r0
16; CHECK-T1-NEXT:    mov r4, r2
17; CHECK-T1-NEXT:    b .LBB0_3
18; CHECK-T1-NEXT:  .LBB0_2:
19; CHECK-T1-NEXT:    mov r4, r1
20; CHECK-T1-NEXT:    movs r0, #6
21; CHECK-T1-NEXT:    bics r4, r0
22; CHECK-T1-NEXT:  .LBB0_3:
23; CHECK-T1-NEXT:    mov r0, r4
24; CHECK-T1-NEXT:    bl foo
25; CHECK-T1-NEXT:    adds r0, r4, #2
26; CHECK-T1-NEXT:    pop {r4, pc}
27;
28; CHECK-T2-LABEL: test_add_i3:
29; CHECK-T2:       @ %bb.0:
30; CHECK-T2-NEXT:    .save {r4, lr}
31; CHECK-T2-NEXT:    push {r4, lr}
32; CHECK-T2-NEXT:    bic r4, r2, #3
33; CHECK-T2-NEXT:    lsls r0, r0, #31
34; CHECK-T2-NEXT:    it ne
35; CHECK-T2-NEXT:    bicne r4, r1, #6
36; CHECK-T2-NEXT:    mov r0, r4
37; CHECK-T2-NEXT:    bl foo
38; CHECK-T2-NEXT:    adds r0, r4, #2
39; CHECK-T2-NEXT:    pop {r4, pc}
40;
41; CHECK-A-LABEL: test_add_i3:
42; CHECK-A:       @ %bb.0:
43; CHECK-A-NEXT:    .save {r4, lr}
44; CHECK-A-NEXT:    push {r4, lr}
45; CHECK-A-NEXT:    bic r4, r2, #3
46; CHECK-A-NEXT:    tst r0, #1
47; CHECK-A-NEXT:    bicne r4, r1, #6
48; CHECK-A-NEXT:    mov r0, r4
49; CHECK-A-NEXT:    bl foo
50; CHECK-A-NEXT:    orr r0, r4, #2
51; CHECK-A-NEXT:    pop {r4, pc}
52  %tmp = and i32 %a, -7
53  %tmp1 = and i32 %b, -4
54  %int = select i1 %tst, i32 %tmp, i32 %tmp1
55
56  ; Call to force %int into a register that isn't r0 so using the i3 form is a
57  ; good idea.
58  call void @foo(i32 %int)
59  %res = or i32 %int, 2
60  ret i32 %res
61}
62
63define i32 @test_add_i8(i32 %a, i32 %b, i1 %tst) {
64; CHECK-T1-LABEL: test_add_i8:
65; CHECK-T1:       @ %bb.0:
66; CHECK-T1-NEXT:    lsls r2, r2, #31
67; CHECK-T1-NEXT:    bne .LBB1_2
68; CHECK-T1-NEXT:  @ %bb.1:
69; CHECK-T1-NEXT:    ldr r0, .LCPI1_0
70; CHECK-T1-NEXT:    ands r1, r0
71; CHECK-T1-NEXT:    mov r0, r1
72; CHECK-T1-NEXT:    adds r0, #12
73; CHECK-T1-NEXT:    bx lr
74; CHECK-T1-NEXT:  .LBB1_2:
75; CHECK-T1-NEXT:    movs r1, #255
76; CHECK-T1-NEXT:    bics r0, r1
77; CHECK-T1-NEXT:    adds r0, #12
78; CHECK-T1-NEXT:    bx lr
79; CHECK-T1-NEXT:    .p2align 2
80; CHECK-T1-NEXT:  @ %bb.3:
81; CHECK-T1-NEXT:  .LCPI1_0:
82; CHECK-T1-NEXT:    .long 4294966784 @ 0xfffffe00
83;
84; CHECK-T2-LABEL: test_add_i8:
85; CHECK-T2:       @ %bb.0:
86; CHECK-T2-NEXT:    movw r3, #511
87; CHECK-T2-NEXT:    bics r1, r3
88; CHECK-T2-NEXT:    lsls r2, r2, #31
89; CHECK-T2-NEXT:    it ne
90; CHECK-T2-NEXT:    bicne r1, r0, #255
91; CHECK-T2-NEXT:    add.w r0, r1, #12
92; CHECK-T2-NEXT:    bx lr
93;
94; CHECK-A-LABEL: test_add_i8:
95; CHECK-A:       @ %bb.0:
96; CHECK-A-NEXT:    bfc r1, #0, #9
97; CHECK-A-NEXT:    tst r2, #1
98; CHECK-A-NEXT:    bicne r1, r0, #255
99; CHECK-A-NEXT:    orr r0, r1, #12
100; CHECK-A-NEXT:    bx lr
101  %tmp = and i32 %a, -256
102  %tmp1 = and i32 %b, -512
103  %int = select i1 %tst, i32 %tmp, i32 %tmp1
104  %res = or i32 %int, 12
105  ret i32 %res
106}
107
108define i32 @test_add_i12(i32 %a, i32 %b, i1 %tst) {
109; CHECK-T1-LABEL: test_add_i12:
110; CHECK-T1:       @ %bb.0:
111; CHECK-T1-NEXT:    lsls r2, r2, #31
112; CHECK-T1-NEXT:    bne .LBB2_2
113; CHECK-T1-NEXT:  @ %bb.1:
114; CHECK-T1-NEXT:    ldr r0, .LCPI2_1
115; CHECK-T1-NEXT:    ands r1, r0
116; CHECK-T1-NEXT:    mov r0, r1
117; CHECK-T1-NEXT:    b .LBB2_3
118; CHECK-T1-NEXT:  .LBB2_2:
119; CHECK-T1-NEXT:    ldr r1, .LCPI2_0
120; CHECK-T1-NEXT:    ands r0, r1
121; CHECK-T1-NEXT:  .LBB2_3:
122; CHECK-T1-NEXT:    ldr r1, .LCPI2_2
123; CHECK-T1-NEXT:    adds r0, r0, r1
124; CHECK-T1-NEXT:    bx lr
125; CHECK-T1-NEXT:    .p2align 2
126; CHECK-T1-NEXT:  @ %bb.4:
127; CHECK-T1-NEXT:  .LCPI2_0:
128; CHECK-T1-NEXT:    .long 4294963200 @ 0xfffff000
129; CHECK-T1-NEXT:  .LCPI2_1:
130; CHECK-T1-NEXT:    .long 4294959104 @ 0xffffe000
131; CHECK-T1-NEXT:  .LCPI2_2:
132; CHECK-T1-NEXT:    .long 854 @ 0x356
133;
134; CHECK-T2-LABEL: test_add_i12:
135; CHECK-T2:       @ %bb.0:
136; CHECK-T2-NEXT:    movw r3, #8191
137; CHECK-T2-NEXT:    bics r1, r3
138; CHECK-T2-NEXT:    movw r12, #4095
139; CHECK-T2-NEXT:    lsls r2, r2, #31
140; CHECK-T2-NEXT:    it ne
141; CHECK-T2-NEXT:    bicne.w r1, r0, r12
142; CHECK-T2-NEXT:    addw r0, r1, #854
143; CHECK-T2-NEXT:    bx lr
144;
145; CHECK-A-LABEL: test_add_i12:
146; CHECK-A:       @ %bb.0:
147; CHECK-A-NEXT:    bfc r0, #0, #12
148; CHECK-A-NEXT:    bfc r1, #0, #13
149; CHECK-A-NEXT:    tst r2, #1
150; CHECK-A-NEXT:    movne r1, r0
151; CHECK-A-NEXT:    movw r0, #854
152; CHECK-A-NEXT:    orr r0, r1, r0
153; CHECK-A-NEXT:    bx lr
154  %tmp = and i32 %a, -4096
155  %tmp1 = and i32 %b, -8192
156  %int = select i1 %tst, i32 %tmp, i32 %tmp1
157  %res = or i32 %int, 854
158  ret i32 %res
159}
160
161define i32 @oradd(i32 %i, i32 %y) {
162; CHECK-T1-LABEL: oradd:
163; CHECK-T1:       @ %bb.0: @ %entry
164; CHECK-T1-NEXT:    lsls r0, r0, #1
165; CHECK-T1-NEXT:    adds r0, r1, r0
166; CHECK-T1-NEXT:    adds r0, r0, #1
167; CHECK-T1-NEXT:    bx lr
168;
169; CHECK-T2-LABEL: oradd:
170; CHECK-T2:       @ %bb.0: @ %entry
171; CHECK-T2-NEXT:    add.w r0, r1, r0, lsl #1
172; CHECK-T2-NEXT:    adds r0, #1
173; CHECK-T2-NEXT:    bx lr
174;
175; CHECK-A-LABEL: oradd:
176; CHECK-A:       @ %bb.0: @ %entry
177; CHECK-A-NEXT:    add r0, r1, r0, lsl #1
178; CHECK-A-NEXT:    add r0, r0, #1
179; CHECK-A-NEXT:    bx lr
180entry:
181  %mul = shl i32 %i, 1
182  %or = or i32 %mul, 1
183  %add = add i32 %or, %y
184  ret i32 %add
185}
186
187define i32 @orgep(i32 %i, ptr %x, ptr %y) {
188; CHECK-T1-LABEL: orgep:
189; CHECK-T1:       @ %bb.0: @ %entry
190; CHECK-T1-NEXT:    lsls r0, r0, #3
191; CHECK-T1-NEXT:    adds r0, r1, r0
192; CHECK-T1-NEXT:    ldr r0, [r0, #4]
193; CHECK-T1-NEXT:    bx lr
194;
195; CHECK-T2-LABEL: orgep:
196; CHECK-T2:       @ %bb.0: @ %entry
197; CHECK-T2-NEXT:    add.w r0, r1, r0, lsl #3
198; CHECK-T2-NEXT:    ldr r0, [r0, #4]
199; CHECK-T2-NEXT:    bx lr
200;
201; CHECK-A-LABEL: orgep:
202; CHECK-A:       @ %bb.0: @ %entry
203; CHECK-A-NEXT:    add r0, r1, r0, lsl #3
204; CHECK-A-NEXT:    ldr r0, [r0, #4]
205; CHECK-A-NEXT:    bx lr
206entry:
207  %mul = shl i32 %i, 1
208  %add = or i32 %mul, 1
209  %arrayidx = getelementptr inbounds i32, ptr %x, i32 %add
210  %0 = load i32, ptr %arrayidx, align 8
211  ret i32 %0
212}
213
214define i32 @orgeps(i32 %i, ptr %x, ptr %y) {
215; CHECK-T1-LABEL: orgeps:
216; CHECK-T1:       @ %bb.0: @ %entry
217; CHECK-T1-NEXT:    lsls r0, r0, #3
218; CHECK-T1-NEXT:    adds r0, r1, r0
219; CHECK-T1-NEXT:    ldr r1, [r0, #4]
220; CHECK-T1-NEXT:    ldr r0, [r0, #8]
221; CHECK-T1-NEXT:    adds r0, r0, r1
222; CHECK-T1-NEXT:    bx lr
223;
224; CHECK-T2-LABEL: orgeps:
225; CHECK-T2:       @ %bb.0: @ %entry
226; CHECK-T2-NEXT:    add.w r0, r1, r0, lsl #3
227; CHECK-T2-NEXT:    ldrd r0, r1, [r0, #4]
228; CHECK-T2-NEXT:    add r0, r1
229; CHECK-T2-NEXT:    bx lr
230;
231; CHECK-A-LABEL: orgeps:
232; CHECK-A:       @ %bb.0: @ %entry
233; CHECK-A-NEXT:    add r0, r1, r0, lsl #3
234; CHECK-A-NEXT:    ldrd r0, r1, [r0, #4]
235; CHECK-A-NEXT:    add r0, r1, r0
236; CHECK-A-NEXT:    bx lr
237entry:
238  %mul = shl i32 %i, 1
239  %add = or i32 %mul, 1
240  %arrayidx = getelementptr inbounds i32, ptr %x, i32 %add
241  %0 = load i32, ptr %arrayidx, align 8
242  %add2 = add i32 %mul, 2
243  %arrayidx3 = getelementptr inbounds i32, ptr %x, i32 %add2
244  %1 = load i32, ptr %arrayidx3, align 8
245  %add4 = add i32 %1, %0
246  ret i32 %add4
247}
248
249define i32 @multiuse(i32 %i, ptr %x, ptr %y) {
250; CHECK-T1-LABEL: multiuse:
251; CHECK-T1:       @ %bb.0: @ %entry
252; CHECK-T1-NEXT:    lsls r0, r0, #1
253; CHECK-T1-NEXT:    adds r0, r0, #1
254; CHECK-T1-NEXT:    lsls r2, r0, #2
255; CHECK-T1-NEXT:    ldr r1, [r1, r2]
256; CHECK-T1-NEXT:    adds r0, r0, r1
257; CHECK-T1-NEXT:    bx lr
258;
259; CHECK-T2-LABEL: multiuse:
260; CHECK-T2:       @ %bb.0: @ %entry
261; CHECK-T2-NEXT:    lsls r0, r0, #1
262; CHECK-T2-NEXT:    adds r0, #1
263; CHECK-T2-NEXT:    ldr.w r1, [r1, r0, lsl #2]
264; CHECK-T2-NEXT:    add r0, r1
265; CHECK-T2-NEXT:    bx lr
266;
267; CHECK-A-LABEL: multiuse:
268; CHECK-A:       @ %bb.0: @ %entry
269; CHECK-A-NEXT:    mov r2, #1
270; CHECK-A-NEXT:    orr r0, r2, r0, lsl #1
271; CHECK-A-NEXT:    ldr r1, [r1, r0, lsl #2]
272; CHECK-A-NEXT:    add r0, r0, r1
273; CHECK-A-NEXT:    bx lr
274entry:
275  %mul = shl i32 %i, 1
276  %add = or i32 %mul, 1
277  %arrayidx = getelementptr inbounds i32, ptr %x, i32 %add
278  %0 = load i32, ptr %arrayidx, align 8
279  %r = add i32 %add, %0
280  ret i32 %r
281}
282
283declare void @foo(i32)
284