1; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM
2; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM
3; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB
4; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
5; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
6; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG
7
8; Note that some of these tests assume that relocations are either
9; movw/movt or constant pool loads. Different platforms will select
10; different approaches.
11
12@message1 = global [60 x i8] c"The LLVM Compiler Infrastructure\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 1
13@temp = common global [60 x i8] zeroinitializer, align 1
14
15define void @t1() nounwind ssp {
16; ARM-LABEL: t1:
17; ARM: {{(movw r0, :lower16:_?message1)|(ldr r0, .LCPI)}}
18; ARM: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}}
19; ARM: add r0, r0, #5
20; ARM: movw r1, #64
21; ARM: movw r2, #10
22; ARM: and r1, r1, #255
23; ARM: bl {{_?}}memset
24; ARM-LONG-LABEL: t1:
25; ARM-LONG: {{(movw r3, :lower16:L_memset\$non_lazy_ptr)|(ldr r3, .LCPI)}}
26; ARM-LONG: {{(movt r3, :upper16:L_memset\$non_lazy_ptr)?}}
27; ARM-LONG: ldr r3, [r3]
28; ARM-LONG: blx r3
29; THUMB-LABEL: t1:
30; THUMB: {{(movw r0, :lower16:_?message1)|(ldr.n r0, .LCPI)}}
31; THUMB: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}}
32; THUMB: adds r0, #5
33; THUMB: movs r1, #64
34; THUMB: movs r2, #10
35; THUMB: and r1, r1, #255
36; THUMB: bl {{_?}}memset
37; THUMB-LONG-LABEL: t1:
38; THUMB-LONG: movw r3, :lower16:L_memset$non_lazy_ptr
39; THUMB-LONG: movt r3, :upper16:L_memset$non_lazy_ptr
40; THUMB-LONG: ldr r3, [r3]
41; THUMB-LONG: blx r3
42  call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @message1, i32 0, i32 5), i8 64, i32 10, i32 4, i1 false)
43  ret void
44}
45
46declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
47
48define void @t2() nounwind ssp {
49; ARM-LABEL: t2:
50; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
51; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
52; ARM: ldr r0, [r0]
53; ARM: add r1, r0, #4
54; ARM: add r0, r0, #16
55; ARM: movw r2, #17
56; ARM: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
57; ARM: mov r0, r1
58; ARM: ldr r1, [sp[[SLOT]]] @ 4-byte Reload
59; ARM: bl {{_?}}memcpy
60; ARM-LONG-LABEL: t2:
61; ARM-LONG: {{(movw r3, :lower16:L_memcpy\$non_lazy_ptr)|(ldr r3, .LCPI)}}
62; ARM-LONG: {{(movt r3, :upper16:L_memcpy\$non_lazy_ptr)?}}
63; ARM-LONG: ldr r3, [r3]
64; ARM-LONG: blx r3
65; THUMB-LABEL: t2:
66; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
67; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
68; THUMB: ldr r0, [r0]
69; THUMB: adds r1, r0, #4
70; THUMB: adds r0, #16
71; THUMB: movs r2, #17
72; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
73; THUMB: mov r0, r1
74; THUMB: ldr r1,  [sp[[SLOT]]] @ 4-byte Reload
75; THUMB: bl {{_?}}memcpy
76; THUMB-LONG-LABEL: t2:
77; THUMB-LONG: movw r3, :lower16:L_memcpy$non_lazy_ptr
78; THUMB-LONG: movt r3, :upper16:L_memcpy$non_lazy_ptr
79; THUMB-LONG: ldr r3, [r3]
80; THUMB-LONG: blx r3
81  call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 17, i32 4, i1 false)
82  ret void
83}
84
85declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
86
87define void @t3() nounwind ssp {
88; ARM-LABEL: t3:
89; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
90; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
91; ARM: ldr r0, [r0]
92; ARM: add r1, r0, #4
93; ARM: add r0, r0, #16
94; ARM: movw r2, #10
95; ARM: mov r0, r1
96; ARM: bl {{_?}}memmove
97; ARM-LONG-LABEL: t3:
98; ARM-LONG: {{(movw r3, :lower16:L_memmove\$non_lazy_ptr)|(ldr r3, .LCPI)}}
99; ARM-LONG: {{(movt r3, :upper16:L_memmove\$non_lazy_ptr)?}}
100; ARM-LONG: ldr r3, [r3]
101; ARM-LONG: blx r3
102; THUMB-LABEL: t3:
103; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
104; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
105; THUMB: ldr r0, [r0]
106; THUMB: adds r1, r0, #4
107; THUMB: adds r0, #16
108; THUMB: movs r2, #10
109; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
110; THUMB: mov r0, r1
111; THUMB: ldr r1,  [sp[[SLOT]]] @ 4-byte Reload
112; THUMB: bl {{_?}}memmove
113; THUMB-LONG-LABEL: t3:
114; THUMB-LONG: movw r3, :lower16:L_memmove$non_lazy_ptr
115; THUMB-LONG: movt r3, :upper16:L_memmove$non_lazy_ptr
116; THUMB-LONG: ldr r3, [r3]
117; THUMB-LONG: blx r3
118  call void @llvm.memmove.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false)
119  ret void
120}
121
122define void @t4() nounwind ssp {
123; ARM-LABEL: t4:
124; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
125; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
126; ARM: ldr r0, [r0]
127; ARM: ldr r1, [r0, #16]
128; ARM: str r1, [r0, #4]
129; ARM: ldr r1, [r0, #20]
130; ARM: str r1, [r0, #8]
131; ARM: ldrh r1, [r0, #24]
132; ARM: strh r1, [r0, #12]
133; ARM: bx lr
134; THUMB-LABEL: t4:
135; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
136; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
137; THUMB: ldr r0, [r0]
138; THUMB: ldr r1, [r0, #16]
139; THUMB: str r1, [r0, #4]
140; THUMB: ldr r1, [r0, #20]
141; THUMB: str r1, [r0, #8]
142; THUMB: ldrh r1, [r0, #24]
143; THUMB: strh r1, [r0, #12]
144; THUMB: bx lr
145  call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 4, i1 false)
146  ret void
147}
148
149declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
150
151define void @t5() nounwind ssp {
152; ARM-LABEL: t5:
153; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
154; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
155; ARM: ldr r0, [r0]
156; ARM: ldrh r1, [r0, #16]
157; ARM: strh r1, [r0, #4]
158; ARM: ldrh r1, [r0, #18]
159; ARM: strh r1, [r0, #6]
160; ARM: ldrh r1, [r0, #20]
161; ARM: strh r1, [r0, #8]
162; ARM: ldrh r1, [r0, #22]
163; ARM: strh r1, [r0, #10]
164; ARM: ldrh r1, [r0, #24]
165; ARM: strh r1, [r0, #12]
166; ARM: bx lr
167; THUMB-LABEL: t5:
168; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
169; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
170; THUMB: ldr r0, [r0]
171; THUMB: ldrh r1, [r0, #16]
172; THUMB: strh r1, [r0, #4]
173; THUMB: ldrh r1, [r0, #18]
174; THUMB: strh r1, [r0, #6]
175; THUMB: ldrh r1, [r0, #20]
176; THUMB: strh r1, [r0, #8]
177; THUMB: ldrh r1, [r0, #22]
178; THUMB: strh r1, [r0, #10]
179; THUMB: ldrh r1, [r0, #24]
180; THUMB: strh r1, [r0, #12]
181; THUMB: bx lr
182  call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 2, i1 false)
183  ret void
184}
185
186define void @t6() nounwind ssp {
187; ARM-LABEL: t6:
188; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
189; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
190; ARM: ldr r0, [r0]
191; ARM: ldrb r1, [r0, #16]
192; ARM: strb r1, [r0, #4]
193; ARM: ldrb r1, [r0, #17]
194; ARM: strb r1, [r0, #5]
195; ARM: ldrb r1, [r0, #18]
196; ARM: strb r1, [r0, #6]
197; ARM: ldrb r1, [r0, #19]
198; ARM: strb r1, [r0, #7]
199; ARM: ldrb r1, [r0, #20]
200; ARM: strb r1, [r0, #8]
201; ARM: ldrb r1, [r0, #21]
202; ARM: strb r1, [r0, #9]
203; ARM: ldrb r1, [r0, #22]
204; ARM: strb r1, [r0, #10]
205; ARM: ldrb r1, [r0, #23]
206; ARM: strb r1, [r0, #11]
207; ARM: ldrb r1, [r0, #24]
208; ARM: strb r1, [r0, #12]
209; ARM: ldrb r1, [r0, #25]
210; ARM: strb r1, [r0, #13]
211; ARM: bx lr
212; THUMB-LABEL: t6:
213; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
214; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
215; THUMB: ldr r0, [r0]
216; THUMB: ldrb r1, [r0, #16]
217; THUMB: strb r1, [r0, #4]
218; THUMB: ldrb r1, [r0, #17]
219; THUMB: strb r1, [r0, #5]
220; THUMB: ldrb r1, [r0, #18]
221; THUMB: strb r1, [r0, #6]
222; THUMB: ldrb r1, [r0, #19]
223; THUMB: strb r1, [r0, #7]
224; THUMB: ldrb r1, [r0, #20]
225; THUMB: strb r1, [r0, #8]
226; THUMB: ldrb r1, [r0, #21]
227; THUMB: strb r1, [r0, #9]
228; THUMB: ldrb r1, [r0, #22]
229; THUMB: strb r1, [r0, #10]
230; THUMB: ldrb r1, [r0, #23]
231; THUMB: strb r1, [r0, #11]
232; THUMB: ldrb r1, [r0, #24]
233; THUMB: strb r1, [r0, #12]
234; THUMB: ldrb r1, [r0, #25]
235; THUMB: strb r1, [r0, #13]
236; THUMB: bx lr
237  call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false)
238  ret void
239}
240
241; rdar://13202135
242define void @t7() nounwind ssp {
243; Just make sure this doesn't assert when we have an odd length and an alignment of 2.
244  call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 3, i32 2, i1 false)
245  ret void
246}
247
248define i32 @t8(i32 %x) nounwind {
249entry:
250; ARM-LABEL: t8:
251; ARM-NOT: FastISel missed call:   %expval = call i32 @llvm.expect.i32(i32 %x, i32 1)
252; THUMB-LABEL: t8:
253; THUMB-NOT: FastISel missed call:   %expval = call i32 @llvm.expect.i32(i32 %x, i32 1)
254  %expval = call i32 @llvm.expect.i32(i32 %x, i32 1)
255  ret i32 %expval
256}
257
258declare i32 @llvm.expect.i32(i32, i32) nounwind readnone
259