553 lines · c
1// REQUIRES: arm-registered-target2// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK3// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64 %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK4// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-gnu %s | FileCheck %s --check-prefix=NOTNATIVE --check-prefix=CHECK5// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \6// RUN: | FileCheck %s --check-prefix=NATIVE-HALF7// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64 -fnative-half-type %s \8// RUN: | FileCheck %s --check-prefix=NATIVE-HALF9typedef unsigned cond_t;10typedef __fp16 float16_t;11 12volatile cond_t test;13volatile int i0;14volatile __fp16 h0 = 0.0, h1 = 1.0, h2;15volatile float f0, f1, f2;16volatile double d0;17short s0;18 19void foo(void) {20 // CHECK-LABEL: define{{.*}} void @foo()21 22 // Check unary ops23 24 // NOTNATIVE: [[F16TOF32:fpext half]]25 // CHECK: fptoui float26 // NATIVE-HALF: fptoui half27 test = (h0);28 // CHECK: uitofp i3229 // NOTNATIVE: [[F32TOF16:fptrunc float]]30 // NATIVE-HALF: uitofp i32 {{.*}} to half31 h0 = (test);32 // CHECK: [[F16TOF32]]33 // CHECK: fcmp une float34 // NATIVE-HALF: fcmp une half35 test = (!h1);36 // CHECK: [[F16TOF32]]37 // CHECK: fneg float38 // NOTNATIVE: [[F32TOF16]]39 // NATIVE-HALF: fneg half40 h1 = -h1;41 // CHECK: [[F16TOF32]]42 // CHECK: [[F32TOF16]]43 // NATIVE-HALF: load volatile half44 // NATIVE-HALF-NEXT: store volatile half45 h1 = +h1;46 // CHECK: [[F16TOF32]]47 // CHECK: fadd float48 // CHECK: [[F32TOF16]]49 // NATIVE-HALF: fadd half50 h1++;51 // CHECK: [[F16TOF32]]52 // CHECK: fadd float53 // CHECK: [[F32TOF16]]54 // NATIVE-HALF: fadd half55 ++h1;56 // CHECK: [[F16TOF32]]57 // CHECK: fadd float58 // CHECK: [[F32TOF16]]59 // NATIVE-HALF: fadd half60 --h1;61 // CHECK: [[F16TOF32]]62 // CHECK: fadd float63 // CHECK: [[F32TOF16]]64 // NATIVE-HALF: fadd half65 h1--;66 67 // Check binary ops with various operands68 // CHECK: [[F16TOF32]]69 // CHECK: [[F16TOF32]]70 // CHECK: fmul float71 // CHECK: [[F32TOF16]]72 // NATIVE-HALF: fmul half73 h1 = h0 * h2;74 // CHECK: [[F16TOF32]]75 // CHECK: fmul float76 // CHECK: [[F32TOF16]]77 // NATIVE-HALF: fmul half78 h1 = h0 * (__fp16) -2.0f;79 // CHECK: [[F16TOF32]]80 // CHECK: fmul float81 // CHECK: [[F32TOF16]]82 // NATIVE-HALF: fpext half83 // NATIVE-HALF: fmul float84 h1 = h0 * f2;85 // CHECK: [[F16TOF32]]86 // CHECK: fmul float87 // CHECK: [[F32TOF16]]88 // NATIVE-HALF: fpext half89 // NATIVE-HALF: fmul float90 h1 = f0 * h2;91 // CHECK: [[F16TOF32]]92 // CHECK: fmul float93 // CHECK: [[F32TOF16]]94 // NATIVE-HALF: fmul half95 h1 = h0 * i0;96 97 // CHECK: [[F16TOF32]]98 // CHECK: [[F16TOF32]]99 // CHECK: fdiv float100 // CHECK: [[F32TOF16]]101 // NATIVE-HALF: fdiv half102 h1 = (h0 / h2);103 // CHECK: [[F16TOF32]]104 // CHECK: fdiv float105 // CHECK: [[F32TOF16]]106 // NATIVE-HALF: fdiv half107 h1 = (h0 / (__fp16) -2.0f);108 // CHECK: [[F16TOF32]]109 // CHECK: fdiv float110 // CHECK: [[F32TOF16]]111 // NATIVE-HALF: fpext half112 // NATIVE-HALF: fdiv float113 h1 = (h0 / f2);114 // CHECK: [[F16TOF32]]115 // CHECK: fdiv float116 // CHECK: [[F32TOF16]]117 // NATIVE-HALF: fpext half118 // NATIVE-HALF: fdiv float119 h1 = (f0 / h2);120 // CHECK: [[F16TOF32]]121 // CHECK: fdiv float122 // CHECK: [[F32TOF16]]123 // NATIVE-HALF: fdiv half124 h1 = (h0 / i0);125 126 // CHECK: [[F16TOF32]]127 // CHECK: [[F16TOF32]]128 // CHECK: fadd float129 // CHECK: [[F32TOF16]]130 // NATIVE-HALF: fadd half131 h1 = (h2 + h0);132 // CHECK: [[F16TOF32]]133 // CHECK: fadd float134 // CHECK: [[F32TOF16]]135 // NATIVE-HALF: fadd half136 h1 = ((__fp16)-2.0 + h0);137 // CHECK: [[F16TOF32]]138 // CHECK: fadd float139 // CHECK: [[F32TOF16]]140 // NATIVE-HALF: fpext half141 // NATIVE-HALF: fadd float142 h1 = (h2 + f0);143 // CHECK: [[F16TOF32]]144 // CHECK: fadd float145 // CHECK: [[F32TOF16]]146 // NATIVE-HALF: fpext half147 // NATIVE-HALF: fadd float148 h1 = (f2 + h0);149 // CHECK: [[F16TOF32]]150 // CHECK: fadd float151 // CHECK: [[F32TOF16]]152 // NATIVE-HALF: fadd half153 h1 = (h0 + i0);154 155 // CHECK: [[F16TOF32]]156 // CHECK: [[F16TOF32]]157 // CHECK: fsub float158 // CHECK: [[F32TOF16]]159 // NATIVE-HALF: fsub half160 h1 = (h2 - h0);161 // CHECK: [[F16TOF32]]162 // CHECK: fsub float163 // CHECK: [[F32TOF16]]164 // NATIVE-HALF: fsub half165 h1 = ((__fp16)-2.0f - h0);166 // CHECK: [[F16TOF32]]167 // CHECK: fsub float168 // CHECK: [[F32TOF16]]169 // NATIVE-HALF: fpext half170 // NATIVE-HALF: fsub float171 h1 = (h2 - f0);172 // CHECK: [[F16TOF32]]173 // CHECK: fsub float174 // CHECK: [[F32TOF16]]175 // NATIVE-HALF: fpext half176 // NATIVE-HALF: fsub float177 h1 = (f2 - h0);178 // CHECK: [[F16TOF32]]179 // CHECK: fsub float180 // CHECK: [[F32TOF16]]181 // NATIVE-HALF: fsub half182 h1 = (h0 - i0);183 184 // CHECK: [[F16TOF32]]185 // CHECK: [[F16TOF32]]186 // CHECK: fcmp olt float187 // NATIVE-HALF: fcmp olt half188 test = (h2 < h0);189 // CHECK: [[F16TOF32]]190 // CHECK: fcmp olt float191 // NATIVE-HALF: fcmp olt half192 test = (h2 < (__fp16)42.0);193 // CHECK: [[F16TOF32]]194 // CHECK: fcmp olt float195 // NATIVE-HALF: fpext half196 // NATIVE-HALF: fcmp olt float197 test = (h2 < f0);198 // CHECK: [[F16TOF32]]199 // CHECK: fcmp olt float200 // NATIVE-HALF: fpext half201 // NATIVE-HALF: fcmp olt float202 test = (f2 < h0);203 // CHECK: [[F16TOF32]]204 // CHECK: fcmp olt float205 // NATIVE-HALF: fcmp olt half206 test = (i0 < h0);207 // CHECK: [[F16TOF32]]208 // CHECK: fcmp olt float209 // NATIVE-HALF: fcmp olt half210 test = (h0 < i0);211 212 // CHECK: [[F16TOF32]]213 // CHECK: [[F16TOF32]]214 // CHECK: fcmp ogt float215 // NATIVE-HALF: fcmp ogt half216 test = (h0 > h2);217 // CHECK: [[F16TOF32]]218 // CHECK: fcmp ogt float219 // NATIVE-HALF: fcmp ogt half220 test = ((__fp16)42.0 > h2);221 // CHECK: [[F16TOF32]]222 // CHECK: fcmp ogt float223 // NATIVE-HALF: fpext half224 // NATIVE-HALF: fcmp ogt float225 test = (h0 > f2);226 // CHECK: [[F16TOF32]]227 // CHECK: fcmp ogt float228 // NATIVE-HALF: fpext half229 // NATIVE-HALF: fcmp ogt float230 test = (f0 > h2);231 // CHECK: [[F16TOF32]]232 // CHECK: fcmp ogt float233 // NATIVE-HALF: fcmp ogt half234 test = (i0 > h0);235 // CHECK: [[F16TOF32]]236 // CHECK: fcmp ogt float237 // NATIVE-HALF: fcmp ogt half238 test = (h0 > i0);239 240 // CHECK: [[F16TOF32]]241 // CHECK: [[F16TOF32]]242 // CHECK: fcmp ole float243 // NATIVE-HALF: fcmp ole half244 test = (h2 <= h0);245 // CHECK: [[F16TOF32]]246 // CHECK: fcmp ole float247 // NATIVE-HALF: fcmp ole half248 test = (h2 <= (__fp16)42.0);249 // CHECK: [[F16TOF32]]250 // CHECK: fcmp ole float251 // NATIVE-HALF: fpext half252 // NATIVE-HALF: fcmp ole float253 test = (h2 <= f0);254 // CHECK: [[F16TOF32]]255 // CHECK: fcmp ole float256 // NATIVE-HALF: fpext half257 // NATIVE-HALF: fcmp ole float258 test = (f2 <= h0);259 // CHECK: [[F16TOF32]]260 // CHECK: fcmp ole float261 // NATIVE-HALF: fcmp ole half262 test = (i0 <= h0);263 // CHECK: [[F16TOF32]]264 // CHECK: fcmp ole float265 // NATIVE-HALF: fcmp ole half266 test = (h0 <= i0);267 268 269 // CHECK: [[F16TOF32]]270 // CHECK: [[F16TOF32]]271 // CHECK: fcmp oge float272 // NATIVE-HALF: fcmp oge half273 test = (h0 >= h2);274 // CHECK: [[F16TOF32]]275 // CHECK: fcmp oge float276 // NATIVE-HALF: fcmp oge half277 test = (h0 >= (__fp16)-2.0);278 // CHECK: [[F16TOF32]]279 // CHECK: fcmp oge float280 // NATIVE-HALF: fpext half281 // NATIVE-HALF: fcmp oge float282 test = (h0 >= f2);283 // CHECK: [[F16TOF32]]284 // CHECK: fcmp oge float285 // NATIVE-HALF: fpext half286 // NATIVE-HALF: fcmp oge float287 test = (f0 >= h2);288 // CHECK: [[F16TOF32]]289 // CHECK: fcmp oge float290 // NATIVE-HALF: fcmp oge half291 test = (i0 >= h0);292 // CHECK: [[F16TOF32]]293 // CHECK: fcmp oge float294 // NATIVE-HALF: fcmp oge half295 test = (h0 >= i0);296 297 // CHECK: [[F16TOF32]]298 // CHECK: [[F16TOF32]]299 // CHECK: fcmp oeq float300 // NATIVE-HALF: fcmp oeq half301 test = (h1 == h2);302 // CHECK: [[F16TOF32]]303 // CHECK: fcmp oeq float304 // NATIVE-HALF: fcmp oeq half305 test = (h1 == (__fp16)1.0);306 // CHECK: [[F16TOF32]]307 // CHECK: fcmp oeq float308 // NATIVE-HALF: fpext half309 // NATIVE-HALF: fcmp oeq float310 test = (h1 == f1);311 // CHECK: [[F16TOF32]]312 // CHECK: fcmp oeq float313 // NATIVE-HALF: fpext half314 // NATIVE-HALF: fcmp oeq float315 test = (f1 == h1);316 // CHECK: [[F16TOF32]]317 // CHECK: fcmp oeq float318 // NATIVE-HALF: fcmp oeq half319 test = (i0 == h0);320 // CHECK: [[F16TOF32]]321 // CHECK: fcmp oeq float322 // NATIVE-HALF: fcmp oeq half323 test = (h0 == i0);324 325 // CHECK: [[F16TOF32]]326 // CHECK: [[F16TOF32]]327 // CHECK: fcmp une float328 // NATIVE-HALF: fcmp une half329 test = (h1 != h2);330 // CHECK: [[F16TOF32]]331 // CHECK: fcmp une float332 // NATIVE-HALF: fcmp une half333 test = (h1 != (__fp16)1.0);334 // CHECK: [[F16TOF32]]335 // CHECK: fcmp une float336 // NATIVE-HALF: fpext half337 // NATIVE-HALF: fcmp une float338 test = (h1 != f1);339 // CHECK: [[F16TOF32]]340 // CHECK: fcmp une float341 // NATIVE-HALF: fpext half342 // NATIVE-HALF: fcmp une float343 test = (f1 != h1);344 // CHECK: [[F16TOF32]]345 // CHECK: fcmp une float346 // NATIVE-HALF: fcmp une half347 test = (i0 != h0);348 // CHECK: [[F16TOF32]]349 // CHECK: fcmp une float350 // NATIVE-HALF: fcmp une half351 test = (h0 != i0);352 353 // CHECK: [[F16TOF32]]354 // CHECK: fcmp une float355 // CHECK: [[F16TOF32]]356 // CHECK: [[F16TOF32]]357 // CHECK: [[F32TOF16]]358 // NATIVE-HALF: fcmp une half {{.*}}, 0xH0000359 h1 = (h1 ? h2 : h0);360 // Check assignments (inc. compound)361 h0 = h1;362 // NOTNATIVE: store {{.*}} half 0xHC000363 // NATIVE-HALF: store {{.*}} half 0xHC000364 h0 = (__fp16)-2.0f;365 // CHECK: [[F32TOF16]]366 // NATIVE-HALF: fptrunc float367 h0 = f0;368 369 // CHECK: sitofp i32 {{.*}} to float370 // CHECK: [[F32TOF16]]371 // NATIVE-HALF: sitofp i32 {{.*}} to half372 h0 = i0;373 // CHECK: [[F16TOF32]]374 // CHECK: fptosi float {{.*}} to i32375 // NATIVE-HALF: fptosi half {{.*}} to i32376 i0 = h0;377 378 // CHECK: [[F16TOF32]]379 // CHECK: [[F16TOF32]]380 // CHECK: fadd float381 // CHECK: [[F32TOF16]]382 // NATIVE-HALF: fadd half383 h0 += h1;384 // CHECK: [[F16TOF32]]385 // CHECK: fadd float386 // CHECK: [[F32TOF16]]387 // NATIVE-HALF: fadd half388 h0 += (__fp16)1.0f;389 // CHECK: [[F16TOF32]]390 // CHECK: fadd float391 // CHECK: [[F32TOF16]]392 // NATIVE-HALF: fpext half393 // NATIVE-HALF: fadd float394 // NATIVE-HALF: fptrunc float395 h0 += f2;396 // CHECK: [[F16TOF32]]397 // CHECK: sitofp i32 {{.*}} to float398 // CHECK: fadd float399 // CHECK: fptosi float {{.*}} to i32400 // NATIVE-HALF: sitofp i32 {{.*}} to half401 // NATIVE-HALF: fadd half402 // NATIVE-HALF: fptosi half {{.*}} to i32403 i0 += h0;404 // CHECK: sitofp i32 {{.*}} to float405 // CHECK: [[F16TOF32]]406 // CHECK: fadd float407 // CHECK: [[F32TOF16]]408 // NATIVE-HALF: sitofp i32 {{.*}} to half409 // NATIVE-HALF: fadd half410 h0 += i0;411 412 // CHECK: [[F16TOF32]]413 // CHECK: [[F16TOF32]]414 // CHECK: fsub float415 // CHECK: [[F32TOF16]]416 // NATIVE-HALF: fsub half417 h0 -= h1;418 // CHECK: [[F16TOF32]]419 // CHECK: fsub float420 // CHECK: [[F32TOF16]]421 // NATIVE-HALF: fsub half422 h0 -= (__fp16)1.0;423 // CHECK: [[F16TOF32]]424 // CHECK: fsub float425 // CHECK: [[F32TOF16]]426 // NATIVE-HALF: fpext half427 // NATIVE-HALF: fsub float428 // NATIVE-HALF: fptrunc float429 h0 -= f2;430 // CHECK: [[F16TOF32]]431 // CHECK: sitofp i32 {{.*}} to float432 // CHECK: fsub float433 // CHECK: fptosi float {{.*}} to i32434 // NATIVE-HALF: sitofp i32 {{.*}} to half435 // NATIVE-HALF: fsub half436 // NATIVE-HALF: fptosi half {{.*}} to i32437 i0 -= h0;438 // CHECK: sitofp i32 {{.*}} to float439 // CHECK: [[F16TOF32]]440 // CHECK: fsub float441 // CHECK: [[F32TOF16]]442 // NATIVE-HALF: sitofp i32 {{.*}} to half443 // NATIVE-HALF: fsub half444 h0 -= i0;445 446 // CHECK: [[F16TOF32]]447 // CHECK: [[F16TOF32]]448 // CHECK: fmul float449 // CHECK: [[F32TOF16]]450 // NATIVE-HALF: fmul half451 h0 *= h1;452 // CHECK: [[F16TOF32]]453 // CHECK: fmul float454 // CHECK: [[F32TOF16]]455 // NATIVE-HALF: fmul half456 h0 *= (__fp16)1.0;457 // CHECK: [[F16TOF32]]458 // CHECK: fmul float459 // CHECK: [[F32TOF16]]460 // NATIVE-HALF: fpext half461 // NATIVE-HALF: fmul float462 // NATIVE-HALF: fptrunc float463 h0 *= f2;464 // CHECK: [[F16TOF32]]465 // CHECK: sitofp i32 {{.*}} to float466 // CHECK: fmul float467 // CHECK: fptosi float {{.*}} to i32468 // NATIVE-HALF: sitofp i32 {{.*}} to half469 // NATIVE-HALF: fmul half470 // NATIVE-HALF: fptosi half {{.*}} to i32471 i0 *= h0;472 // CHECK: sitofp i32 {{.*}} to float473 // CHECK: [[F16TOF32]]474 // CHECK: fmul float475 // CHECK: [[F32TOF16]]476 // NATIVE-HALF: sitofp i32 {{.*}} to half477 // NATIVE-HALF: fmul half478 h0 *= i0;479 480 // CHECK: [[F16TOF32]]481 // CHECK: [[F16TOF32]]482 // CHECK: fdiv float483 // CHECK: [[F32TOF16]]484 // NATIVE-HALF: fdiv half485 h0 /= h1;486 // CHECK: [[F16TOF32]]487 // CHECK: fdiv float488 // CHECK: [[F32TOF16]]489 // NATIVE-HALF: fdiv half490 h0 /= (__fp16)1.0;491 // CHECK: [[F16TOF32]]492 // CHECK: fdiv float493 // CHECK: [[F32TOF16]]494 // NATIVE-HALF: fpext half495 // NATIVE-HALF: fdiv float496 // NATIVE-HALF: fptrunc float497 h0 /= f2;498 // CHECK: [[F16TOF32]]499 // CHECK: sitofp i32 {{.*}} to float500 // CHECK: fdiv float501 // CHECK: fptosi float {{.*}} to i32502 // NATIVE-HALF: sitofp i32 {{.*}} to half503 // NATIVE-HALF: fdiv half504 // NATIVE-HALF: fptosi half {{.*}} to i32505 i0 /= h0;506 // CHECK: sitofp i32 {{.*}} to float507 // CHECK: [[F16TOF32]]508 // CHECK: fdiv float509 // CHECK: [[F32TOF16]]510 // NATIVE-HALF: sitofp i32 {{.*}} to half511 // NATIVE-HALF: fdiv half512 h0 /= i0;513 514 // Check conversions to/from double515 // NOTNATIVE: fptrunc double {{.*}} to half516 // NATIVE-HALF: fptrunc double {{.*}} to half517 h0 = d0;518 519 // CHECK: [[MID:%.*]] = fptrunc double {{%.*}} to float520 // NOTNATIVE: fptrunc float [[MID]] to half521 // NATIVE-HALF: [[MID:%.*]] = fptrunc double {{%.*}} to float522 // NATIVE-HALF: fptrunc float {{.*}} to half523 h0 = (float)d0;524 525 // NOTNATIVE: fpext half {{.*}} to double526 // NATIVE-HALF: fpext half {{.*}} to double527 d0 = h0;528 529 // NOTNATIVE: [[MID:%.*]] = fpext half {{.*}} to float530 // CHECK: fpext float [[MID]] to double531 // NATIVE-HALF: [[MID:%.*]] = fpext half {{.*}} to float532 // NATIVE-HALF: fpext float [[MID]] to double533 d0 = (float)h0;534 535 // NOTNATIVE: [[V1:%.*]] = load i16, ptr @s0536 // NOTNATIVE: [[CONV:%.*]] = sitofp i16 [[V1]] to float537 // NOTNATIVE: [[TRUNC:%.*]] = fptrunc float [[CONV]] to half538 // NOTNATIVE: store volatile half [[TRUNC]], ptr @h0539 h0 = s0;540}541 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>547 548void testTypeDef() {549 __fp16 t0 __attribute__((vector_size(8)));550 float16_t t1 __attribute__((vector_size(8)));551 t1 = t0 + t1;552}553