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