When the "true" and "false" blocks of a diamond if-conversion are the same,
[oota-llvm.git] / test / MC / ARM / simple-fp-encoding.ll
1 ; RUN: llc -mtriple=armv7-apple-darwin -mcpu=cortex-a8 -mattr=-neonfp -show-mc-encoding < %s | FileCheck %s
2
3
4 ; FIXME: Once the ARM integrated assembler is up and going, these sorts of tests
5 ;        should run on .s source files rather than using llc to generate the
6 ;        assembly.
7
8
9 define double @f1(double %a, double %b) nounwind readnone {
10 entry:
11 ; CHECK: f1
12 ; CHECK: vadd.f64 d16, d17, d16      @ encoding: [0xa0,0x0b,0x71,0xee]
13   %add = fadd double %a, %b
14   ret double %add
15 }
16
17 define float @f2(float %a, float %b) nounwind readnone {
18 entry:
19 ; CHECK: f2
20 ; CHECK: vadd.f32 s0, s1, s0         @ encoding: [0x80,0x0a,0x30,0xee]
21   %add = fadd float %a, %b
22   ret float %add
23 }
24
25 define double @f3(double %a, double %b) nounwind readnone {
26 entry:
27 ; CHECK: f3
28 ; CHECK: vsub.f64 d16, d17, d16      @ encoding: [0xe0,0x0b,0x71,0xee]
29   %sub = fsub double %a, %b
30   ret double %sub
31 }
32
33 define float @f4(float %a, float %b) nounwind readnone {
34 entry:
35 ; CHECK: f4
36 ; CHECK: vsub.f32 s0, s1, s0         @ encoding: [0xc0,0x0a,0x30,0xee]
37   %sub = fsub float %a, %b
38   ret float %sub
39 }
40
41 define double @f5(double %a, double %b) nounwind readnone {
42 entry:
43 ; CHECK: f5
44 ; CHECK: vdiv.f64 d16, d17, d16      @ encoding: [0xa0,0x0b,0xc1,0xee]
45   %div = fdiv double %a, %b
46   ret double %div
47 }
48
49 define float @f6(float %a, float %b) nounwind readnone {
50 entry:
51 ; CHECK: f6
52 ; CHECK: vdiv.f32 s0, s1, s0         @ encoding: [0x80,0x0a,0x80,0xee]
53   %div = fdiv float %a, %b
54   ret float %div
55 }
56
57 define double @f7(double %a, double %b) nounwind readnone {
58 entry:
59 ; CHECK: f7
60 ; CHECK: vmul.f64 d16, d17, d16      @ encoding: [0xa0,0x0b,0x61,0xee]
61   %mul = fmul double %a, %b
62   ret double %mul
63 }
64
65 define float @f8(float %a, float %b) nounwind readnone {
66 entry:
67 ; CHECK: f8
68 ; CHECK: vmul.f32 s0, s1, s0         @ encoding: [0x80,0x0a,0x20,0xee]
69   %mul = fmul float %a, %b
70   ret float %mul
71 }
72
73 define double @f9(double %a, double %b) nounwind readnone {
74 entry:
75 ; CHECK: f9
76 ; CHECK: vnmul.f64 d16, d17, d16     @ encoding: [0xe0,0x0b,0x61,0xee]
77   %mul = fmul double %a, %b
78   %sub = fsub double -0.000000e+00, %mul
79   ret double %sub
80 }
81
82 define void @f10(float %a, float %b, float* %c) nounwind readnone {
83 entry:
84 ; CHECK: f10
85 ; CHECK: vnmul.f32 s0, s1, s0        @ encoding: [0xc0,0x0a,0x20,0xee]
86   %mul = fmul float %a, %b
87   %sub = fsub float -0.000000e+00, %mul
88   store float %sub, float* %c, align 4
89   ret void
90 }
91
92 define i1 @f11(double %a, double %b) nounwind readnone {
93 entry:
94 ; CHECK: f11
95 ; CHECK: vcmpe.f64 d17, d16          @ encoding: [0xe0,0x1b,0xf4,0xee]
96   %cmp = fcmp oeq double %a, %b
97   ret i1 %cmp
98 }
99
100 define i1 @f12(float %a, float %b) nounwind readnone {
101 entry:
102 ; CHECK: f12
103 ; CHECK: vcmpe.f32 s1, s0            @ encoding: [0xc0,0x0a,0xf4,0xee]
104   %cmp = fcmp oeq float %a, %b
105   ret i1 %cmp
106 }
107
108 define i1 @f13(double %a) nounwind readnone {
109 entry:
110 ; CHECK: f13
111 ; CHECK: vcmpe.f64 d16, #0           @ encoding: [0xc0,0x0b,0xf5,0xee]
112   %cmp = fcmp oeq double %a, 0.000000e+00
113   ret i1 %cmp
114 }
115
116 define i1 @f14(float %a) nounwind readnone {
117 entry:
118 ; CHECK: f14
119 ; CHECK: vcmpe.f32 s0, #0            @ encoding: [0xc0,0x0a,0xb5,0xee]
120   %cmp = fcmp oeq float %a, 0.000000e+00
121   ret i1 %cmp
122 }
123
124 define double @f15(double %a) nounwind {
125 entry:
126 ; CHECK: f15
127 ; CHECK: vabs.f64 d16, d16           @ encoding: [0xe0,0x0b,0xf0,0xee]
128   %call = tail call double @fabsl(double %a)
129   ret double %call
130 }
131
132 declare double @fabsl(double)
133
134 define float @f16(float %a) nounwind {
135 entry:
136 ; CHECK: f16
137 ; FIXME: This call generates a "bfc" instruction instead of "vabs.f32".
138   %call = tail call float @fabsf(float %a)
139   ret float %call
140 }
141
142 declare float @fabsf(float)
143
144 define float @f17(double %a) nounwind readnone {
145 entry:
146 ; CHECK: f17
147 ; CHECK: vcvt.f32.f64 s0, d16        @ encoding: [0xe0,0x0b,0xb7,0xee]
148   %conv = fptrunc double %a to float
149   ret float %conv
150 }
151
152 define double @f18(float %a) nounwind readnone {
153 entry:
154 ; CHECK: f18
155 ; CHECK: vcvt.f64.f32 d16, s0        @ encoding: [0xc0,0x0a,0xf7,0xee]
156   %conv = fpext float %a to double
157   ret double %conv
158 }
159
160 define double @f19(double %a) nounwind readnone {
161 entry:
162 ; CHECK: f19
163 ; CHECK: vneg.f64 d16, d16           @ encoding: [0x60,0x0b,0xf1,0xee]
164   %sub = fsub double -0.000000e+00, %a
165   ret double %sub
166 }
167
168 define float @f20(float %a) nounwind readnone {
169 entry:
170 ; CHECK: f20
171 ; FIXME: This produces an 'eor' instruction.
172   %sub = fsub float -0.000000e+00, %a
173   ret float %sub
174 }
175
176 define double @f21(double %a) nounwind readnone {
177 entry:
178 ; CHECK: f21
179 ; CHECK: vsqrt.f64 d16, d16          @ encoding: [0xe0,0x0b,0xf1,0xee]
180   %call = tail call double @sqrtl(double %a) nounwind
181   ret double %call
182 }
183
184 declare double @sqrtl(double) readnone
185
186 define float @f22(float %a) nounwind readnone {
187 entry:
188 ; CHECK: f22
189 ; CHECK: vsqrt.f32 s0, s0            @ encoding: [0xc0,0x0a,0xb1,0xee]
190   %call = tail call float @sqrtf(float %a) nounwind
191   ret float %call
192 }
193
194 declare float @sqrtf(float) readnone
195
196 define double @f23(i32 %a) nounwind readnone {
197 entry:
198 ; CHECK: f23
199 ; CHECK: vcvt.f64.s32 d16, s0        @ encoding: [0xc0,0x0b,0xf8,0xee]
200   %conv = sitofp i32 %a to double
201   ret double %conv
202 }
203
204 define float @f24(i32 %a) nounwind readnone {
205 entry:
206 ; CHECK: f24
207 ; CHECK: vcvt.f32.s32 s0, s0         @ encoding: [0xc0,0x0a,0xb8,0xee]
208   %conv = sitofp i32 %a to float
209   ret float %conv
210 }
211
212 define double @f25(i32 %a) nounwind readnone {
213 entry:
214 ; CHECK: f25
215 ; CHECK: vcvt.f64.u32 d16, s0        @ encoding: [0x40,0x0b,0xf8,0xee]
216   %conv = uitofp i32 %a to double
217   ret double %conv
218 }
219
220 define float @f26(i32 %a) nounwind readnone {
221 entry:
222 ; CHECK: f26
223 ; CHECK: vcvt.f32.u32 s0, s0         @ encoding: [0x40,0x0a,0xb8,0xee]
224   %conv = uitofp i32 %a to float
225   ret float %conv
226 }
227
228 define i32 @f27(double %a) nounwind readnone {
229 entry:
230 ; CHECK: f27
231 ; CHECK: vcvt.s32.f64 s0, d16        @ encoding: [0xe0,0x0b,0xbd,0xee]
232   %conv = fptosi double %a to i32
233   ret i32 %conv
234 }
235
236 define i32 @f28(float %a) nounwind readnone {
237 entry:
238 ; CHECK: f28
239 ; CHECK: vcvt.s32.f32 s0, s0         @ encoding: [0xc0,0x0a,0xbd,0xee]
240   %conv = fptosi float %a to i32
241   ret i32 %conv
242 }
243
244 define i32 @f29(double %a) nounwind readnone {
245 entry:
246 ; CHECK: f29
247 ; CHECK: vcvt.u32.f64 s0, d16        @ encoding: [0xe0,0x0b,0xbc,0xee]
248   %conv = fptoui double %a to i32
249   ret i32 %conv
250 }
251
252 define i32 @f30(float %a) nounwind readnone {
253 entry:
254 ; CHECK: f30
255 ; CHECK: vcvt.u32.f32 s0, s0         @ encoding: [0xc0,0x0a,0xbc,0xee]
256   %conv = fptoui float %a to i32
257   ret i32 %conv
258 }
259
260 define double @f90(double %a, double %b, double %c) nounwind readnone {
261 entry:
262 ; CHECK: f90
263 ; FIXME: vmla.f64 d16, d18, d17      @ encoding: [0xa1,0x0b,0x42,0xee]
264   %mul = fmul double %a, %b
265   %add = fadd double %mul, %c
266   ret double %add
267 }
268
269 define float @f91(float %a, float %b, float %c) nounwind readnone {
270 entry:
271 ; CHECK: f91
272 ; CHECK: vmla.f32 s1, s2, s0         @ encoding: [0x00,0x0a,0x41,0xee]
273   %mul = fmul float %a, %b
274   %add = fadd float %mul, %c
275   ret float %add
276 }
277
278 define double @f92(double %a, double %b, double %c) nounwind readnone {
279 entry:
280 ; CHECK: f92
281 ; CHECK: vmls.f64 d16, d18, d17      @ encoding: [0xe1,0x0b,0x42,0xee]
282   %mul = fmul double %a, %b
283   %sub = fsub double %c, %mul
284   ret double %sub
285 }
286
287 define float @f93(float %a, float %b, float %c) nounwind readnone {
288 entry:
289 ; CHECK: f93
290 ; CHECK: vmls.f32 s1, s2, s0         @ encoding: [0x40,0x0a,0x41,0xee]
291   %mul = fmul float %a, %b
292   %sub = fsub float %c, %mul
293   ret float %sub
294 }
295
296 define double @f94(double %a, double %b, double %c) nounwind readnone {
297 entry:
298 ; CHECK: f94
299 ; CHECK: vnmla.f64 d16, d18, d17     @ encoding: [0xe1,0x0b,0x52,0xee]
300   %mul = fmul double %a, %b
301   %sub = fsub double -0.000000e+00, %mul
302   %sub3 = fsub double %sub, %c
303   ret double %sub3
304 }
305
306 define float @f95(float %a, float %b, float %c) nounwind readnone {
307 entry:
308 ; CHECK: f95
309 ; CHECK: vnmla.f32 s1, s2, s0        @ encoding: [0x40,0x0a,0x51,0xee]
310   %mul = fmul float %a, %b
311   %sub = fsub float -0.000000e+00, %mul
312   %sub3 = fsub float %sub, %c
313   ret float %sub3
314 }
315
316 define double @f96(double %a, double %b, double %c) nounwind readnone {
317 entry:
318 ; CHECK: f96
319 ; CHECK: vnmls.f64 d16, d18, d17     @ encoding: [0xa1,0x0b,0x52,0xee]
320   %mul = fmul double %a, %b
321   %sub = fsub double %mul, %c
322   ret double %sub
323 }
324
325 define float @f97(float %a, float %b, float %c) nounwind readnone {
326 entry:
327 ; CHECK: f97
328 ; CHECK: vnmls.f32 s1, s2, s0        @ encoding: [0x00,0x0a,0x51,0xee]
329   %mul = fmul float %a, %b
330   %sub = fsub float %mul, %c
331   ret float %sub
332 }
333
334 ; FIXME: Check for fmstat instruction.
335
336
337 define double @f98(double %a, i32 %i) nounwind readnone {
338 entry:
339   %cmp = icmp eq i32 %i, 3
340   br i1 %cmp, label %return, label %if.end
341
342 if.end:                                           ; preds = %entry
343 ; CHECK: f98
344 ; CHECK: vnegne.f64 d16, d16         @ encoding: [0x60,0x0b,0xf1,0x1e]
345   %sub = fsub double -0.000000e+00, %a
346   ret double %sub
347
348 return:                                           ; preds = %entry
349   ret double %a
350 }
351
352 define float @f99(float %a, float %b, i32 %i) nounwind readnone {
353 entry:
354   %cmp = icmp eq i32 %i, 3
355   br i1 %cmp, label %if.end, label %return
356
357 if.end:                                           ; preds = %entry
358 ; CHECK: f99
359 ; CHECK: vmovne s0, r0               @ encoding: [0x10,0x0a,0x00,0x1e]
360 ; CHECK: vmoveq s0, r1               @ encoding: [0x10,0x1a,0x00,0x0e]
361   ret float %b
362
363 return:                                           ; preds = %entry
364   ret float %a
365 }
366
367
368 define i32 @f100() nounwind readnone {
369 entry:
370 ; CHECK: f100
371 ; CHECK: vmrs r0, fpscr              @ encoding: [0x10,0x0a,0xf1,0xee]
372   %0 = tail call i32 @llvm.arm.get.fpscr()
373   ret i32 %0
374 }
375
376 declare i32 @llvm.arm.get.fpscr() nounwind readnone
377
378 define void @f101(i32 %a) nounwind {
379 entry:
380 ; CHECK: f101
381 ; CHECK: vmsr fpscr, r0              @ encoding: [0x10,0x0a,0xe1,0xee]
382   tail call void @llvm.arm.set.fpscr(i32 %a)
383   ret void
384 }
385
386 declare void @llvm.arm.set.fpscr(i32) nounwind
387
388
389 define double @f102() nounwind readnone {
390 entry:
391 ; CHECK: f102
392 ; CHECK: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee]
393   ret double 3.000000e+00
394 }
395
396 define float @f103(float %a) nounwind readnone {
397 entry:
398 ; CHECK: f103
399 ; CHECK: vmov.f32 s0, #3.000000e+00  @ encoding: [0x08,0x0a,0xb0,0xee]
400   %add = fadd float %a, 3.000000e+00
401   ret float %add
402 }
403
404 define void @f104(float %a, float %b, float %c, float %d, float %e, float %f) nounwind {
405 entry:
406 ; CHECK: f104
407 ; CHECK: vmov s0, r0                 @ encoding: [0x10,0x0a,0x00,0xee]
408 ; CHECK: vmov s1, r1                 @ encoding: [0x90,0x1a,0x00,0xee]
409 ; CHECK: vmov s2, r2                 @ encoding: [0x10,0x2a,0x01,0xee]
410 ; CHECK: vmov s3, r3                 @ encoding: [0x90,0x3a,0x01,0xee]
411   %conv = fptosi float %a to i32
412   %conv2 = fptosi float %b to i32
413   %conv4 = fptosi float %c to i32
414   %conv6 = fptosi float %d to i32
415   %conv8 = fptosi float %e to i32
416   %conv10 = fptosi float %f to i32
417   tail call void @g104(i32 %conv, i32 %conv2, i32 %conv4, i32 %conv6, i32 %conv8, i32 %conv10) nounwind
418 ; CHECK: vmov r0, s0                 @ encoding: [0x10,0x0a,0x10,0xee]
419 ; CHECK: vmov r1, s1                 @ encoding: [0x90,0x1a,0x10,0xee]
420 ; CHECK: vmov r2, s2                 @ encoding: [0x10,0x2a,0x11,0xee]
421 ; CHECK: vmov r3, s3                 @ encoding: [0x90,0x3a,0x11,0xee]
422   ret void
423 }
424
425 declare void @g104(i32, i32, i32, i32, i32, i32)
426
427 define double @f105(i32 %a) nounwind readnone {
428 entry:
429 ; CHECK: f105
430 ; CHECK: vmov r0, r1, d16            @ encoding: [0x30,0x0b,0x51,0xec]
431   %conv = uitofp i32 %a to double
432   ret double %conv
433 }