[AArch64] Add fpext and fpround costs (#119292)
[llvm-project.git] / clang / test / CodeGen / complex-math.c
blobba00b9cbecd2fe6bf7d69a452fb49bde5e859eea
1 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefix=X86
2 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s --check-prefix=X86
3 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s --check-prefix=X86
4 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s --check-prefix=PPC
5 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM
6 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARMHF
7 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K
8 // 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-FASTMATH
9 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple spir -o - | FileCheck %s --check-prefix=SPIR
11 float _Complex add_float_rr(float a, float b) {
12 // X86-LABEL: @add_float_rr(
13 // X86: fadd
14 // X86-NOT: fadd
15 // X86: ret
16 return a + b;
18 float _Complex add_float_cr(float _Complex a, float b) {
19 // X86-LABEL: @add_float_cr(
20 // X86: fadd
21 // X86-NOT: fadd
22 // X86: ret
23 return a + b;
25 float _Complex add_float_rc(float a, float _Complex b) {
26 // X86-LABEL: @add_float_rc(
27 // X86: fadd
28 // X86-NOT: fadd
29 // X86: ret
30 return a + b;
32 float _Complex add_float_cc(float _Complex a, float _Complex b) {
33 // X86-LABEL: @add_float_cc(
34 // X86: fadd
35 // X86: fadd
36 // X86-NOT: fadd
37 // X86: ret
38 return a + b;
41 float _Complex sub_float_rr(float a, float b) {
42 // X86-LABEL: @sub_float_rr(
43 // X86: fsub
44 // X86-NOT: fsub
45 // X86: ret
46 return a - b;
48 float _Complex sub_float_cr(float _Complex a, float b) {
49 // X86-LABEL: @sub_float_cr(
50 // X86: fsub
51 // X86-NOT: fsub
52 // X86: ret
53 return a - b;
55 float _Complex sub_float_rc(float a, float _Complex b) {
56 // X86-LABEL: @sub_float_rc(
57 // X86: fsub
58 // X86: fneg
59 // X86-NOT: fsub
60 // X86: ret
61 return a - b;
63 float _Complex sub_float_cc(float _Complex a, float _Complex b) {
64 // X86-LABEL: @sub_float_cc(
65 // X86: fsub
66 // X86: fsub
67 // X86-NOT: fsub
68 // X86: ret
69 return a - b;
72 float _Complex mul_float_rr(float a, float b) {
73 // X86-LABEL: @mul_float_rr(
74 // X86: fmul
75 // X86-NOT: fmul
76 // X86: ret
77 return a * b;
79 float _Complex mul_float_cr(float _Complex a, float b) {
80 // X86-LABEL: @mul_float_cr(
81 // X86: fmul
82 // X86: fmul
83 // X86-NOT: fmul
84 // X86: ret
85 return a * b;
87 float _Complex mul_float_rc(float a, float _Complex b) {
88 // X86-LABEL: @mul_float_rc(
89 // X86: fmul
90 // X86: fmul
91 // X86-NOT: fmul
92 // X86: ret
93 return a * b;
96 float _Complex mul_float_cc(float _Complex a, float _Complex b) {
97 // X86-LABEL: @mul_float_cc(
98 // X86: %[[AC:[^ ]+]] = fmul
99 // X86: %[[BD:[^ ]+]] = fmul
100 // X86: %[[AD:[^ ]+]] = fmul
101 // X86: %[[BC:[^ ]+]] = fmul
102 // X86: %[[RR:[^ ]+]] = fsub
103 // X86: %[[RI:[^ ]+]] = fadd
104 // 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: ret
111 // SPIR: call spir_func {{.*}} @__mulsc3(
112 return a * b;
115 float _Complex div_float_rr(float a, float b) {
116 // X86-LABEL: @div_float_rr(
117 // X86: fdiv
118 // X86-NOT: fdiv
119 // X86: ret
120 return a / b;
122 float _Complex div_float_cr(float _Complex a, float b) {
123 // X86-LABEL: @div_float_cr(
124 // X86: fdiv
125 // X86: fdiv
126 // X86-NOT: fdiv
127 // X86: ret
128 return a / b;
130 float _Complex div_float_rc(float a, float _Complex b) {
131 // X86-LABEL: @div_float_rc(
132 // X86-NOT: fdiv
133 // X86: call {{.*}} @__divsc3(
134 // X86: ret
136 // SPIR: call spir_func {{.*}} @__divsc3(
138 // a / b = (A+iB) / (C+iD) = (E+iF)
139 // if (|C| >= |D|)
140 // DdC = D/C
141 // CpRD = C+DdC*D
142 // E = (A+B*DdC)/CpRD
143 // F = (B-A*DdC)/CpRD
144 // else
145 // CdD = C/D
146 // DpRC= D+CdD*C
147 // E = (A*CdD+B)/DpRC
148 // F = (B*CdD-A)/DpRC
149 // 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 float
155 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label
156 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:
158 // |C| >= |D|
159 // DdC=D/C
160 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
162 // CpRD=C+CdC*D
163 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
164 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
166 // A+BR/CpRD
167 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
168 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
169 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
171 // B-AR/CpRD
172 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
173 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float
174 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
175 // AARCH64-FASTMATH-NEXT: br label
176 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:
178 // |C| < |D|
179 // CdD=C/D
180 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
182 // DpRC=D+CdD*C
183 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
184 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
186 // (A*CdD+B)/DpRC
187 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
188 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
189 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
191 // (BCdD-A)/DpRC
192 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
193 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float
194 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
196 // AARCH64-FASTMATH-NEXT: br label
197 // AARCH64-FASTMATH: complex_div:
198 // AARCH64-FASTMATH-NEXT: phi {{.*}}float
199 // AARCH64-FASTMATH-NEXT: phi {{.*}}float
200 // AARCH64-FASTMATH: ret
201 return a / b;
203 float _Complex div_float_cc(float _Complex a, float _Complex b) {
204 // X86-LABEL: @div_float_cc(
205 // X86-NOT: fdiv
206 // X86: call {{.*}} @__divsc3(
207 // X86: ret
209 // SPIR: call spir_func {{.*}} @__divsc3(
211 // a / b = (A+iB) / (C+iD) = (E+iF)
212 // if (|C| >= |D|)
213 // DdC = D/C
214 // CpRD = C+DdC*D
215 // E = (A+B*DdC)/CpRD
216 // F = (B-A*DdC)/CpRD
217 // else
218 // CdD = C/D
219 // DpRC= D+CdD*C
220 // E = (A*CdD+B)/DpRC
221 // F = (B*CdD-A)/DpRC
222 // 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 float
228 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label
229 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:
231 // |C| >= |D|
232 // DdC=D/C
233 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
235 // CpRD=C+CdC*D
236 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
237 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
239 // A+BR/CpRD
240 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
241 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
242 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
244 // B-AR/CpRD
245 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
246 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float
247 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
248 // AARCH64-FASTMATH-NEXT: br label
249 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:
251 // |C| < |D|
252 // CdD=C/D
253 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
255 // DpRC=D+CdD*C
256 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
257 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
259 // (A*CdD+B)/DpRC
260 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
261 // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
262 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
264 // (BCdD-A)/DpRC
265 // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
266 // AARCH64-FASTMATH-NEXT: fsub {{.*}}float
267 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
269 // AARCH64-FASTMATH-NEXT: br label
270 // AARCH64-FASTMATH: complex_div:
271 // AARCH64-FASTMATH-NEXT: phi {{.*}}float
272 // AARCH64-FASTMATH-NEXT: phi {{.*}}float
273 return a / b;
276 double _Complex add_double_rr(double a, double b) {
277 // X86-LABEL: @add_double_rr(
278 // X86: fadd
279 // X86-NOT: fadd
280 // X86: ret
281 return a + b;
283 double _Complex add_double_cr(double _Complex a, double b) {
284 // X86-LABEL: @add_double_cr(
285 // X86: fadd
286 // X86-NOT: fadd
287 // X86: ret
288 return a + b;
290 double _Complex add_double_rc(double a, double _Complex b) {
291 // X86-LABEL: @add_double_rc(
292 // X86: fadd
293 // X86-NOT: fadd
294 // X86: ret
295 return a + b;
297 double _Complex add_double_cc(double _Complex a, double _Complex b) {
298 // X86-LABEL: @add_double_cc(
299 // X86: fadd
300 // X86: fadd
301 // X86-NOT: fadd
302 // X86: ret
303 return a + b;
306 double _Complex sub_double_rr(double a, double b) {
307 // X86-LABEL: @sub_double_rr(
308 // X86: fsub
309 // X86-NOT: fsub
310 // X86: ret
311 return a - b;
313 double _Complex sub_double_cr(double _Complex a, double b) {
314 // X86-LABEL: @sub_double_cr(
315 // X86: fsub
316 // X86-NOT: fsub
317 // X86: ret
318 return a - b;
320 double _Complex sub_double_rc(double a, double _Complex b) {
321 // X86-LABEL: @sub_double_rc(
322 // X86: fsub
323 // X86: fneg
324 // X86-NOT: fsub
325 // X86: ret
326 return a - b;
328 double _Complex sub_double_cc(double _Complex a, double _Complex b) {
329 // X86-LABEL: @sub_double_cc(
330 // X86: fsub
331 // X86: fsub
332 // X86-NOT: fsub
333 // X86: ret
334 return a - b;
337 double _Complex mul_double_rr(double a, double b) {
338 // X86-LABEL: @mul_double_rr(
339 // X86: fmul
340 // X86-NOT: fmul
341 // X86: ret
342 return a * b;
344 double _Complex mul_double_cr(double _Complex a, double b) {
345 // X86-LABEL: @mul_double_cr(
346 // X86: fmul
347 // X86: fmul
348 // X86-NOT: fmul
349 // X86: ret
350 return a * b;
352 double _Complex mul_double_rc(double a, double _Complex b) {
353 // X86-LABEL: @mul_double_rc(
354 // X86: fmul
355 // X86: fmul
356 // X86-NOT: fmul
357 // X86: ret
358 return a * b;
360 double _Complex mul_double_cc(double _Complex a, double _Complex b) {
361 // X86-LABEL: @mul_double_cc(
362 // X86: %[[AC:[^ ]+]] = fmul
363 // X86: %[[BD:[^ ]+]] = fmul
364 // X86: %[[AD:[^ ]+]] = fmul
365 // X86: %[[BC:[^ ]+]] = fmul
366 // X86: %[[RR:[^ ]+]] = fsub double %[[AC]], %[[BD]]
367 // X86: %[[RI:[^ ]+]] = fadd double
368 // 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: ret
376 // SPIR: call spir_func {{.*}} @__muldc3(
377 return a * b;
380 double _Complex div_double_rr(double a, double b) {
381 // X86-LABEL: @div_double_rr(
382 // X86: fdiv
383 // X86-NOT: fdiv
384 // X86: ret
385 return a / b;
387 double _Complex div_double_cr(double _Complex a, double b) {
388 // X86-LABEL: @div_double_cr(
389 // X86: fdiv
390 // X86: fdiv
391 // X86-NOT: fdiv
392 // X86: ret
393 return a / b;
395 double _Complex div_double_rc(double a, double _Complex b) {
396 // X86-LABEL: @div_double_rc(
397 // X86-NOT: fdiv
398 // X86: call {{.*}} @__divdc3(
399 // X86: ret
401 // SPIR: call spir_func {{.*}} @__divdc3(
403 // a / b = (A+iB) / (C+iD) = (E+iF)
404 // if (|C| >= |D|)
405 // DdC = D/C
406 // CpRD = C+DdC*D
407 // E = (A+B*DdC)/CpRD
408 // F = (B-A*DdC)/CpRD
409 // else
410 // CdD = C/D
411 // DpRC= D+CdD*C
412 // E = (A*CdD+B)/DpRC
413 // F = (B*CdD-A)/DpRC
414 // 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 double
420 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label
421 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:
423 // |C| >= |D|
424 // DdC=D/C
425 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
427 // CpRD=C+CdC*D
428 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
429 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
431 // A+BR/CpRD
432 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
433 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
434 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
436 // B-AR/CpRD
437 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
438 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double
439 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
440 // AARCH64-FASTMATH-NEXT: br label
441 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:
443 // |C| < |D|
444 // CdD=C/D
445 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
447 // DpRC=D+CdD*C
448 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
449 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
451 // (A*CdD+B)/DpRC
452 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
453 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
454 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
456 // (BCdD-A)/DpRC
457 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
458 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double
459 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
461 // AARCH64-FASTMATH-NEXT: br label
462 // AARCH64-FASTMATH: complex_div:
463 // AARCH64-FASTMATH-NEXT: phi {{.*}}double
464 // AARCH64-FASTMATH-NEXT: phi {{.*}}double
465 // AARCH64-FASTMATH: ret
466 return a / b;
468 double _Complex div_double_cc(double _Complex a, double _Complex b) {
469 // X86-LABEL: @div_double_cc(
470 // X86-NOT: fdiv
471 // X86: call {{.*}} @__divdc3(
472 // X86: ret
474 // SPIR: call spir_func {{.*}} @__divdc3(
476 // a / b = (A+iB) / (C+iD) = (E+iF)
477 // if (|C| >= |D|)
478 // DdC = D/C
479 // CpRD = C+DdC*D
480 // E = (A+B*DdC)/CpRD
481 // F = (B-A*DdC)/CpRD
482 // else
483 // CdD = C/D
484 // DpRC= D+CdD*C
485 // E = (A*CdD+B)/DpRC
486 // F = (B*CdD-A)/DpRC
487 // 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 double
493 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label
494 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:
496 // |C| >= |D|
497 // DdC=D/C
498 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
500 // CpRD=C+CdC*D
501 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
502 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
504 // A+BR/CpRD
505 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
506 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
507 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
509 // B-AR/CpRD
510 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
511 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double
512 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
513 // AARCH64-FASTMATH-NEXT: br label
514 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:
516 // |C| < |D|
517 // CdD=C/D
518 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
520 // DpRC=D+CdD*C
521 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
522 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
524 // (A*CdD+B)/DpRC
525 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
526 // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
527 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
529 // (BCdD-A)/DpRC
530 // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
531 // AARCH64-FASTMATH-NEXT: fsub {{.*}}double
532 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
534 // AARCH64-FASTMATH-NEXT: br label
535 // AARCH64-FASTMATH: complex_div:
536 // AARCH64-FASTMATH-NEXT: phi {{.*}}double
537 // AARCH64-FASTMATH-NEXT: phi {{.*}}double
538 // AARCH64-FASTMATH: ret
539 return a / b;
542 long double _Complex add_long_double_rr(long double a, long double b) {
543 // X86-LABEL: @add_long_double_rr(
544 // X86: fadd
545 // X86-NOT: fadd
546 // X86: ret
547 return a + b;
549 long double _Complex add_long_double_cr(long double _Complex a, long double b) {
550 // X86-LABEL: @add_long_double_cr(
551 // X86: fadd
552 // X86-NOT: fadd
553 // X86: ret
554 return a + b;
556 long double _Complex add_long_double_rc(long double a, long double _Complex b) {
557 // X86-LABEL: @add_long_double_rc(
558 // X86: fadd
559 // X86-NOT: fadd
560 // X86: ret
561 return a + b;
563 long double _Complex add_long_double_cc(long double _Complex a, long double _Complex b) {
564 // X86-LABEL: @add_long_double_cc(
565 // X86: fadd
566 // X86: fadd
567 // X86-NOT: fadd
568 // X86: ret
569 return a + b;
572 long double _Complex sub_long_double_rr(long double a, long double b) {
573 // X86-LABEL: @sub_long_double_rr(
574 // X86: fsub
575 // X86-NOT: fsub
576 // X86: ret
577 return a - b;
579 long double _Complex sub_long_double_cr(long double _Complex a, long double b) {
580 // X86-LABEL: @sub_long_double_cr(
581 // X86: fsub
582 // X86-NOT: fsub
583 // X86: ret
584 return a - b;
586 long double _Complex sub_long_double_rc(long double a, long double _Complex b) {
587 // X86-LABEL: @sub_long_double_rc(
588 // X86: fsub
589 // X86: fneg
590 // X86-NOT: fsub
591 // X86: ret
592 return a - b;
594 long double _Complex sub_long_double_cc(long double _Complex a, long double _Complex b) {
595 // X86-LABEL: @sub_long_double_cc(
596 // X86: fsub
597 // X86: fsub
598 // X86-NOT: fsub
599 // X86: ret
600 return a - b;
603 long double _Complex mul_long_double_rr(long double a, long double b) {
604 // X86-LABEL: @mul_long_double_rr(
605 // X86: fmul
606 // X86-NOT: fmul
607 // X86: ret
608 return a * b;
610 long double _Complex mul_long_double_cr(long double _Complex a, long double b) {
611 // X86-LABEL: @mul_long_double_cr(
612 // X86: fmul
613 // X86: fmul
614 // X86-NOT: fmul
615 // X86: ret
616 return a * b;
618 long double _Complex mul_long_double_rc(long double a, long double _Complex b) {
619 // X86-LABEL: @mul_long_double_rc(
620 // X86: fmul
621 // X86: fmul
622 // X86-NOT: fmul
623 // X86: ret
624 return a * b;
626 long double _Complex mul_long_double_cc(long double _Complex a, long double _Complex b) {
627 // X86-LABEL: @mul_long_double_cc(
628 // X86: %[[AC:[^ ]+]] = fmul
629 // X86: %[[BD:[^ ]+]] = fmul
630 // X86: %[[AD:[^ ]+]] = fmul
631 // X86: %[[BC:[^ ]+]] = fmul
632 // X86: %[[RR:[^ ]+]] = fsub x86_fp80 %[[AC]], %[[BD]]
633 // X86: %[[RI:[^ ]+]] = fadd x86_fp80
634 // 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: ret
641 // PPC-LABEL: @mul_long_double_cc(
642 // PPC: %[[AC:[^ ]+]] = fmul
643 // PPC: %[[BD:[^ ]+]] = fmul
644 // PPC: %[[AD:[^ ]+]] = fmul
645 // PPC: %[[BC:[^ ]+]] = fmul
646 // PPC: %[[RR:[^ ]+]] = fsub ppc_fp128 %[[AC]], %[[BD]]
647 // PPC: %[[RI:[^ ]+]] = fadd ppc_fp128
648 // 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: ret
655 // SPIR: call spir_func {{.*}} @__muldc3(
656 return a * b;
659 long double _Complex div_long_double_rr(long double a, long double b) {
660 // X86-LABEL: @div_long_double_rr(
661 // X86: fdiv
662 // X86-NOT: fdiv
663 // X86: ret
664 return a / b;
666 long double _Complex div_long_double_cr(long double _Complex a, long double b) {
667 // X86-LABEL: @div_long_double_cr(
668 // X86: fdiv
669 // X86: fdiv
670 // X86-NOT: fdiv
671 // X86: ret
672 return a / b;
674 long double _Complex div_long_double_rc(long double a, long double _Complex b) {
675 // X86-LABEL: @div_long_double_rc(
676 // X86-NOT: fdiv
677 // X86: call {{.*}} @__divxc3(
678 // X86: ret
679 // PPC-LABEL: @div_long_double_rc(
680 // PPC-NOT: fdiv
681 // PPC: call {{.*}} @__divtc3(
682 // PPC: ret
683 // SPIR: call spir_func {{.*}} @__divdc3(
685 // a / b = (A+iB) / (C+iD) = (E+iF)
686 // if (|C| >= |D|)
687 // DdC = D/C
688 // CpRD = C+DdC*D
689 // E = (A+B*DdC)/CpRD
690 // F = (B-A*DdC)/CpRD
691 // else
692 // CdD = C/D
693 // DpRC= D+CdD*C
694 // E = (A*CdD+B)/DpRC
695 // F = (B*CdD-A)/DpRC
696 // 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 fp128
702 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label
703 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:
705 // |C| >= |D|
706 // DdC=D/C
707 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
709 // CpRD=C+CdC*D
710 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
711 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
713 // A+BR/CpRD
714 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
715 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
716 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
718 // B-AR/CpRD
719 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
720 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128
721 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
722 // AARCH64-FASTMATH-NEXT: br label
723 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:
725 // |C| < |D|
726 // CdD=C/D
727 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
729 // DpRC=D+CdD*C
730 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
731 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
733 // (A*CdD+B)/DpRC
734 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
735 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
736 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
738 // (BCdD-A)/DpRC
739 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
740 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128
741 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
743 // AARCH64-FASTMATH-NEXT: br label
744 // AARCH64-FASTMATH: complex_div:
745 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128
746 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128
747 // AARCH64-FASTMATH: ret
748 return a / b;
750 long double _Complex div_long_double_cc(long double _Complex a, long double _Complex b) {
751 // X86-LABEL: @div_long_double_cc(
752 // X86-NOT: fdiv
753 // X86: call {{.*}} @__divxc3(
754 // X86: ret
755 // PPC-LABEL: @div_long_double_cc(
756 // PPC-NOT: fdiv
757 // PPC: call {{.*}} @__divtc3(
758 // PPC: ret
759 // SPIR: call spir_func {{.*}} @__divdc3(
761 // a / b = (A+iB) / (C+iD) = (E+iF)
762 // if (|C| >= |D|)
763 // DdC = D/C
764 // CpRD = C+DdC*D
765 // E = (A+B*DdC)/CpRD
766 // F = (B-A*DdC)/CpRD
767 // else
768 // CdD = C/D
769 // DpRC= D+CdD*C
770 // E = (A*CdD+B)/DpRC
771 // F = (B*CdD-A)/DpRC
772 // 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 fp128
778 // AARCH64-FASTMATH-NEXT: br i1 {{.*}}, label
779 // AARCH64-FASTMATH: abs_rhsr_greater_or_equal_abs_rhsi:
781 // |C| >= |D|
782 // DdC=D/C
783 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
785 // CpRD=C+CdC*D
786 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
787 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
789 // A+BR/CpRD
790 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
791 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
792 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
794 // B-AR/CpRD
795 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
796 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128
797 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
798 // AARCH64-FASTMATH-NEXT: br label
799 // AARCH64-FASTMATH: abs_rhsr_less_than_abs_rhsi:
801 // |C| < |D|
802 // CdD=C/D
803 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
805 // DpRC=D+CdD*C
806 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
807 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
809 // (A*CdD+B)/DpRC
810 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
811 // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
812 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
814 // (BCdD-A)/DpRC
815 // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
816 // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128
817 // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
819 // AARCH64-FASTMATH-NEXT: br label
820 // AARCH64-FASTMATH: complex_div:
821 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128
822 // AARCH64-FASTMATH-NEXT: phi {{.*}}fp128
823 // AARCH64-FASTMATH: ret
824 return a / b;
827 // Comparison operators don't rely on library calls or have interseting math
828 // 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 oeq
832 // X86: fcmp oeq
833 // X86: and i1
834 // X86: ret
835 return a == b;
837 _Bool eq_float_rc(float a, float _Complex b) {
838 // X86-LABEL: @eq_float_rc(
839 // X86: fcmp oeq
840 // X86: fcmp oeq
841 // X86: and i1
842 // X86: ret
843 return a == b;
845 _Bool eq_float_cc(float _Complex a, float _Complex b) {
846 // X86-LABEL: @eq_float_cc(
847 // X86: fcmp oeq
848 // X86: fcmp oeq
849 // X86: and i1
850 // X86: ret
851 return a == b;
853 _Bool ne_float_cr(float _Complex a, float b) {
854 // X86-LABEL: @ne_float_cr(
855 // X86: fcmp une
856 // X86: fcmp une
857 // X86: or i1
858 // X86: ret
859 return a != b;
861 _Bool ne_float_rc(float a, float _Complex b) {
862 // X86-LABEL: @ne_float_rc(
863 // X86: fcmp une
864 // X86: fcmp une
865 // X86: or i1
866 // X86: ret
867 return a != b;
869 _Bool ne_float_cc(float _Complex a, float _Complex b) {
870 // X86-LABEL: @ne_float_cc(
871 // X86: fcmp une
872 // X86: fcmp une
873 // X86: or i1
874 // X86: ret
875 return a != b;
878 // Check that the libcall will obtain proper calling convention on ARM
879 _Complex double foo(_Complex double a, _Complex double b) {
880 // These functions are not defined as floating point helper functions in
881 // Run-time ABI for the ARM architecture document so they must not always
882 // use the base AAPCS.
884 // ARM-LABEL: @foo(
885 // ARM: call void @__muldc3
887 // SPIR: call spir_func void @__muldc3
889 // ARMHF-LABEL: @foo(
890 // ARMHF: call { double, double } @__muldc3
892 // ARM7K-LABEL: @foo(
893 // ARM7K: call { double, double } @__muldc3
894 return a*b;
897 typedef _Complex double ComplexDouble;
898 typedef double Double;
900 float _Complex double_cr_sugar(ComplexDouble a, Double b) {
901 // X86-LABEL: @double_cr_sugar(
902 // X86: fmul
903 // X86: fmul
904 // X86-NOT: fmul
905 // X86: ret
906 return a *= b;