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