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