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