1 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefix=X86 2 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s --check-prefix=X86 3 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s --check-prefix=X86 4 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s --check-prefix=PPC 5 // RUN %clang_cc1 %s -O1 -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM 6 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARMHF 7 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K 8 9 float _Complex add_float_rr(float a, float b) { 10 // X86-LABEL: @add_float_rr( 11 // X86: fadd 12 // X86-NOT: fadd 13 // X86: ret 14 return a + b; 15 } 16 float _Complex add_float_cr(float _Complex a, float b) { 17 // X86-LABEL: @add_float_cr( 18 // X86: fadd 19 // X86-NOT: fadd 20 // X86: ret 21 return a + b; 22 } 23 float _Complex add_float_rc(float a, float _Complex b) { 24 // X86-LABEL: @add_float_rc( 25 // X86: fadd 26 // X86-NOT: fadd 27 // X86: ret 28 return a + b; 29 } 30 float _Complex add_float_cc(float _Complex a, float _Complex b) { 31 // X86-LABEL: @add_float_cc( 32 // X86: fadd 33 // X86: fadd 34 // X86-NOT: fadd 35 // X86: ret 36 return a + b; 37 } 38 39 float _Complex sub_float_rr(float a, float b) { 40 // X86-LABEL: @sub_float_rr( 41 // X86: fsub 42 // X86-NOT: fsub 43 // X86: ret 44 return a - b; 45 } 46 float _Complex sub_float_cr(float _Complex a, float b) { 47 // X86-LABEL: @sub_float_cr( 48 // X86: fsub 49 // X86-NOT: fsub 50 // X86: ret 51 return a - b; 52 } 53 float _Complex sub_float_rc(float a, float _Complex b) { 54 // X86-LABEL: @sub_float_rc( 55 // X86: fsub 56 // X86: fsub float -0.{{0+}}e+00, 57 // X86-NOT: fsub 58 // X86: ret 59 return a - b; 60 } 61 float _Complex sub_float_cc(float _Complex a, float _Complex b) { 62 // X86-LABEL: @sub_float_cc( 63 // X86: fsub 64 // X86: fsub 65 // X86-NOT: fsub 66 // X86: ret 67 return a - b; 68 } 69 70 float _Complex mul_float_rr(float a, float b) { 71 // X86-LABEL: @mul_float_rr( 72 // X86: fmul 73 // X86-NOT: fmul 74 // X86: ret 75 return a * b; 76 } 77 float _Complex mul_float_cr(float _Complex a, float b) { 78 // X86-LABEL: @mul_float_cr( 79 // X86: fmul 80 // X86: fmul 81 // X86-NOT: fmul 82 // X86: ret 83 return a * b; 84 } 85 float _Complex mul_float_rc(float a, float _Complex b) { 86 // X86-LABEL: @mul_float_rc( 87 // X86: fmul 88 // X86: fmul 89 // X86-NOT: fmul 90 // X86: ret 91 return a * b; 92 } 93 float _Complex mul_float_cc(float _Complex a, float _Complex b) { 94 // X86-LABEL: @mul_float_cc( 95 // X86: %[[AC:[^ ]+]] = fmul 96 // X86: %[[BD:[^ ]+]] = fmul 97 // X86: %[[AD:[^ ]+]] = fmul 98 // X86: %[[BC:[^ ]+]] = fmul 99 // X86: %[[RR:[^ ]+]] = fsub float %[[AC]], %[[BD]] 100 // X86: %[[RI:[^ ]+]] = fadd float 101 // X86-DAG: %[[AD]] 102 // X86-DAG: , 103 // X86-DAG: %[[BC]] 104 // X86: fcmp uno float %[[RR]] 105 // X86: fcmp uno float %[[RI]] 106 // X86: call {{.*}} @__mulsc3( 107 // X86: ret 108 return a * b; 109 } 110 111 float _Complex div_float_rr(float a, float b) { 112 // X86-LABEL: @div_float_rr( 113 // X86: fdiv 114 // X86-NOT: fdiv 115 // X86: ret 116 return a / b; 117 } 118 float _Complex div_float_cr(float _Complex a, float b) { 119 // X86-LABEL: @div_float_cr( 120 // X86: fdiv 121 // X86: fdiv 122 // X86-NOT: fdiv 123 // X86: ret 124 return a / b; 125 } 126 float _Complex div_float_rc(float a, float _Complex b) { 127 // X86-LABEL: @div_float_rc( 128 // X86-NOT: fdiv 129 // X86: call {{.*}} @__divsc3( 130 // X86: ret 131 return a / b; 132 } 133 float _Complex div_float_cc(float _Complex a, float _Complex b) { 134 // X86-LABEL: @div_float_cc( 135 // X86-NOT: fdiv 136 // X86: call {{.*}} @__divsc3( 137 // X86: ret 138 return a / b; 139 } 140 141 double _Complex add_double_rr(double a, double b) { 142 // X86-LABEL: @add_double_rr( 143 // X86: fadd 144 // X86-NOT: fadd 145 // X86: ret 146 return a + b; 147 } 148 double _Complex add_double_cr(double _Complex a, double b) { 149 // X86-LABEL: @add_double_cr( 150 // X86: fadd 151 // X86-NOT: fadd 152 // X86: ret 153 return a + b; 154 } 155 double _Complex add_double_rc(double a, double _Complex b) { 156 // X86-LABEL: @add_double_rc( 157 // X86: fadd 158 // X86-NOT: fadd 159 // X86: ret 160 return a + b; 161 } 162 double _Complex add_double_cc(double _Complex a, double _Complex b) { 163 // X86-LABEL: @add_double_cc( 164 // X86: fadd 165 // X86: fadd 166 // X86-NOT: fadd 167 // X86: ret 168 return a + b; 169 } 170 171 double _Complex sub_double_rr(double a, double b) { 172 // X86-LABEL: @sub_double_rr( 173 // X86: fsub 174 // X86-NOT: fsub 175 // X86: ret 176 return a - b; 177 } 178 double _Complex sub_double_cr(double _Complex a, double b) { 179 // X86-LABEL: @sub_double_cr( 180 // X86: fsub 181 // X86-NOT: fsub 182 // X86: ret 183 return a - b; 184 } 185 double _Complex sub_double_rc(double a, double _Complex b) { 186 // X86-LABEL: @sub_double_rc( 187 // X86: fsub 188 // X86: fsub double -0.{{0+}}e+00, 189 // X86-NOT: fsub 190 // X86: ret 191 return a - b; 192 } 193 double _Complex sub_double_cc(double _Complex a, double _Complex b) { 194 // X86-LABEL: @sub_double_cc( 195 // X86: fsub 196 // X86: fsub 197 // X86-NOT: fsub 198 // X86: ret 199 return a - b; 200 } 201 202 double _Complex mul_double_rr(double a, double b) { 203 // X86-LABEL: @mul_double_rr( 204 // X86: fmul 205 // X86-NOT: fmul 206 // X86: ret 207 return a * b; 208 } 209 double _Complex mul_double_cr(double _Complex a, double b) { 210 // X86-LABEL: @mul_double_cr( 211 // X86: fmul 212 // X86: fmul 213 // X86-NOT: fmul 214 // X86: ret 215 return a * b; 216 } 217 double _Complex mul_double_rc(double a, double _Complex b) { 218 // X86-LABEL: @mul_double_rc( 219 // X86: fmul 220 // X86: fmul 221 // X86-NOT: fmul 222 // X86: ret 223 return a * b; 224 } 225 double _Complex mul_double_cc(double _Complex a, double _Complex b) { 226 // X86-LABEL: @mul_double_cc( 227 // X86: %[[AC:[^ ]+]] = fmul 228 // X86: %[[BD:[^ ]+]] = fmul 229 // X86: %[[AD:[^ ]+]] = fmul 230 // X86: %[[BC:[^ ]+]] = fmul 231 // X86: %[[RR:[^ ]+]] = fsub double %[[AC]], %[[BD]] 232 // X86: %[[RI:[^ ]+]] = fadd double 233 // X86-DAG: %[[AD]] 234 // X86-DAG: , 235 // X86-DAG: %[[BC]] 236 // X86: fcmp uno double %[[RR]] 237 // X86: fcmp uno double %[[RI]] 238 // X86: call {{.*}} @__muldc3( 239 // X86: ret 240 return a * b; 241 } 242 243 double _Complex div_double_rr(double a, double b) { 244 // X86-LABEL: @div_double_rr( 245 // X86: fdiv 246 // X86-NOT: fdiv 247 // X86: ret 248 return a / b; 249 } 250 double _Complex div_double_cr(double _Complex a, double b) { 251 // X86-LABEL: @div_double_cr( 252 // X86: fdiv 253 // X86: fdiv 254 // X86-NOT: fdiv 255 // X86: ret 256 return a / b; 257 } 258 double _Complex div_double_rc(double a, double _Complex b) { 259 // X86-LABEL: @div_double_rc( 260 // X86-NOT: fdiv 261 // X86: call {{.*}} @__divdc3( 262 // X86: ret 263 return a / b; 264 } 265 double _Complex div_double_cc(double _Complex a, double _Complex b) { 266 // X86-LABEL: @div_double_cc( 267 // X86-NOT: fdiv 268 // X86: call {{.*}} @__divdc3( 269 // X86: ret 270 return a / b; 271 } 272 273 long double _Complex add_long_double_rr(long double a, long double b) { 274 // X86-LABEL: @add_long_double_rr( 275 // X86: fadd 276 // X86-NOT: fadd 277 // X86: ret 278 return a + b; 279 } 280 long double _Complex add_long_double_cr(long double _Complex a, long double b) { 281 // X86-LABEL: @add_long_double_cr( 282 // X86: fadd 283 // X86-NOT: fadd 284 // X86: ret 285 return a + b; 286 } 287 long double _Complex add_long_double_rc(long double a, long double _Complex b) { 288 // X86-LABEL: @add_long_double_rc( 289 // X86: fadd 290 // X86-NOT: fadd 291 // X86: ret 292 return a + b; 293 } 294 long double _Complex add_long_double_cc(long double _Complex a, long double _Complex b) { 295 // X86-LABEL: @add_long_double_cc( 296 // X86: fadd 297 // X86: fadd 298 // X86-NOT: fadd 299 // X86: ret 300 return a + b; 301 } 302 303 long double _Complex sub_long_double_rr(long double a, long double b) { 304 // X86-LABEL: @sub_long_double_rr( 305 // X86: fsub 306 // X86-NOT: fsub 307 // X86: ret 308 return a - b; 309 } 310 long double _Complex sub_long_double_cr(long double _Complex a, long double b) { 311 // X86-LABEL: @sub_long_double_cr( 312 // X86: fsub 313 // X86-NOT: fsub 314 // X86: ret 315 return a - b; 316 } 317 long double _Complex sub_long_double_rc(long double a, long double _Complex b) { 318 // X86-LABEL: @sub_long_double_rc( 319 // X86: fsub 320 // X86: fsub x86_fp80 0xK8{{0+}}, 321 // X86-NOT: fsub 322 // X86: ret 323 return a - b; 324 } 325 long double _Complex sub_long_double_cc(long double _Complex a, long double _Complex b) { 326 // X86-LABEL: @sub_long_double_cc( 327 // X86: fsub 328 // X86: fsub 329 // X86-NOT: fsub 330 // X86: ret 331 return a - b; 332 } 333 334 long double _Complex mul_long_double_rr(long double a, long double b) { 335 // X86-LABEL: @mul_long_double_rr( 336 // X86: fmul 337 // X86-NOT: fmul 338 // X86: ret 339 return a * b; 340 } 341 long double _Complex mul_long_double_cr(long double _Complex a, long double b) { 342 // X86-LABEL: @mul_long_double_cr( 343 // X86: fmul 344 // X86: fmul 345 // X86-NOT: fmul 346 // X86: ret 347 return a * b; 348 } 349 long double _Complex mul_long_double_rc(long double a, long double _Complex b) { 350 // X86-LABEL: @mul_long_double_rc( 351 // X86: fmul 352 // X86: fmul 353 // X86-NOT: fmul 354 // X86: ret 355 return a * b; 356 } 357 long double _Complex mul_long_double_cc(long double _Complex a, long double _Complex b) { 358 // X86-LABEL: @mul_long_double_cc( 359 // X86: %[[AC:[^ ]+]] = fmul 360 // X86: %[[BD:[^ ]+]] = fmul 361 // X86: %[[AD:[^ ]+]] = fmul 362 // X86: %[[BC:[^ ]+]] = fmul 363 // X86: %[[RR:[^ ]+]] = fsub x86_fp80 %[[AC]], %[[BD]] 364 // X86: %[[RI:[^ ]+]] = fadd x86_fp80 365 // X86-DAG: %[[AD]] 366 // X86-DAG: , 367 // X86-DAG: %[[BC]] 368 // X86: fcmp uno x86_fp80 %[[RR]] 369 // X86: fcmp uno x86_fp80 %[[RI]] 370 // X86: call {{.*}} @__mulxc3( 371 // X86: ret 372 // PPC-LABEL: @mul_long_double_cc( 373 // PPC: %[[AC:[^ ]+]] = fmul 374 // PPC: %[[BD:[^ ]+]] = fmul 375 // PPC: %[[AD:[^ ]+]] = fmul 376 // PPC: %[[BC:[^ ]+]] = fmul 377 // PPC: %[[RR:[^ ]+]] = fsub ppc_fp128 %[[AC]], %[[BD]] 378 // PPC: %[[RI:[^ ]+]] = fadd ppc_fp128 379 // PPC-DAG: %[[AD]] 380 // PPC-DAG: , 381 // PPC-DAG: %[[BC]] 382 // PPC: fcmp uno ppc_fp128 %[[RR]] 383 // PPC: fcmp uno ppc_fp128 %[[RI]] 384 // PPC: call {{.*}} @__multc3( 385 // PPC: ret 386 return a * b; 387 } 388 389 long double _Complex div_long_double_rr(long double a, long double b) { 390 // X86-LABEL: @div_long_double_rr( 391 // X86: fdiv 392 // X86-NOT: fdiv 393 // X86: ret 394 return a / b; 395 } 396 long double _Complex div_long_double_cr(long double _Complex a, long double b) { 397 // X86-LABEL: @div_long_double_cr( 398 // X86: fdiv 399 // X86: fdiv 400 // X86-NOT: fdiv 401 // X86: ret 402 return a / b; 403 } 404 long double _Complex div_long_double_rc(long double a, long double _Complex b) { 405 // X86-LABEL: @div_long_double_rc( 406 // X86-NOT: fdiv 407 // X86: call {{.*}} @__divxc3( 408 // X86: ret 409 // PPC-LABEL: @div_long_double_rc( 410 // PPC-NOT: fdiv 411 // PPC: call {{.*}} @__divtc3( 412 // PPC: ret 413 return a / b; 414 } 415 long double _Complex div_long_double_cc(long double _Complex a, long double _Complex b) { 416 // X86-LABEL: @div_long_double_cc( 417 // X86-NOT: fdiv 418 // X86: call {{.*}} @__divxc3( 419 // X86: ret 420 // PPC-LABEL: @div_long_double_cc( 421 // PPC-NOT: fdiv 422 // PPC: call {{.*}} @__divtc3( 423 // PPC: ret 424 return a / b; 425 } 426 427 // Comparison operators don't rely on library calls or have interseting math 428 // properties, but test that mixed types work correctly here. 429 _Bool eq_float_cr(float _Complex a, float b) { 430 // X86-LABEL: @eq_float_cr( 431 // X86: fcmp oeq 432 // X86: fcmp oeq 433 // X86: and i1 434 // X86: ret 435 return a == b; 436 } 437 _Bool eq_float_rc(float a, float _Complex b) { 438 // X86-LABEL: @eq_float_rc( 439 // X86: fcmp oeq 440 // X86: fcmp oeq 441 // X86: and i1 442 // X86: ret 443 return a == b; 444 } 445 _Bool eq_float_cc(float _Complex a, float _Complex b) { 446 // X86-LABEL: @eq_float_cc( 447 // X86: fcmp oeq 448 // X86: fcmp oeq 449 // X86: and i1 450 // X86: ret 451 return a == b; 452 } 453 _Bool ne_float_cr(float _Complex a, float b) { 454 // X86-LABEL: @ne_float_cr( 455 // X86: fcmp une 456 // X86: fcmp une 457 // X86: or i1 458 // X86: ret 459 return a != b; 460 } 461 _Bool ne_float_rc(float a, float _Complex b) { 462 // X86-LABEL: @ne_float_rc( 463 // X86: fcmp une 464 // X86: fcmp une 465 // X86: or i1 466 // X86: ret 467 return a != b; 468 } 469 _Bool ne_float_cc(float _Complex a, float _Complex b) { 470 // X86-LABEL: @ne_float_cc( 471 // X86: fcmp une 472 // X86: fcmp une 473 // X86: or i1 474 // X86: ret 475 return a != b; 476 } 477 478 // Check that the libcall will obtain proper calling convention on ARM 479 _Complex double foo(_Complex double a, _Complex double b) { 480 // These functions are not defined as floating point helper functions in 481 // Run-time ABI for the ARM architecture document so they must not always 482 // use the base AAPCS. 483 484 // ARM-LABEL: @foo( 485 // ARM: call void { double, double } @__muldc3 486 487 // ARMHF-LABEL: @foo( 488 // ARMHF: call { double, double } @__muldc3 489 490 // ARM7K-LABEL: @foo( 491 // ARM7K: call { double, double } @__muldc3 492 return a*b; 493 } 494