xref: /llvm-project/clang/test/CodeGen/complex-math.c (revision d9c4c312d81b4a2059d0ca2bb454c3452e52042e)
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
10 
add_float_rr(float a,float b)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;
17 }
add_float_cr(float _Complex a,float 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;
24 }
add_float_rc(float a,float _Complex 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;
31 }
add_float_cc(float _Complex a,float _Complex 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;
39 }
40 
sub_float_rr(float a,float 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;
47 }
sub_float_cr(float _Complex a,float 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;
54 }
sub_float_rc(float a,float _Complex 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;
62 }
sub_float_cc(float _Complex a,float _Complex 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;
70 }
71 
mul_float_rr(float a,float 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;
78 }
mul_float_cr(float _Complex a,float 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;
86 }
mul_float_rc(float a,float _Complex 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;
94 }
95 
mul_float_cc(float _Complex a,float _Complex 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;
113 }
114 
div_float_rr(float a,float 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;
121 }
div_float_cr(float _Complex a,float 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;
129 }
div_float_rc(float a,float _Complex 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
135 
136   // SPIR: call spir_func {{.*}} @__divsc3(
137 
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:
157 
158   // |C| >= |D|
159   // DdC=D/C
160   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
161 
162   // CpRD=C+CdC*D
163   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
164   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
165 
166   // A+BR/CpRD
167   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
168   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
169   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
170 
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:
177 
178   // |C| < |D|
179   // CdD=C/D
180   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
181 
182   // DpRC=D+CdD*C
183   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
184   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
185 
186   // (A*CdD+B)/DpRC
187   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
188   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
189   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
190 
191   // (BCdD-A)/DpRC
192   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
193   // AARCH64-FASTMATH-NEXT: fsub {{.*}}float
194   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
195 
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;
202 }
div_float_cc(float _Complex a,float _Complex 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
208 
209   // SPIR: call spir_func {{.*}} @__divsc3(
210 
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:
230 
231   // |C| >= |D|
232   // DdC=D/C
233   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
234 
235   // CpRD=C+CdC*D
236   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
237   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
238 
239   // A+BR/CpRD
240   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
241   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
242   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
243 
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:
250 
251   // |C| < |D|
252   // CdD=C/D
253   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
254 
255   // DpRC=D+CdD*C
256   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
257   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
258 
259   // (A*CdD+B)/DpRC
260   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
261   // AARCH64-FASTMATH-NEXT: fadd {{.*}}float
262   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
263 
264   // (BCdD-A)/DpRC
265   // AARCH64-FASTMATH-NEXT: fmul {{.*}}float
266   // AARCH64-FASTMATH-NEXT: fsub {{.*}}float
267   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}float
268 
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;
274 }
275 
add_double_rr(double a,double 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;
282 }
add_double_cr(double _Complex a,double 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;
289 }
add_double_rc(double a,double _Complex 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;
296 }
add_double_cc(double _Complex a,double _Complex 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;
304 }
305 
sub_double_rr(double a,double 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;
312 }
sub_double_cr(double _Complex a,double 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;
319 }
sub_double_rc(double a,double _Complex 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;
327 }
sub_double_cc(double _Complex a,double _Complex 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;
335 }
336 
mul_double_rr(double a,double 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;
343 }
mul_double_cr(double _Complex a,double 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;
351 }
mul_double_rc(double a,double _Complex 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;
359 }
mul_double_cc(double _Complex a,double _Complex 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
375 
376   // SPIR: call spir_func {{.*}} @__muldc3(
377   return a * b;
378 }
379 
div_double_rr(double a,double 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;
386 }
div_double_cr(double _Complex a,double 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;
394 }
div_double_rc(double a,double _Complex 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
400 
401   // SPIR: call spir_func {{.*}} @__divdc3(
402 
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:
422 
423   // |C| >= |D|
424   // DdC=D/C
425   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
426 
427   // CpRD=C+CdC*D
428   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
429   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
430 
431   // A+BR/CpRD
432   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
433   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
434   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
435 
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:
442 
443   // |C| < |D|
444   // CdD=C/D
445   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
446 
447   // DpRC=D+CdD*C
448   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
449   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
450 
451   // (A*CdD+B)/DpRC
452   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
453   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
454   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
455 
456   // (BCdD-A)/DpRC
457   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
458   // AARCH64-FASTMATH-NEXT: fsub {{.*}}double
459   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
460 
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;
467 }
div_double_cc(double _Complex a,double _Complex 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
473 
474   // SPIR: call spir_func {{.*}} @__divdc3(
475 
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:
495 
496   // |C| >= |D|
497   // DdC=D/C
498   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
499 
500   // CpRD=C+CdC*D
501   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
502   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
503 
504   // A+BR/CpRD
505   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
506   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
507   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
508 
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:
515 
516   // |C| < |D|
517   // CdD=C/D
518   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
519 
520   // DpRC=D+CdD*C
521   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
522   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
523 
524   // (A*CdD+B)/DpRC
525   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
526   // AARCH64-FASTMATH-NEXT: fadd {{.*}}double
527   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
528 
529   // (BCdD-A)/DpRC
530   // AARCH64-FASTMATH-NEXT: fmul {{.*}}double
531   // AARCH64-FASTMATH-NEXT: fsub {{.*}}double
532   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}double
533 
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;
540 }
541 
add_long_double_rr(long double a,long double 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;
548 }
add_long_double_cr(long double _Complex a,long double 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;
555 }
add_long_double_rc(long double a,long double _Complex 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;
562 }
add_long_double_cc(long double _Complex a,long double _Complex 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;
570 }
571 
sub_long_double_rr(long double a,long double 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;
578 }
sub_long_double_cr(long double _Complex a,long double 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;
585 }
sub_long_double_rc(long double a,long double _Complex 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;
593 }
sub_long_double_cc(long double _Complex a,long double _Complex 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;
601 }
602 
mul_long_double_rr(long double a,long double 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;
609 }
mul_long_double_cr(long double _Complex a,long double 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;
617 }
mul_long_double_rc(long double a,long double _Complex 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;
625 }
mul_long_double_cc(long double _Complex a,long double _Complex 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;
657 }
658 
div_long_double_rr(long double a,long double 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;
665 }
div_long_double_cr(long double _Complex a,long double 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;
673 }
div_long_double_rc(long double a,long double _Complex 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(
684 
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:
704 
705   // |C| >= |D|
706   // DdC=D/C
707   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
708 
709   // CpRD=C+CdC*D
710   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
711   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
712 
713   // A+BR/CpRD
714   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
715   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
716   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
717 
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:
724 
725   // |C| < |D|
726   // CdD=C/D
727   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
728 
729   // DpRC=D+CdD*C
730   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
731   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
732 
733   // (A*CdD+B)/DpRC
734   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
735   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
736   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
737 
738   // (BCdD-A)/DpRC
739   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
740   // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128
741   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
742 
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;
749 }
div_long_double_cc(long double _Complex a,long double _Complex 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(
760 
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:
780 
781   // |C| >= |D|
782   // DdC=D/C
783   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
784 
785   // CpRD=C+CdC*D
786   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
787   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
788 
789   // A+BR/CpRD
790   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
791   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
792   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
793 
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:
800 
801   // |C| < |D|
802   // CdD=C/D
803   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
804 
805   // DpRC=D+CdD*C
806   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
807   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
808 
809   // (A*CdD+B)/DpRC
810   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
811   // AARCH64-FASTMATH-NEXT: fadd {{.*}}fp128
812   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
813 
814   // (BCdD-A)/DpRC
815   // AARCH64-FASTMATH-NEXT: fmul {{.*}}fp128
816   // AARCH64-FASTMATH-NEXT: fsub {{.*}}fp128
817   // AARCH64-FASTMATH-NEXT: fdiv {{.*}}fp128
818 
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;
825 }
826 
827 // Comparison operators don't rely on library calls or have interseting math
828 // properties, but test that mixed types work correctly here.
eq_float_cr(float _Complex a,float b)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;
836 }
eq_float_rc(float a,float _Complex 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;
844 }
eq_float_cc(float _Complex a,float _Complex 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;
852 }
ne_float_cr(float _Complex a,float 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;
860 }
ne_float_rc(float a,float _Complex 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;
868 }
ne_float_cc(float _Complex a,float _Complex 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;
876 }
877 
878 // Check that the libcall will obtain proper calling convention on ARM
foo(_Complex double a,_Complex double b)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.
883 
884   // ARM-LABEL: @foo(
885   // ARM: call void @__muldc3
886 
887   // SPIR: call spir_func void @__muldc3
888 
889   // ARMHF-LABEL: @foo(
890   // ARMHF: call { double, double } @__muldc3
891 
892   // ARM7K-LABEL: @foo(
893   // ARM7K: call { double, double } @__muldc3
894   return a*b;
895 }
896 
897 typedef _Complex double ComplexDouble;
898 typedef double Double;
899 
double_cr_sugar(ComplexDouble a,Double b)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;
907 }
908