908 lines · c
1// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefix=X862// RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s --check-prefix=X863// RUN: %clang_cc1 %s -O0 -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s --check-prefix=X864// RUN: %clang_cc1 %s -O0 -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s --check-prefix=PPC5// RUN: %clang_cc1 %s -O0 -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM6// RUN: %clang_cc1 %s -O0 -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARMHF7// RUN: %clang_cc1 %s -O0 -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K8// RUN: %clang_cc1 %s -O0 -emit-llvm -triple aarch64-unknown-unknown -ffast-math -ffp-contract=fast -complex-range=improved -o - | FileCheck %s --check-prefix=AARCH64-FASTMATH9// RUN: %clang_cc1 %s -O0 -emit-llvm -triple spir -o - | FileCheck %s --check-prefix=SPIR10 11float _Complex add_float_rr(float a, float b) {12 // X86-LABEL: @add_float_rr(13 // X86: fadd14 // X86-NOT: fadd15 // X86: ret16 return a + b;17}18float _Complex add_float_cr(float _Complex a, float b) {19 // X86-LABEL: @add_float_cr(20 // X86: fadd21 // X86-NOT: fadd22 // X86: ret23 return a + b;24}25float _Complex add_float_rc(float a, float _Complex b) {26 // X86-LABEL: @add_float_rc(27 // X86: fadd28 // X86-NOT: fadd29 // X86: ret30 return a + b;31}32float _Complex add_float_cc(float _Complex a, float _Complex b) {33 // X86-LABEL: @add_float_cc(34 // X86: fadd35 // X86: fadd36 // X86-NOT: fadd37 // X86: ret38 return a + b;39}40 41float _Complex sub_float_rr(float a, float b) {42 // X86-LABEL: @sub_float_rr(43 // X86: fsub44 // X86-NOT: fsub45 // X86: ret46 return a - b;47}48float _Complex sub_float_cr(float _Complex a, float b) {49 // X86-LABEL: @sub_float_cr(50 // X86: fsub51 // X86-NOT: fsub52 // X86: ret53 return a - b;54}55float _Complex sub_float_rc(float a, float _Complex b) {56 // X86-LABEL: @sub_float_rc(57 // X86: fsub58 // X86: fneg59 // X86-NOT: fsub60 // X86: ret61 return a - b;62}63float _Complex sub_float_cc(float _Complex a, float _Complex b) {64 // X86-LABEL: @sub_float_cc(65 // X86: fsub66 // X86: fsub67 // X86-NOT: fsub68 // X86: ret69 return a - b;70}71 72float _Complex mul_float_rr(float a, float b) {73 // X86-LABEL: @mul_float_rr(74 // X86: fmul75 // X86-NOT: fmul76 // X86: ret77 return a * b;78}79float _Complex mul_float_cr(float _Complex a, float b) {80 // X86-LABEL: @mul_float_cr(81 // X86: fmul82 // X86: fmul83 // X86-NOT: fmul84 // X86: ret85 return a * b;86}87float _Complex mul_float_rc(float a, float _Complex b) {88 // X86-LABEL: @mul_float_rc(89 // X86: fmul90 // X86: fmul91 // X86-NOT: fmul92 // X86: ret93 return a * b;94}95 96float _Complex mul_float_cc(float _Complex a, float _Complex b) {97 // X86-LABEL: @mul_float_cc(98 // X86: %[[AC:[^ ]+]] = fmul99 // X86: %[[BD:[^ ]+]] = fmul100 // X86: %[[AD:[^ ]+]] = fmul101 // X86: %[[BC:[^ ]+]] = fmul102 // X86: %[[RR:[^ ]+]] = fsub103 // X86: %[[RI:[^ ]+]] = fadd104 // X86-DAG: %[[AD]]105 // X86-DAG: ,106 // X86-DAG: %[[BC]]107 // X86: fcmp uno float %[[RR]]108 // X86: fcmp uno float %[[RI]]109 // X86: call {{.*}} @__mulsc3(110 // X86: ret111 // SPIR: call spir_func {{.*}} @__mulsc3(112 return a * b;113}114 115float _Complex div_float_rr(float a, float b) {116 // X86-LABEL: @div_float_rr(117 // X86: fdiv118 // X86-NOT: fdiv119 // X86: ret120 return a / b;121}122float _Complex div_float_cr(float _Complex a, float b) {123 // X86-LABEL: @div_float_cr(124 // X86: fdiv125 // X86: fdiv126 // X86-NOT: fdiv127 // X86: ret128 return a / b;129}130float _Complex div_float_rc(float a, float _Complex b) {131 // X86-LABEL: @div_float_rc(132 // X86-NOT: fdiv133 // X86: call {{.*}} @__divsc3(134 // X86: ret135 136 // SPIR: call spir_func {{.*}} @__divsc3(137 138 // a / b = (A+iB) / (C+iD) = (E+iF)139 // if (|C| >= |D|)140 // DdC = D/C141 // CpRD = C+DdC*D142 // E = (A+B*DdC)/CpRD143 // F = (B-A*DdC)/CpRD144 // else145 // CdD = C/D146 // DpRC= D+CdD*C147 // E = (A*CdD+B)/DpRC148 // F = (B*CdD-A)/DpRC149 // AARCH64-FASTMATH-LABEL: @div_float_rc(float noundef nofpclass(nan inf) %a, [2 x float] noundef nofpclass(nan inf) alignstack(8) %b.coerce)150 // |C|151 // AARCH64-FASTMATH: call {{.*}}float @llvm.fabs.f32(float {{.*}})152 // |D|153 // AARCH64-FASTMATH-NEXT: call {{.*}}float @llvm.fabs.f32(float {{.*}})154 // AARCH64-FASTMATH-NEXT: fcmp {{.*}}ugt float155 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label156 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:157 158 // |C| >= |D|159 // DdC=D/C160 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float161 162 // CpRD=C+CdC*D163 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float164 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float165 166 // A+BR/CpRD167 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float168 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float169 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float170 171 // B-AR/CpRD172 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float173 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float174 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float175 // AARCH64-FASTMATH-NEXT: br label176 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:177 178 // |C| < |D|179 // CdD=C/D180 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float181 182 // DpRC=D+CdD*C183 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float184 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float185 186 // (A*CdD+B)/DpRC187 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float188 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float189 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float190 191 // (BCdD-A)/DpRC192 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float193 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float194 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float195 196 // AARCH64-FASTMATH-NEXT: br label197 // AARCH64-FASTMATH: complex_div:198 // AARCH64-FASTMATH-NEXT: phi {{.*}}float199 // AARCH64-FASTMATH-NEXT: phi {{.*}}float200 // AARCH64-FASTMATH: ret201 return a / b;202}203float _Complex div_float_cc(float _Complex a, float _Complex b) {204 // X86-LABEL: @div_float_cc(205 // X86-NOT: fdiv206 // X86: call {{.*}} @__divsc3(207 // X86: ret208 209 // SPIR: call spir_func {{.*}} @__divsc3(210 211 // a / b = (A+iB) / (C+iD) = (E+iF)212 // if (|C| >= |D|)213 // DdC = D/C214 // CpRD = C+DdC*D215 // E = (A+B*DdC)/CpRD216 // F = (B-A*DdC)/CpRD217 // else218 // CdD = C/D219 // DpRC= D+CdD*C220 // E = (A*CdD+B)/DpRC221 // F = (B*CdD-A)/DpRC222 // AARCH64-FASTMATH-LABEL: @div_float_cc([2 x float] noundef nofpclass(nan inf) alignstack(8) %a.coerce, [2 x float] noundef nofpclass(nan inf) alignstack(8) %b.coerce)223 // |C|224 // AARCH64-FASTMATH: call {{.*}}float @llvm.fabs.f32(float {{.*}})225 // |D|226 // AARCH64-FASTMATH-NEXT: call {{.*}}float @llvm.fabs.f32(float {{.*}})227 // AARCH64-FASTMATH-NEXT: fcmp {{.*}}ugt float228 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label229 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:230 231 // |C| >= |D|232 // DdC=D/C233 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float234 235 // CpRD=C+CdC*D236 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float237 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float238 239 // A+BR/CpRD240 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float241 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float242 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float243 244 // B-AR/CpRD245 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float246 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float247 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float248 // AARCH64-FASTMATH-NEXT: br label249 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:250 251 // |C| < |D|252 // CdD=C/D253 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float254 255 // DpRC=D+CdD*C256 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float257 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float258 259 // (A*CdD+B)/DpRC260 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float261 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float262 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float263 264 // (BCdD-A)/DpRC265 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float266 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float267 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float268 269 // AARCH64-FASTMATH-NEXT: br label270 // AARCH64-FASTMATH: complex_div:271 // AARCH64-FASTMATH-NEXT: phi {{.*}}float272 // AARCH64-FASTMATH-NEXT: phi {{.*}}float273 return a / b;274}275 276double _Complex add_double_rr(double a, double b) {277 // X86-LABEL: @add_double_rr(278 // X86: fadd279 // X86-NOT: fadd280 // X86: ret281 return a + b;282}283double _Complex add_double_cr(double _Complex a, double b) {284 // X86-LABEL: @add_double_cr(285 // X86: fadd286 // X86-NOT: fadd287 // X86: ret288 return a + b;289}290double _Complex add_double_rc(double a, double _Complex b) {291 // X86-LABEL: @add_double_rc(292 // X86: fadd293 // X86-NOT: fadd294 // X86: ret295 return a + b;296}297double _Complex add_double_cc(double _Complex a, double _Complex b) {298 // X86-LABEL: @add_double_cc(299 // X86: fadd300 // X86: fadd301 // X86-NOT: fadd302 // X86: ret303 return a + b;304}305 306double _Complex sub_double_rr(double a, double b) {307 // X86-LABEL: @sub_double_rr(308 // X86: fsub309 // X86-NOT: fsub310 // X86: ret311 return a - b;312}313double _Complex sub_double_cr(double _Complex a, double b) {314 // X86-LABEL: @sub_double_cr(315 // X86: fsub316 // X86-NOT: fsub317 // X86: ret318 return a - b;319}320double _Complex sub_double_rc(double a, double _Complex b) {321 // X86-LABEL: @sub_double_rc(322 // X86: fsub323 // X86: fneg324 // X86-NOT: fsub325 // X86: ret326 return a - b;327}328double _Complex sub_double_cc(double _Complex a, double _Complex b) {329 // X86-LABEL: @sub_double_cc(330 // X86: fsub331 // X86: fsub332 // X86-NOT: fsub333 // X86: ret334 return a - b;335}336 337double _Complex mul_double_rr(double a, double b) {338 // X86-LABEL: @mul_double_rr(339 // X86: fmul340 // X86-NOT: fmul341 // X86: ret342 return a * b;343}344double _Complex mul_double_cr(double _Complex a, double b) {345 // X86-LABEL: @mul_double_cr(346 // X86: fmul347 // X86: fmul348 // X86-NOT: fmul349 // X86: ret350 return a * b;351}352double _Complex mul_double_rc(double a, double _Complex b) {353 // X86-LABEL: @mul_double_rc(354 // X86: fmul355 // X86: fmul356 // X86-NOT: fmul357 // X86: ret358 return a * b;359}360double _Complex mul_double_cc(double _Complex a, double _Complex b) {361 // X86-LABEL: @mul_double_cc(362 // X86: %[[AC:[^ ]+]] = fmul363 // X86: %[[BD:[^ ]+]] = fmul364 // X86: %[[AD:[^ ]+]] = fmul365 // X86: %[[BC:[^ ]+]] = fmul366 // X86: %[[RR:[^ ]+]] = fsub double %[[AC]], %[[BD]]367 // X86: %[[RI:[^ ]+]] = fadd double368 // X86-DAG: %[[AD]]369 // X86-DAG: ,370 // X86-DAG: %[[BC]]371 // X86: fcmp uno double %[[RR]]372 // X86: fcmp uno double %[[RI]]373 // X86: call {{.*}} @__muldc3(374 // X86: ret375 376 // SPIR: call spir_func {{.*}} @__muldc3(377 return a * b;378}379 380double _Complex div_double_rr(double a, double b) {381 // X86-LABEL: @div_double_rr(382 // X86: fdiv383 // X86-NOT: fdiv384 // X86: ret385 return a / b;386}387double _Complex div_double_cr(double _Complex a, double b) {388 // X86-LABEL: @div_double_cr(389 // X86: fdiv390 // X86: fdiv391 // X86-NOT: fdiv392 // X86: ret393 return a / b;394}395double _Complex div_double_rc(double a, double _Complex b) {396 // X86-LABEL: @div_double_rc(397 // X86-NOT: fdiv398 // X86: call {{.*}} @__divdc3(399 // X86: ret400 401 // SPIR: call spir_func {{.*}} @__divdc3(402 403 // a / b = (A+iB) / (C+iD) = (E+iF)404 // if (|C| >= |D|)405 // DdC = D/C406 // CpRD = C+DdC*D407 // E = (A+B*DdC)/CpRD408 // F = (B-A*DdC)/CpRD409 // else410 // CdD = C/D411 // DpRC= D+CdD*C412 // E = (A*CdD+B)/DpRC413 // F = (B*CdD-A)/DpRC414 // AARCH64-FASTMATH-LABEL: @div_double_rc(double noundef nofpclass(nan inf) %a, [2 x double] noundef nofpclass(nan inf) alignstack(8) %b.coerce)415 // |C|416 // AARCH64-FASTMATH: call {{.*}}double @llvm.fabs.f64(double {{.*}})417 // |D|418 // AARCH64-FASTMATH-NEXT: call {{.*}}double @llvm.fabs.f64(double {{.*}})419 // AARCH64-FASTMATH-NEXT: fcmp {{.*}}ugt double420 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label421 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:422 423 // |C| >= |D|424 // DdC=D/C425 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double426 427 // CpRD=C+CdC*D428 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double429 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double430 431 // A+BR/CpRD432 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double433 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double434 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double435 436 // B-AR/CpRD437 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double438 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double439 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double440 // AARCH64-FASTMATH-NEXT: br label441 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:442 443 // |C| < |D|444 // CdD=C/D445 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double446 447 // DpRC=D+CdD*C448 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double449 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double450 451 // (A*CdD+B)/DpRC452 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double453 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double454 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double455 456 // (BCdD-A)/DpRC457 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double458 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double459 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double460 461 // AARCH64-FASTMATH-NEXT: br label462 // AARCH64-FASTMATH: complex_div:463 // AARCH64-FASTMATH-NEXT: phi {{.*}}double464 // AARCH64-FASTMATH-NEXT: phi {{.*}}double465 // AARCH64-FASTMATH: ret466 return a / b;467}468double _Complex div_double_cc(double _Complex a, double _Complex b) {469 // X86-LABEL: @div_double_cc(470 // X86-NOT: fdiv471 // X86: call {{.*}} @__divdc3(472 // X86: ret473 474 // SPIR: call spir_func {{.*}} @__divdc3(475 476 // a / b = (A+iB) / (C+iD) = (E+iF)477 // if (|C| >= |D|)478 // DdC = D/C479 // CpRD = C+DdC*D480 // E = (A+B*DdC)/CpRD481 // F = (B-A*DdC)/CpRD482 // else483 // CdD = C/D484 // DpRC= D+CdD*C485 // E = (A*CdD+B)/DpRC486 // F = (B*CdD-A)/DpRC487 // AARCH64-FASTMATH-LABEL: @div_double_cc([2 x double] noundef nofpclass(nan inf) alignstack(8) %a.coerce, [2 x double] noundef nofpclass(nan inf) alignstack(8) %b.coerce)488 // |C|489 // AARCH64-FASTMATH: call {{.*}}double @llvm.fabs.f64(double {{.*}})490 // |D|491 // AARCH64-FASTMATH-NEXT: call {{.*}}double @llvm.fabs.f64(double {{.*}})492 // AARCH64-FASTMATH-NEXT: fcmp {{.*}}ugt double493 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label494 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:495 496 // |C| >= |D|497 // DdC=D/C498 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double499 500 // CpRD=C+CdC*D501 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double502 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double503 504 // A+BR/CpRD505 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double506 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double507 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double508 509 // B-AR/CpRD510 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double511 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double512 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double513 // AARCH64-FASTMATH-NEXT: br label514 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:515 516 // |C| < |D|517 // CdD=C/D518 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double519 520 // DpRC=D+CdD*C521 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double522 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double523 524 // (A*CdD+B)/DpRC525 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double526 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double527 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double528 529 // (BCdD-A)/DpRC530 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double531 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double532 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double533 534 // AARCH64-FASTMATH-NEXT: br label535 // AARCH64-FASTMATH: complex_div:536 // AARCH64-FASTMATH-NEXT: phi {{.*}}double537 // AARCH64-FASTMATH-NEXT: phi {{.*}}double538 // AARCH64-FASTMATH: ret539 return a / b;540}541 542long double _Complex add_long_double_rr(long double a, long double b) {543 // X86-LABEL: @add_long_double_rr(544 // X86: fadd545 // X86-NOT: fadd546 // X86: ret547 return a + b;548}549long double _Complex add_long_double_cr(long double _Complex a, long double b) {550 // X86-LABEL: @add_long_double_cr(551 // X86: fadd552 // X86-NOT: fadd553 // X86: ret554 return a + b;555}556long double _Complex add_long_double_rc(long double a, long double _Complex b) {557 // X86-LABEL: @add_long_double_rc(558 // X86: fadd559 // X86-NOT: fadd560 // X86: ret561 return a + b;562}563long double _Complex add_long_double_cc(long double _Complex a, long double _Complex b) {564 // X86-LABEL: @add_long_double_cc(565 // X86: fadd566 // X86: fadd567 // X86-NOT: fadd568 // X86: ret569 return a + b;570}571 572long double _Complex sub_long_double_rr(long double a, long double b) {573 // X86-LABEL: @sub_long_double_rr(574 // X86: fsub575 // X86-NOT: fsub576 // X86: ret577 return a - b;578}579long double _Complex sub_long_double_cr(long double _Complex a, long double b) {580 // X86-LABEL: @sub_long_double_cr(581 // X86: fsub582 // X86-NOT: fsub583 // X86: ret584 return a - b;585}586long double _Complex sub_long_double_rc(long double a, long double _Complex b) {587 // X86-LABEL: @sub_long_double_rc(588 // X86: fsub589 // X86: fneg590 // X86-NOT: fsub591 // X86: ret592 return a - b;593}594long double _Complex sub_long_double_cc(long double _Complex a, long double _Complex b) {595 // X86-LABEL: @sub_long_double_cc(596 // X86: fsub597 // X86: fsub598 // X86-NOT: fsub599 // X86: ret600 return a - b;601}602 603long double _Complex mul_long_double_rr(long double a, long double b) {604 // X86-LABEL: @mul_long_double_rr(605 // X86: fmul606 // X86-NOT: fmul607 // X86: ret608 return a * b;609}610long double _Complex mul_long_double_cr(long double _Complex a, long double b) {611 // X86-LABEL: @mul_long_double_cr(612 // X86: fmul613 // X86: fmul614 // X86-NOT: fmul615 // X86: ret616 return a * b;617}618long double _Complex mul_long_double_rc(long double a, long double _Complex b) {619 // X86-LABEL: @mul_long_double_rc(620 // X86: fmul621 // X86: fmul622 // X86-NOT: fmul623 // X86: ret624 return a * b;625}626long double _Complex mul_long_double_cc(long double _Complex a, long double _Complex b) {627 // X86-LABEL: @mul_long_double_cc(628 // X86: %[[AC:[^ ]+]] = fmul629 // X86: %[[BD:[^ ]+]] = fmul630 // X86: %[[AD:[^ ]+]] = fmul631 // X86: %[[BC:[^ ]+]] = fmul632 // X86: %[[RR:[^ ]+]] = fsub x86_fp80 %[[AC]], %[[BD]]633 // X86: %[[RI:[^ ]+]] = fadd x86_fp80634 // X86-DAG: %[[AD]]635 // X86-DAG: ,636 // X86-DAG: %[[BC]]637 // X86: fcmp uno x86_fp80 %[[RR]]638 // X86: fcmp uno x86_fp80 %[[RI]]639 // X86: call {{.*}} @__mulxc3(640 // X86: ret641 // PPC-LABEL: @mul_long_double_cc(642 // PPC: %[[AC:[^ ]+]] = fmul643 // PPC: %[[BD:[^ ]+]] = fmul644 // PPC: %[[AD:[^ ]+]] = fmul645 // PPC: %[[BC:[^ ]+]] = fmul646 // PPC: %[[RR:[^ ]+]] = fsub ppc_fp128 %[[AC]], %[[BD]]647 // PPC: %[[RI:[^ ]+]] = fadd ppc_fp128648 // PPC-DAG: %[[AD]]649 // PPC-DAG: ,650 // PPC-DAG: %[[BC]]651 // PPC: fcmp uno ppc_fp128 %[[RR]]652 // PPC: fcmp uno ppc_fp128 %[[RI]]653 // PPC: call {{.*}} @__multc3(654 // PPC: ret655 // SPIR: call spir_func {{.*}} @__muldc3(656 return a * b;657}658 659long double _Complex div_long_double_rr(long double a, long double b) {660 // X86-LABEL: @div_long_double_rr(661 // X86: fdiv662 // X86-NOT: fdiv663 // X86: ret664 return a / b;665}666long double _Complex div_long_double_cr(long double _Complex a, long double b) {667 // X86-LABEL: @div_long_double_cr(668 // X86: fdiv669 // X86: fdiv670 // X86-NOT: fdiv671 // X86: ret672 return a / b;673}674long double _Complex div_long_double_rc(long double a, long double _Complex b) {675 // X86-LABEL: @div_long_double_rc(676 // X86-NOT: fdiv677 // X86: call {{.*}} @__divxc3(678 // X86: ret679 // PPC-LABEL: @div_long_double_rc(680 // PPC-NOT: fdiv681 // PPC: call {{.*}} @__divtc3(682 // PPC: ret683 // SPIR: call spir_func {{.*}} @__divdc3(684 685 // a / b = (A+iB) / (C+iD) = (E+iF)686 // if (|C| >= |D|)687 // DdC = D/C688 // CpRD = C+DdC*D689 // E = (A+B*DdC)/CpRD690 // F = (B-A*DdC)/CpRD691 // else692 // CdD = C/D693 // DpRC= D+CdD*C694 // E = (A*CdD+B)/DpRC695 // F = (B*CdD-A)/DpRC696 // AARCH64-FASTMATH-LABEL: @div_long_double_rc(fp128 noundef nofpclass(nan inf) %a, [2 x fp128] noundef nofpclass(nan inf) alignstack(16) %b.coerce)697 // |C|698 // AARCH64-FASTMATH: call {{.*}}fp128 @llvm.fabs.f128(fp128 {{.*}})699 // |D|700 // AARCH64-FASTMATH-NEXT: call {{.*}}fp128 @llvm.fabs.f128(fp128 {{.*}})701 // AARCH64-FASTMATH-NEXT: fcmp {{.*}}ugt fp128702 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label703 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:704 705 // |C| >= |D|706 // DdC=D/C707 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128708 709 // CpRD=C+CdC*D710 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128711 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128712 713 // A+BR/CpRD714 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128715 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128716 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128717 718 // B-AR/CpRD719 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128720 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128721 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128722 // AARCH64-FASTMATH-NEXT: br label723 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:724 725 // |C| < |D|726 // CdD=C/D727 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128728 729 // DpRC=D+CdD*C730 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128731 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128732 733 // (A*CdD+B)/DpRC734 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128735 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128736 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128737 738 // (BCdD-A)/DpRC739 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128740 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128741 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128742 743 // AARCH64-FASTMATH-NEXT: br label744 // AARCH64-FASTMATH: complex_div:745 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128746 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128747 // AARCH64-FASTMATH: ret748 return a / b;749}750long double _Complex div_long_double_cc(long double _Complex a, long double _Complex b) {751 // X86-LABEL: @div_long_double_cc(752 // X86-NOT: fdiv753 // X86: call {{.*}} @__divxc3(754 // X86: ret755 // PPC-LABEL: @div_long_double_cc(756 // PPC-NOT: fdiv757 // PPC: call {{.*}} @__divtc3(758 // PPC: ret759 // SPIR: call spir_func {{.*}} @__divdc3(760 761 // a / b = (A+iB) / (C+iD) = (E+iF)762 // if (|C| >= |D|)763 // DdC = D/C764 // CpRD = C+DdC*D765 // E = (A+B*DdC)/CpRD766 // F = (B-A*DdC)/CpRD767 // else768 // CdD = C/D769 // DpRC= D+CdD*C770 // E = (A*CdD+B)/DpRC771 // F = (B*CdD-A)/DpRC772 // AARCH64-FASTMATH-LABEL: @div_long_double_cc([2 x fp128] noundef nofpclass(nan inf) alignstack(16) %a.coerce, [2 x fp128] noundef nofpclass(nan inf) alignstack(16) %b.coerce)773 // |C|774 // AARCH64-FASTMATH: call {{.*}}fp128 @llvm.fabs.f128(fp128 {{.*}})775 // |D|776 // AARCH64-FASTMATH-NEXT: call {{.*}}fp128 @llvm.fabs.f128(fp128 {{.*}})777 // AARCH64-FASTMATH-NEXT: fcmp {{.*}}ugt fp128778 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label779 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:780 781 // |C| >= |D|782 // DdC=D/C783 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128784 785 // CpRD=C+CdC*D786 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128787 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128788 789 // A+BR/CpRD790 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128791 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128792 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128793 794 // B-AR/CpRD795 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128796 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128797 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128798 // AARCH64-FASTMATH-NEXT: br label799 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:800 801 // |C| < |D|802 // CdD=C/D803 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128804 805 // DpRC=D+CdD*C806 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128807 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128808 809 // (A*CdD+B)/DpRC810 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128811 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128812 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128813 814 // (BCdD-A)/DpRC815 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128816 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128817 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128818 819 // AARCH64-FASTMATH-NEXT: br label820 // AARCH64-FASTMATH: complex_div:821 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128822 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128823 // AARCH64-FASTMATH: ret824 return a / b;825}826 827// Comparison operators don't rely on library calls or have interseting math828// properties, but test that mixed types work correctly here.829_Bool eq_float_cr(float _Complex a, float b) {830 // X86-LABEL: @eq_float_cr(831 // X86: fcmp oeq832 // X86: fcmp oeq833 // X86: and i1834 // X86: ret835 return a == b;836}837_Bool eq_float_rc(float a, float _Complex b) {838 // X86-LABEL: @eq_float_rc(839 // X86: fcmp oeq840 // X86: fcmp oeq841 // X86: and i1842 // X86: ret843 return a == b;844}845_Bool eq_float_cc(float _Complex a, float _Complex b) {846 // X86-LABEL: @eq_float_cc(847 // X86: fcmp oeq848 // X86: fcmp oeq849 // X86: and i1850 // X86: ret851 return a == b;852}853_Bool ne_float_cr(float _Complex a, float b) {854 // X86-LABEL: @ne_float_cr(855 // X86: fcmp une856 // X86: fcmp une857 // X86: or i1858 // X86: ret859 return a != b;860}861_Bool ne_float_rc(float a, float _Complex b) {862 // X86-LABEL: @ne_float_rc(863 // X86: fcmp une864 // X86: fcmp une865 // X86: or i1866 // X86: ret867 return a != b;868}869_Bool ne_float_cc(float _Complex a, float _Complex b) {870 // X86-LABEL: @ne_float_cc(871 // X86: fcmp une872 // X86: fcmp une873 // X86: or i1874 // X86: ret875 return a != b;876}877 878// Check that the libcall will obtain proper calling convention on ARM879_Complex double foo(_Complex double a, _Complex double b) {880 // These functions are not defined as floating point helper functions in881 // Run-time ABI for the ARM architecture document so they must not always882 // use the base AAPCS.883 884 // ARM-LABEL: @foo(885 // ARM: call void @__muldc3886 887 // SPIR: call spir_func void @__muldc3888 889 // ARMHF-LABEL: @foo(890 // ARMHF: call { double, double } @__muldc3891 892 // ARM7K-LABEL: @foo(893 // ARM7K: call { double, double } @__muldc3894 return a*b;895}896 897typedef _Complex double ComplexDouble;898typedef double Double;899 900float _Complex double_cr_sugar(ComplexDouble a, Double b) {901 // X86-LABEL: @double_cr_sugar(902 // X86: fmul903 // X86: fmul904 // X86-NOT: fmul905 // X86: ret906 return a *= b;907}908