[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / CodeGen / fp16-ops.c
blob0626e0aaed9d0c023aacb6341862a5239033321b
1 // REQUIRES: arm-registered-target
2 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
3 // RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
4 // RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK
5 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \
6 // RUN: | FileCheck %s --check-prefix=NATIVE-HALF
7 // RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fnative-half-type %s \
8 // RUN: | FileCheck %s --check-prefix=NATIVE-HALF
9 // RUN: %clang_cc1 -emit-llvm -o - -x renderscript %s \
10 // RUN: | FileCheck %s --check-prefix=NATIVE-HALF
11 typedef unsigned cond_t;
12 typedef __fp16 float16_t;
14 volatile cond_t test;
15 volatile int i0;
16 volatile __fp16 h0 = 0.0, h1 = 1.0, h2;
17 volatile float f0, f1, f2;
18 volatile double d0;
19 short s0;
21 void foo(void) {
22 // CHECK-LABEL: define{{.*}} void @foo()
24 // Check unary ops
26 // NOTNATIVE: [[F16TOF32:fpext half]]
27 // CHECK: fptoui float
28 // NATIVE-HALF: fptoui half
29 test = (h0);
30 // CHECK: uitofp i32
31 // NOTNATIVE: [[F32TOF16:fptrunc float]]
32 // NATIVE-HALF: uitofp i32 {{.*}} to half
33 h0 = (test);
34 // CHECK: [[F16TOF32]]
35 // CHECK: fcmp une float
36 // NATIVE-HALF: fcmp une half
37 test = (!h1);
38 // CHECK: [[F16TOF32]]
39 // CHECK: fneg float
40 // NOTNATIVE: [[F32TOF16]]
41 // NATIVE-HALF: fneg half
42 h1 = -h1;
43 // CHECK: [[F16TOF32]]
44 // CHECK: [[F32TOF16]]
45 // NATIVE-HALF: load volatile half
46 // NATIVE-HALF-NEXT: store volatile half
47 h1 = +h1;
48 // CHECK: [[F16TOF32]]
49 // CHECK: fadd float
50 // CHECK: [[F32TOF16]]
51 // NATIVE-HALF: fadd half
52 h1++;
53 // CHECK: [[F16TOF32]]
54 // CHECK: fadd float
55 // CHECK: [[F32TOF16]]
56 // NATIVE-HALF: fadd half
57 ++h1;
58 // CHECK: [[F16TOF32]]
59 // CHECK: fadd float
60 // CHECK: [[F32TOF16]]
61 // NATIVE-HALF: fadd half
62 --h1;
63 // CHECK: [[F16TOF32]]
64 // CHECK: fadd float
65 // CHECK: [[F32TOF16]]
66 // NATIVE-HALF: fadd half
67 h1--;
69 // Check binary ops with various operands
70 // CHECK: [[F16TOF32]]
71 // CHECK: [[F16TOF32]]
72 // CHECK: fmul float
73 // CHECK: [[F32TOF16]]
74 // NATIVE-HALF: fmul half
75 h1 = h0 * h2;
76 // CHECK: [[F16TOF32]]
77 // CHECK: fmul float
78 // CHECK: [[F32TOF16]]
79 // NATIVE-HALF: fmul half
80 h1 = h0 * (__fp16) -2.0f;
81 // CHECK: [[F16TOF32]]
82 // CHECK: fmul float
83 // CHECK: [[F32TOF16]]
84 // NATIVE-HALF: fpext half
85 // NATIVE-HALF: fmul float
86 h1 = h0 * f2;
87 // CHECK: [[F16TOF32]]
88 // CHECK: fmul float
89 // CHECK: [[F32TOF16]]
90 // NATIVE-HALF: fpext half
91 // NATIVE-HALF: fmul float
92 h1 = f0 * h2;
93 // CHECK: [[F16TOF32]]
94 // CHECK: fmul float
95 // CHECK: [[F32TOF16]]
96 // NATIVE-HALF: fmul half
97 h1 = h0 * i0;
99 // CHECK: [[F16TOF32]]
100 // CHECK: [[F16TOF32]]
101 // CHECK: fdiv float
102 // CHECK: [[F32TOF16]]
103 // NATIVE-HALF: fdiv half
104 h1 = (h0 / h2);
105 // CHECK: [[F16TOF32]]
106 // CHECK: fdiv float
107 // CHECK: [[F32TOF16]]
108 // NATIVE-HALF: fdiv half
109 h1 = (h0 / (__fp16) -2.0f);
110 // CHECK: [[F16TOF32]]
111 // CHECK: fdiv float
112 // CHECK: [[F32TOF16]]
113 // NATIVE-HALF: fpext half
114 // NATIVE-HALF: fdiv float
115 h1 = (h0 / f2);
116 // CHECK: [[F16TOF32]]
117 // CHECK: fdiv float
118 // CHECK: [[F32TOF16]]
119 // NATIVE-HALF: fpext half
120 // NATIVE-HALF: fdiv float
121 h1 = (f0 / h2);
122 // CHECK: [[F16TOF32]]
123 // CHECK: fdiv float
124 // CHECK: [[F32TOF16]]
125 // NATIVE-HALF: fdiv half
126 h1 = (h0 / i0);
128 // CHECK: [[F16TOF32]]
129 // CHECK: [[F16TOF32]]
130 // CHECK: fadd float
131 // CHECK: [[F32TOF16]]
132 // NATIVE-HALF: fadd half
133 h1 = (h2 + h0);
134 // CHECK: [[F16TOF32]]
135 // CHECK: fadd float
136 // CHECK: [[F32TOF16]]
137 // NATIVE-HALF: fadd half
138 h1 = ((__fp16)-2.0 + h0);
139 // CHECK: [[F16TOF32]]
140 // CHECK: fadd float
141 // CHECK: [[F32TOF16]]
142 // NATIVE-HALF: fpext half
143 // NATIVE-HALF: fadd float
144 h1 = (h2 + f0);
145 // CHECK: [[F16TOF32]]
146 // CHECK: fadd float
147 // CHECK: [[F32TOF16]]
148 // NATIVE-HALF: fpext half
149 // NATIVE-HALF: fadd float
150 h1 = (f2 + h0);
151 // CHECK: [[F16TOF32]]
152 // CHECK: fadd float
153 // CHECK: [[F32TOF16]]
154 // NATIVE-HALF: fadd half
155 h1 = (h0 + i0);
157 // CHECK: [[F16TOF32]]
158 // CHECK: [[F16TOF32]]
159 // CHECK: fsub float
160 // CHECK: [[F32TOF16]]
161 // NATIVE-HALF: fsub half
162 h1 = (h2 - h0);
163 // CHECK: [[F16TOF32]]
164 // CHECK: fsub float
165 // CHECK: [[F32TOF16]]
166 // NATIVE-HALF: fsub half
167 h1 = ((__fp16)-2.0f - h0);
168 // CHECK: [[F16TOF32]]
169 // CHECK: fsub float
170 // CHECK: [[F32TOF16]]
171 // NATIVE-HALF: fpext half
172 // NATIVE-HALF: fsub float
173 h1 = (h2 - f0);
174 // CHECK: [[F16TOF32]]
175 // CHECK: fsub float
176 // CHECK: [[F32TOF16]]
177 // NATIVE-HALF: fpext half
178 // NATIVE-HALF: fsub float
179 h1 = (f2 - h0);
180 // CHECK: [[F16TOF32]]
181 // CHECK: fsub float
182 // CHECK: [[F32TOF16]]
183 // NATIVE-HALF: fsub half
184 h1 = (h0 - i0);
186 // CHECK: [[F16TOF32]]
187 // CHECK: [[F16TOF32]]
188 // CHECK: fcmp olt float
189 // NATIVE-HALF: fcmp olt half
190 test = (h2 < h0);
191 // CHECK: [[F16TOF32]]
192 // CHECK: fcmp olt float
193 // NATIVE-HALF: fcmp olt half
194 test = (h2 < (__fp16)42.0);
195 // CHECK: [[F16TOF32]]
196 // CHECK: fcmp olt float
197 // NATIVE-HALF: fpext half
198 // NATIVE-HALF: fcmp olt float
199 test = (h2 < f0);
200 // CHECK: [[F16TOF32]]
201 // CHECK: fcmp olt float
202 // NATIVE-HALF: fpext half
203 // NATIVE-HALF: fcmp olt float
204 test = (f2 < h0);
205 // CHECK: [[F16TOF32]]
206 // CHECK: fcmp olt float
207 // NATIVE-HALF: fcmp olt half
208 test = (i0 < h0);
209 // CHECK: [[F16TOF32]]
210 // CHECK: fcmp olt float
211 // NATIVE-HALF: fcmp olt half
212 test = (h0 < i0);
214 // CHECK: [[F16TOF32]]
215 // CHECK: [[F16TOF32]]
216 // CHECK: fcmp ogt float
217 // NATIVE-HALF: fcmp ogt half
218 test = (h0 > h2);
219 // CHECK: [[F16TOF32]]
220 // CHECK: fcmp ogt float
221 // NATIVE-HALF: fcmp ogt half
222 test = ((__fp16)42.0 > h2);
223 // CHECK: [[F16TOF32]]
224 // CHECK: fcmp ogt float
225 // NATIVE-HALF: fpext half
226 // NATIVE-HALF: fcmp ogt float
227 test = (h0 > f2);
228 // CHECK: [[F16TOF32]]
229 // CHECK: fcmp ogt float
230 // NATIVE-HALF: fpext half
231 // NATIVE-HALF: fcmp ogt float
232 test = (f0 > h2);
233 // CHECK: [[F16TOF32]]
234 // CHECK: fcmp ogt float
235 // NATIVE-HALF: fcmp ogt half
236 test = (i0 > h0);
237 // CHECK: [[F16TOF32]]
238 // CHECK: fcmp ogt float
239 // NATIVE-HALF: fcmp ogt half
240 test = (h0 > i0);
242 // CHECK: [[F16TOF32]]
243 // CHECK: [[F16TOF32]]
244 // CHECK: fcmp ole float
245 // NATIVE-HALF: fcmp ole half
246 test = (h2 <= h0);
247 // CHECK: [[F16TOF32]]
248 // CHECK: fcmp ole float
249 // NATIVE-HALF: fcmp ole half
250 test = (h2 <= (__fp16)42.0);
251 // CHECK: [[F16TOF32]]
252 // CHECK: fcmp ole float
253 // NATIVE-HALF: fpext half
254 // NATIVE-HALF: fcmp ole float
255 test = (h2 <= f0);
256 // CHECK: [[F16TOF32]]
257 // CHECK: fcmp ole float
258 // NATIVE-HALF: fpext half
259 // NATIVE-HALF: fcmp ole float
260 test = (f2 <= h0);
261 // CHECK: [[F16TOF32]]
262 // CHECK: fcmp ole float
263 // NATIVE-HALF: fcmp ole half
264 test = (i0 <= h0);
265 // CHECK: [[F16TOF32]]
266 // CHECK: fcmp ole float
267 // NATIVE-HALF: fcmp ole half
268 test = (h0 <= i0);
271 // CHECK: [[F16TOF32]]
272 // CHECK: [[F16TOF32]]
273 // CHECK: fcmp oge float
274 // NATIVE-HALF: fcmp oge half
275 test = (h0 >= h2);
276 // CHECK: [[F16TOF32]]
277 // CHECK: fcmp oge float
278 // NATIVE-HALF: fcmp oge half
279 test = (h0 >= (__fp16)-2.0);
280 // CHECK: [[F16TOF32]]
281 // CHECK: fcmp oge float
282 // NATIVE-HALF: fpext half
283 // NATIVE-HALF: fcmp oge float
284 test = (h0 >= f2);
285 // CHECK: [[F16TOF32]]
286 // CHECK: fcmp oge float
287 // NATIVE-HALF: fpext half
288 // NATIVE-HALF: fcmp oge float
289 test = (f0 >= h2);
290 // CHECK: [[F16TOF32]]
291 // CHECK: fcmp oge float
292 // NATIVE-HALF: fcmp oge half
293 test = (i0 >= h0);
294 // CHECK: [[F16TOF32]]
295 // CHECK: fcmp oge float
296 // NATIVE-HALF: fcmp oge half
297 test = (h0 >= i0);
299 // CHECK: [[F16TOF32]]
300 // CHECK: [[F16TOF32]]
301 // CHECK: fcmp oeq float
302 // NATIVE-HALF: fcmp oeq half
303 test = (h1 == h2);
304 // CHECK: [[F16TOF32]]
305 // CHECK: fcmp oeq float
306 // NATIVE-HALF: fcmp oeq half
307 test = (h1 == (__fp16)1.0);
308 // CHECK: [[F16TOF32]]
309 // CHECK: fcmp oeq float
310 // NATIVE-HALF: fpext half
311 // NATIVE-HALF: fcmp oeq float
312 test = (h1 == f1);
313 // CHECK: [[F16TOF32]]
314 // CHECK: fcmp oeq float
315 // NATIVE-HALF: fpext half
316 // NATIVE-HALF: fcmp oeq float
317 test = (f1 == h1);
318 // CHECK: [[F16TOF32]]
319 // CHECK: fcmp oeq float
320 // NATIVE-HALF: fcmp oeq half
321 test = (i0 == h0);
322 // CHECK: [[F16TOF32]]
323 // CHECK: fcmp oeq float
324 // NATIVE-HALF: fcmp oeq half
325 test = (h0 == i0);
327 // CHECK: [[F16TOF32]]
328 // CHECK: [[F16TOF32]]
329 // CHECK: fcmp une float
330 // NATIVE-HALF: fcmp une half
331 test = (h1 != h2);
332 // CHECK: [[F16TOF32]]
333 // CHECK: fcmp une float
334 // NATIVE-HALF: fcmp une half
335 test = (h1 != (__fp16)1.0);
336 // CHECK: [[F16TOF32]]
337 // CHECK: fcmp une float
338 // NATIVE-HALF: fpext half
339 // NATIVE-HALF: fcmp une float
340 test = (h1 != f1);
341 // CHECK: [[F16TOF32]]
342 // CHECK: fcmp une float
343 // NATIVE-HALF: fpext half
344 // NATIVE-HALF: fcmp une float
345 test = (f1 != h1);
346 // CHECK: [[F16TOF32]]
347 // CHECK: fcmp une float
348 // NATIVE-HALF: fcmp une half
349 test = (i0 != h0);
350 // CHECK: [[F16TOF32]]
351 // CHECK: fcmp une float
352 // NATIVE-HALF: fcmp une half
353 test = (h0 != i0);
355 // CHECK: [[F16TOF32]]
356 // CHECK: fcmp une float
357 // CHECK: [[F16TOF32]]
358 // CHECK: [[F16TOF32]]
359 // CHECK: [[F32TOF16]]
360 // NATIVE-HALF: fcmp une half {{.*}}, 0xH0000
361 h1 = (h1 ? h2 : h0);
362 // Check assignments (inc. compound)
363 h0 = h1;
364 // NOTNATIVE: store {{.*}} half 0xHC000
365 // NATIVE-HALF: store {{.*}} half 0xHC000
366 h0 = (__fp16)-2.0f;
367 // CHECK: [[F32TOF16]]
368 // NATIVE-HALF: fptrunc float
369 h0 = f0;
371 // CHECK: sitofp i32 {{.*}} to float
372 // CHECK: [[F32TOF16]]
373 // NATIVE-HALF: sitofp i32 {{.*}} to half
374 h0 = i0;
375 // CHECK: [[F16TOF32]]
376 // CHECK: fptosi float {{.*}} to i32
377 // NATIVE-HALF: fptosi half {{.*}} to i32
378 i0 = h0;
380 // CHECK: [[F16TOF32]]
381 // CHECK: [[F16TOF32]]
382 // CHECK: fadd float
383 // CHECK: [[F32TOF16]]
384 // NATIVE-HALF: fadd half
385 h0 += h1;
386 // CHECK: [[F16TOF32]]
387 // CHECK: fadd float
388 // CHECK: [[F32TOF16]]
389 // NATIVE-HALF: fadd half
390 h0 += (__fp16)1.0f;
391 // CHECK: [[F16TOF32]]
392 // CHECK: fadd float
393 // CHECK: [[F32TOF16]]
394 // NATIVE-HALF: fpext half
395 // NATIVE-HALF: fadd float
396 // NATIVE-HALF: fptrunc float
397 h0 += f2;
398 // CHECK: [[F16TOF32]]
399 // CHECK: sitofp i32 {{.*}} to float
400 // CHECK: fadd float
401 // CHECK: fptosi float {{.*}} to i32
402 // NATIVE-HALF: sitofp i32 {{.*}} to half
403 // NATIVE-HALF: fadd half
404 // NATIVE-HALF: fptosi half {{.*}} to i32
405 i0 += h0;
406 // CHECK: sitofp i32 {{.*}} to float
407 // CHECK: [[F16TOF32]]
408 // CHECK: fadd float
409 // CHECK: [[F32TOF16]]
410 // NATIVE-HALF: sitofp i32 {{.*}} to half
411 // NATIVE-HALF: fadd half
412 h0 += i0;
414 // CHECK: [[F16TOF32]]
415 // CHECK: [[F16TOF32]]
416 // CHECK: fsub float
417 // CHECK: [[F32TOF16]]
418 // NATIVE-HALF: fsub half
419 h0 -= h1;
420 // CHECK: [[F16TOF32]]
421 // CHECK: fsub float
422 // CHECK: [[F32TOF16]]
423 // NATIVE-HALF: fsub half
424 h0 -= (__fp16)1.0;
425 // CHECK: [[F16TOF32]]
426 // CHECK: fsub float
427 // CHECK: [[F32TOF16]]
428 // NATIVE-HALF: fpext half
429 // NATIVE-HALF: fsub float
430 // NATIVE-HALF: fptrunc float
431 h0 -= f2;
432 // CHECK: [[F16TOF32]]
433 // CHECK: sitofp i32 {{.*}} to float
434 // CHECK: fsub float
435 // CHECK: fptosi float {{.*}} to i32
436 // NATIVE-HALF: sitofp i32 {{.*}} to half
437 // NATIVE-HALF: fsub half
438 // NATIVE-HALF: fptosi half {{.*}} to i32
439 i0 -= h0;
440 // CHECK: sitofp i32 {{.*}} to float
441 // CHECK: [[F16TOF32]]
442 // CHECK: fsub float
443 // CHECK: [[F32TOF16]]
444 // NATIVE-HALF: sitofp i32 {{.*}} to half
445 // NATIVE-HALF: fsub half
446 h0 -= i0;
448 // CHECK: [[F16TOF32]]
449 // CHECK: [[F16TOF32]]
450 // CHECK: fmul float
451 // CHECK: [[F32TOF16]]
452 // NATIVE-HALF: fmul half
453 h0 *= h1;
454 // CHECK: [[F16TOF32]]
455 // CHECK: fmul float
456 // CHECK: [[F32TOF16]]
457 // NATIVE-HALF: fmul half
458 h0 *= (__fp16)1.0;
459 // CHECK: [[F16TOF32]]
460 // CHECK: fmul float
461 // CHECK: [[F32TOF16]]
462 // NATIVE-HALF: fpext half
463 // NATIVE-HALF: fmul float
464 // NATIVE-HALF: fptrunc float
465 h0 *= f2;
466 // CHECK: [[F16TOF32]]
467 // CHECK: sitofp i32 {{.*}} to float
468 // CHECK: fmul float
469 // CHECK: fptosi float {{.*}} to i32
470 // NATIVE-HALF: sitofp i32 {{.*}} to half
471 // NATIVE-HALF: fmul half
472 // NATIVE-HALF: fptosi half {{.*}} to i32
473 i0 *= h0;
474 // CHECK: sitofp i32 {{.*}} to float
475 // CHECK: [[F16TOF32]]
476 // CHECK: fmul float
477 // CHECK: [[F32TOF16]]
478 // NATIVE-HALF: sitofp i32 {{.*}} to half
479 // NATIVE-HALF: fmul half
480 h0 *= i0;
482 // CHECK: [[F16TOF32]]
483 // CHECK: [[F16TOF32]]
484 // CHECK: fdiv float
485 // CHECK: [[F32TOF16]]
486 // NATIVE-HALF: fdiv half
487 h0 /= h1;
488 // CHECK: [[F16TOF32]]
489 // CHECK: fdiv float
490 // CHECK: [[F32TOF16]]
491 // NATIVE-HALF: fdiv half
492 h0 /= (__fp16)1.0;
493 // CHECK: [[F16TOF32]]
494 // CHECK: fdiv float
495 // CHECK: [[F32TOF16]]
496 // NATIVE-HALF: fpext half
497 // NATIVE-HALF: fdiv float
498 // NATIVE-HALF: fptrunc float
499 h0 /= f2;
500 // CHECK: [[F16TOF32]]
501 // CHECK: sitofp i32 {{.*}} to float
502 // CHECK: fdiv float
503 // CHECK: fptosi float {{.*}} to i32
504 // NATIVE-HALF: sitofp i32 {{.*}} to half
505 // NATIVE-HALF: fdiv half
506 // NATIVE-HALF: fptosi half {{.*}} to i32
507 i0 /= h0;
508 // CHECK: sitofp i32 {{.*}} to float
509 // CHECK: [[F16TOF32]]
510 // CHECK: fdiv float
511 // CHECK: [[F32TOF16]]
512 // NATIVE-HALF: sitofp i32 {{.*}} to half
513 // NATIVE-HALF: fdiv half
514 h0 /= i0;
516 // Check conversions to/from double
517 // NOTNATIVE: fptrunc double {{.*}} to half
518 // NATIVE-HALF: fptrunc double {{.*}} to half
519 h0 = d0;
521 // CHECK: [[MID:%.*]] = fptrunc double {{%.*}} to float
522 // NOTNATIVE: fptrunc float [[MID]] to half
523 // NATIVE-HALF: [[MID:%.*]] = fptrunc double {{%.*}} to float
524 // NATIVE-HALF: fptrunc float {{.*}} to half
525 h0 = (float)d0;
527 // NOTNATIVE: fpext half {{.*}} to double
528 // NATIVE-HALF: fpext half {{.*}} to double
529 d0 = h0;
531 // NOTNATIVE: [[MID:%.*]] = fpext half {{.*}} to float
532 // CHECK: fpext float [[MID]] to double
533 // NATIVE-HALF: [[MID:%.*]] = fpext half {{.*}} to float
534 // NATIVE-HALF: fpext float [[MID]] to double
535 d0 = (float)h0;
537 // NOTNATIVE: [[V1:%.*]] = load i16, ptr @s0
538 // NOTNATIVE: [[CONV:%.*]] = sitofp i16 [[V1]] to float
539 // NOTNATIVE: [[TRUNC:%.*]] = fptrunc float [[CONV]] to half
540 // NOTNATIVE: store volatile half [[TRUNC]], ptr @h0
541 h0 = s0;
544 // CHECK-LABEL: define{{.*}} void @testTypeDef(
545 // CHECK: %[[CONV:.*]] = fpext <4 x half> %{{.*}} to <4 x float>
546 // CHECK: %[[CONV1:.*]] = fpext <4 x half> %{{.*}} to <4 x float>
547 // CHECK: %[[ADD:.*]] = fadd <4 x float> %[[CONV]], %[[CONV1]]
548 // CHECK: fptrunc <4 x float> %[[ADD]] to <4 x half>
550 void testTypeDef() {
551 __fp16 t0 __attribute__((vector_size(8)));
552 float16_t t1 __attribute__((vector_size(8)));
553 t1 = t0 + t1;