1 // FIXME: This file should not be using -O1; that makes it depend on the entire LLVM IR optimizer.
2 
3 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefix=X86
4 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s --check-prefix=X86
5 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s --check-prefix=X86
6 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s --check-prefix=PPC
7 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM
8 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARMHF
9 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K
10 // RUN: %clang_cc1 %s -O1 -fno-experimental-new-pass-manager -emit-llvm -triple aarch64-unknown-unknown -ffast-math -o - | FileCheck %s --check-prefix=AARCH64-FASTMATH
11 
12 float _Complex add_float_rr(float a, float b) {
13   // X86-LABEL: @add_float_rr(
14   // X86: fadd
15   // X86-NOT: fadd
16   // X86: ret
17   return a + b;
18 }
19 float _Complex add_float_cr(float _Complex a, float b) {
20   // X86-LABEL: @add_float_cr(
21   // X86: fadd
22   // X86-NOT: fadd
23   // X86: ret
24   return a + b;
25 }
26 float _Complex add_float_rc(float a, float _Complex b) {
27   // X86-LABEL: @add_float_rc(
28   // X86: fadd
29   // X86-NOT: fadd
30   // X86: ret
31   return a + b;
32 }
33 float _Complex add_float_cc(float _Complex a, float _Complex b) {
34   // X86-LABEL: @add_float_cc(
35   // X86: fadd
36   // X86: fadd
37   // X86-NOT: fadd
38   // X86: ret
39   return a + b;
40 }
41 
42 float _Complex sub_float_rr(float a, float b) {
43   // X86-LABEL: @sub_float_rr(
44   // X86: fsub
45   // X86-NOT: fsub
46   // X86: ret
47   return a - b;
48 }
49 float _Complex sub_float_cr(float _Complex a, float b) {
50   // X86-LABEL: @sub_float_cr(
51   // X86: fsub
52   // X86-NOT: fsub
53   // X86: ret
54   return a - b;
55 }
56 float _Complex sub_float_rc(float a, float _Complex b) {
57   // X86-LABEL: @sub_float_rc(
58   // X86: fsub
59   // X86: fneg
60   // X86-NOT: fsub
61   // X86: ret
62   return a - b;
63 }
64 float _Complex sub_float_cc(float _Complex a, float _Complex b) {
65   // X86-LABEL: @sub_float_cc(
66   // X86: fsub
67   // X86: fsub
68   // X86-NOT: fsub
69   // X86: ret
70   return a - b;
71 }
72 
73 float _Complex mul_float_rr(float a, float b) {
74   // X86-LABEL: @mul_float_rr(
75   // X86: fmul
76   // X86-NOT: fmul
77   // X86: ret
78   return a * b;
79 }
80 float _Complex mul_float_cr(float _Complex a, float b) {
81   // X86-LABEL: @mul_float_cr(
82   // X86: fmul
83   // X86: fmul
84   // X86-NOT: fmul
85   // X86: ret
86   return a * b;
87 }
88 float _Complex mul_float_rc(float a, float _Complex b) {
89   // X86-LABEL: @mul_float_rc(
90   // X86: fmul
91   // X86: fmul
92   // X86-NOT: fmul
93   // X86: ret
94   return a * b;
95 }
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 float %[[AC]], %[[BD]]
103   // X86: %[[RI:[^ ]+]] = fadd float
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   return a * b;
112 }
113 
114 float _Complex div_float_rr(float a, float b) {
115   // X86-LABEL: @div_float_rr(
116   // X86: fdiv
117   // X86-NOT: fdiv
118   // X86: ret
119   return a / b;
120 }
121 float _Complex div_float_cr(float _Complex a, float b) {
122   // X86-LABEL: @div_float_cr(
123   // X86: fdiv
124   // X86: fdiv
125   // X86-NOT: fdiv
126   // X86: ret
127   return a / b;
128 }
129 float _Complex div_float_rc(float a, float _Complex b) {
130   // X86-LABEL: @div_float_rc(
131   // X86-NOT: fdiv
132   // X86: call {{.*}} @__divsc3(
133   // X86: ret
134 
135   // a / b = (A+iB) / (C+iD) = ((AC+BD)/(CC+DD)) + i((BC-AD)/(CC+DD))
136   // AARCH64-FASTMATH-LABEL: @div_float_rc(float %a, [2 x float] %b.coerce)
137   // A = a
138   // B = 0
139   // AARCH64-FASTMATH: [[C:%.*]] = extractvalue [2 x float] %b.coerce, 0
140   // AARCH64-FASTMATH: [[D:%.*]] = extractvalue [2 x float] %b.coerce, 1
141   //
142   // AARCH64-FASTMATH: [[AC:%.*]] = fmul fast float [[C]], %a
143   // BD = 0
144   // ACpBD = AC
145   //
146   // AARCH64-FASTMATH: [[CC:%.*]] = fmul fast float [[C]], [[C]]
147   // AARCH64-FASTMATH: [[DD:%.*]] = fmul fast float [[D]], [[D]]
148   // AARCH64-FASTMATH: [[CCpDD:%.*]] = fadd fast float [[CC]], [[DD]]
149   //
150   // BC = 0
151   // AARCH64-FASTMATH: [[NEGA:%.*]] = fsub fast float -0.000000e+00, %a
152   // AARCH64-FASTMATH: [[AD:%.*]] = fmul fast float  [[D]], [[NEGA]]
153   //
154   // AARCH64-FASTMATH: fdiv fast float [[AC]], [[CCpDD]]
155   // AARCH64-FASTMATH: fdiv fast float [[AD]], [[CCpDD]]
156   // AARCH64-FASTMATH: ret
157   return a / b;
158 }
159 float _Complex div_float_cc(float _Complex a, float _Complex b) {
160   // X86-LABEL: @div_float_cc(
161   // X86-NOT: fdiv
162   // X86: call {{.*}} @__divsc3(
163   // X86: ret
164 
165   // a / b = (A+iB) / (C+iD) = ((AC+BD)/(CC+DD)) + i((BC-AD)/(CC+DD))
166   // AARCH64-FASTMATH-LABEL: @div_float_cc([2 x float] %a.coerce, [2 x float] %b.coerce)
167   // AARCH64-FASTMATH: [[A:%.*]] = extractvalue [2 x float] %a.coerce, 0
168   // AARCH64-FASTMATH: [[B:%.*]] = extractvalue [2 x float] %a.coerce, 1
169   // AARCH64-FASTMATH: [[C:%.*]] = extractvalue [2 x float] %b.coerce, 0
170   // AARCH64-FASTMATH: [[D:%.*]] = extractvalue [2 x float] %b.coerce, 1
171   //
172   // AARCH64-FASTMATH: [[AC:%.*]] = fmul fast float [[C]], [[A]]
173   // AARCH64-FASTMATH: [[BD:%.*]] = fmul fast float [[D]], [[B]]
174   // AARCH64-FASTMATH: [[ACpBD:%.*]] = fadd fast float [[AC]], [[BD]]
175   //
176   // AARCH64-FASTMATH: [[CC:%.*]] = fmul fast float [[C]], [[C]]
177   // AARCH64-FASTMATH: [[DD:%.*]] = fmul fast float [[D]], [[D]]
178   // AARCH64-FASTMATH: [[CCpDD:%.*]] = fadd fast float [[CC]], [[DD]]
179   //
180   // AARCH64-FASTMATH: [[BC:%.*]] = fmul fast float [[C]], [[B]]
181   // AARCH64-FASTMATH: [[AD:%.*]] = fmul fast float [[D]], [[A]]
182   // AARCH64-FASTMATH: [[BCmAD:%.*]] = fsub fast float [[BC]], [[AD]]
183   //
184   // AARCH64-FASTMATH: fdiv fast float [[ACpBD]], [[CCpDD]]
185   // AARCH64-FASTMATH: fdiv fast float [[BCmAD]], [[CCpDD]]
186   // AARCH64-FASTMATH: ret
187   return a / b;
188 }
189 
190 double _Complex add_double_rr(double a, double b) {
191   // X86-LABEL: @add_double_rr(
192   // X86: fadd
193   // X86-NOT: fadd
194   // X86: ret
195   return a + b;
196 }
197 double _Complex add_double_cr(double _Complex a, double b) {
198   // X86-LABEL: @add_double_cr(
199   // X86: fadd
200   // X86-NOT: fadd
201   // X86: ret
202   return a + b;
203 }
204 double _Complex add_double_rc(double a, double _Complex b) {
205   // X86-LABEL: @add_double_rc(
206   // X86: fadd
207   // X86-NOT: fadd
208   // X86: ret
209   return a + b;
210 }
211 double _Complex add_double_cc(double _Complex a, double _Complex b) {
212   // X86-LABEL: @add_double_cc(
213   // X86: fadd
214   // X86: fadd
215   // X86-NOT: fadd
216   // X86: ret
217   return a + b;
218 }
219 
220 double _Complex sub_double_rr(double a, double b) {
221   // X86-LABEL: @sub_double_rr(
222   // X86: fsub
223   // X86-NOT: fsub
224   // X86: ret
225   return a - b;
226 }
227 double _Complex sub_double_cr(double _Complex a, double b) {
228   // X86-LABEL: @sub_double_cr(
229   // X86: fsub
230   // X86-NOT: fsub
231   // X86: ret
232   return a - b;
233 }
234 double _Complex sub_double_rc(double a, double _Complex b) {
235   // X86-LABEL: @sub_double_rc(
236   // X86: fsub
237   // X86: fneg
238   // X86-NOT: fsub
239   // X86: ret
240   return a - b;
241 }
242 double _Complex sub_double_cc(double _Complex a, double _Complex b) {
243   // X86-LABEL: @sub_double_cc(
244   // X86: fsub
245   // X86: fsub
246   // X86-NOT: fsub
247   // X86: ret
248   return a - b;
249 }
250 
251 double _Complex mul_double_rr(double a, double b) {
252   // X86-LABEL: @mul_double_rr(
253   // X86: fmul
254   // X86-NOT: fmul
255   // X86: ret
256   return a * b;
257 }
258 double _Complex mul_double_cr(double _Complex a, double b) {
259   // X86-LABEL: @mul_double_cr(
260   // X86: fmul
261   // X86: fmul
262   // X86-NOT: fmul
263   // X86: ret
264   return a * b;
265 }
266 double _Complex mul_double_rc(double a, double _Complex b) {
267   // X86-LABEL: @mul_double_rc(
268   // X86: fmul
269   // X86: fmul
270   // X86-NOT: fmul
271   // X86: ret
272   return a * b;
273 }
274 double _Complex mul_double_cc(double _Complex a, double _Complex b) {
275   // X86-LABEL: @mul_double_cc(
276   // X86: %[[AC:[^ ]+]] = fmul
277   // X86: %[[BD:[^ ]+]] = fmul
278   // X86: %[[AD:[^ ]+]] = fmul
279   // X86: %[[BC:[^ ]+]] = fmul
280   // X86: %[[RR:[^ ]+]] = fsub double %[[AC]], %[[BD]]
281   // X86: %[[RI:[^ ]+]] = fadd double
282   // X86-DAG: %[[AD]]
283   // X86-DAG: ,
284   // X86-DAG: %[[BC]]
285   // X86: fcmp uno double %[[RR]]
286   // X86: fcmp uno double %[[RI]]
287   // X86: call {{.*}} @__muldc3(
288   // X86: ret
289   return a * b;
290 }
291 
292 double _Complex div_double_rr(double a, double b) {
293   // X86-LABEL: @div_double_rr(
294   // X86: fdiv
295   // X86-NOT: fdiv
296   // X86: ret
297   return a / b;
298 }
299 double _Complex div_double_cr(double _Complex a, double b) {
300   // X86-LABEL: @div_double_cr(
301   // X86: fdiv
302   // X86: fdiv
303   // X86-NOT: fdiv
304   // X86: ret
305   return a / b;
306 }
307 double _Complex div_double_rc(double a, double _Complex b) {
308   // X86-LABEL: @div_double_rc(
309   // X86-NOT: fdiv
310   // X86: call {{.*}} @__divdc3(
311   // X86: ret
312 
313   // a / b = (A+iB) / (C+iD) = ((AC+BD)/(CC+DD)) + i((BC-AD)/(CC+DD))
314   // AARCH64-FASTMATH-LABEL: @div_double_rc(double %a, [2 x double] %b.coerce)
315   // A = a
316   // B = 0
317   // AARCH64-FASTMATH: [[C:%.*]] = extractvalue [2 x double] %b.coerce, 0
318   // AARCH64-FASTMATH: [[D:%.*]] = extractvalue [2 x double] %b.coerce, 1
319   //
320   // AARCH64-FASTMATH: [[AC:%.*]] = fmul fast double [[C]], %a
321   // BD = 0
322   // ACpBD = AC
323   //
324   // AARCH64-FASTMATH: [[CC:%.*]] = fmul fast double [[C]], [[C]]
325   // AARCH64-FASTMATH: [[DD:%.*]] = fmul fast double [[D]], [[D]]
326   // AARCH64-FASTMATH: [[CCpDD:%.*]] = fadd fast double [[CC]], [[DD]]
327   //
328   // BC = 0
329   // AARCH64-FASTMATH: [[NEGA:%.*]] = fsub fast double -0.000000e+00, %a
330   // AARCH64-FASTMATH: [[AD:%.*]] = fmul fast double [[D]], [[NEGA]]
331   //
332   // AARCH64-FASTMATH: fdiv fast double [[AC]], [[CCpDD]]
333   // AARCH64-FASTMATH: fdiv fast double [[AD]], [[CCpDD]]
334   // AARCH64-FASTMATH: ret
335   return a / b;
336 }
337 double _Complex div_double_cc(double _Complex a, double _Complex b) {
338   // X86-LABEL: @div_double_cc(
339   // X86-NOT: fdiv
340   // X86: call {{.*}} @__divdc3(
341   // X86: ret
342 
343   // a / b = (A+iB) / (C+iD) = ((AC+BD)/(CC+DD)) + i((BC-AD)/(CC+DD))
344   // AARCH64-FASTMATH-LABEL: @div_double_cc([2 x double] %a.coerce, [2 x double] %b.coerce)
345   // AARCH64-FASTMATH: [[A:%.*]] = extractvalue [2 x double] %a.coerce, 0
346   // AARCH64-FASTMATH: [[B:%.*]] = extractvalue [2 x double] %a.coerce, 1
347   // AARCH64-FASTMATH: [[C:%.*]] = extractvalue [2 x double] %b.coerce, 0
348   // AARCH64-FASTMATH: [[D:%.*]] = extractvalue [2 x double] %b.coerce, 1
349   //
350   // AARCH64-FASTMATH: [[AC:%.*]] = fmul fast double [[C]], [[A]]
351   // AARCH64-FASTMATH: [[BD:%.*]] = fmul fast double [[D]], [[B]]
352   // AARCH64-FASTMATH: [[ACpBD:%.*]] = fadd fast double [[AC]], [[BD]]
353   //
354   // AARCH64-FASTMATH: [[CC:%.*]] = fmul fast double [[C]], [[C]]
355   // AARCH64-FASTMATH: [[DD:%.*]] = fmul fast double [[D]], [[D]]
356   // AARCH64-FASTMATH: [[CCpDD:%.*]] = fadd fast double [[CC]], [[DD]]
357   //
358   // AARCH64-FASTMATH: [[BC:%.*]] = fmul fast double [[C]], [[B]]
359   // AARCH64-FASTMATH: [[AD:%.*]] = fmul fast double [[D]], [[A]]
360   // AARCH64-FASTMATH: [[BCmAD:%.*]] = fsub fast double [[BC]], [[AD]]
361   //
362   // AARCH64-FASTMATH: fdiv fast double [[ACpBD]], [[CCpDD]]
363   // AARCH64-FASTMATH: fdiv fast double [[BCmAD]], [[CCpDD]]
364   // AARCH64-FASTMATH: ret
365   return a / b;
366 }
367 
368 long double _Complex add_long_double_rr(long double a, long double b) {
369   // X86-LABEL: @add_long_double_rr(
370   // X86: fadd
371   // X86-NOT: fadd
372   // X86: ret
373   return a + b;
374 }
375 long double _Complex add_long_double_cr(long double _Complex a, long double b) {
376   // X86-LABEL: @add_long_double_cr(
377   // X86: fadd
378   // X86-NOT: fadd
379   // X86: ret
380   return a + b;
381 }
382 long double _Complex add_long_double_rc(long double a, long double _Complex b) {
383   // X86-LABEL: @add_long_double_rc(
384   // X86: fadd
385   // X86-NOT: fadd
386   // X86: ret
387   return a + b;
388 }
389 long double _Complex add_long_double_cc(long double _Complex a, long double _Complex b) {
390   // X86-LABEL: @add_long_double_cc(
391   // X86: fadd
392   // X86: fadd
393   // X86-NOT: fadd
394   // X86: ret
395   return a + b;
396 }
397 
398 long double _Complex sub_long_double_rr(long double a, long double b) {
399   // X86-LABEL: @sub_long_double_rr(
400   // X86: fsub
401   // X86-NOT: fsub
402   // X86: ret
403   return a - b;
404 }
405 long double _Complex sub_long_double_cr(long double _Complex a, long double b) {
406   // X86-LABEL: @sub_long_double_cr(
407   // X86: fsub
408   // X86-NOT: fsub
409   // X86: ret
410   return a - b;
411 }
412 long double _Complex sub_long_double_rc(long double a, long double _Complex b) {
413   // X86-LABEL: @sub_long_double_rc(
414   // X86: fsub
415   // X86: fneg
416   // X86-NOT: fsub
417   // X86: ret
418   return a - b;
419 }
420 long double _Complex sub_long_double_cc(long double _Complex a, long double _Complex b) {
421   // X86-LABEL: @sub_long_double_cc(
422   // X86: fsub
423   // X86: fsub
424   // X86-NOT: fsub
425   // X86: ret
426   return a - b;
427 }
428 
429 long double _Complex mul_long_double_rr(long double a, long double b) {
430   // X86-LABEL: @mul_long_double_rr(
431   // X86: fmul
432   // X86-NOT: fmul
433   // X86: ret
434   return a * b;
435 }
436 long double _Complex mul_long_double_cr(long double _Complex a, long double b) {
437   // X86-LABEL: @mul_long_double_cr(
438   // X86: fmul
439   // X86: fmul
440   // X86-NOT: fmul
441   // X86: ret
442   return a * b;
443 }
444 long double _Complex mul_long_double_rc(long double a, long double _Complex b) {
445   // X86-LABEL: @mul_long_double_rc(
446   // X86: fmul
447   // X86: fmul
448   // X86-NOT: fmul
449   // X86: ret
450   return a * b;
451 }
452 long double _Complex mul_long_double_cc(long double _Complex a, long double _Complex b) {
453   // X86-LABEL: @mul_long_double_cc(
454   // X86: %[[AC:[^ ]+]] = fmul
455   // X86: %[[BD:[^ ]+]] = fmul
456   // X86: %[[AD:[^ ]+]] = fmul
457   // X86: %[[BC:[^ ]+]] = fmul
458   // X86: %[[RR:[^ ]+]] = fsub x86_fp80 %[[AC]], %[[BD]]
459   // X86: %[[RI:[^ ]+]] = fadd x86_fp80
460   // X86-DAG: %[[AD]]
461   // X86-DAG: ,
462   // X86-DAG: %[[BC]]
463   // X86: fcmp uno x86_fp80 %[[RR]]
464   // X86: fcmp uno x86_fp80 %[[RI]]
465   // X86: call {{.*}} @__mulxc3(
466   // X86: ret
467   // PPC-LABEL: @mul_long_double_cc(
468   // PPC: %[[AC:[^ ]+]] = fmul
469   // PPC: %[[BD:[^ ]+]] = fmul
470   // PPC: %[[AD:[^ ]+]] = fmul
471   // PPC: %[[BC:[^ ]+]] = fmul
472   // PPC: %[[RR:[^ ]+]] = fsub ppc_fp128 %[[AC]], %[[BD]]
473   // PPC: %[[RI:[^ ]+]] = fadd ppc_fp128
474   // PPC-DAG: %[[AD]]
475   // PPC-DAG: ,
476   // PPC-DAG: %[[BC]]
477   // PPC: fcmp uno ppc_fp128 %[[RR]]
478   // PPC: fcmp uno ppc_fp128 %[[RI]]
479   // PPC: call {{.*}} @__multc3(
480   // PPC: ret
481   return a * b;
482 }
483 
484 long double _Complex div_long_double_rr(long double a, long double b) {
485   // X86-LABEL: @div_long_double_rr(
486   // X86: fdiv
487   // X86-NOT: fdiv
488   // X86: ret
489   return a / b;
490 }
491 long double _Complex div_long_double_cr(long double _Complex a, long double b) {
492   // X86-LABEL: @div_long_double_cr(
493   // X86: fdiv
494   // X86: fdiv
495   // X86-NOT: fdiv
496   // X86: ret
497   return a / b;
498 }
499 long double _Complex div_long_double_rc(long double a, long double _Complex b) {
500   // X86-LABEL: @div_long_double_rc(
501   // X86-NOT: fdiv
502   // X86: call {{.*}} @__divxc3(
503   // X86: ret
504   // PPC-LABEL: @div_long_double_rc(
505   // PPC-NOT: fdiv
506   // PPC: call {{.*}} @__divtc3(
507   // PPC: ret
508 
509   // a / b = (A+iB) / (C+iD) = ((AC+BD)/(CC+DD)) + i((BC-AD)/(CC+DD))
510   // AARCH64-FASTMATH-LABEL: @div_long_double_rc(fp128 %a, [2 x fp128] %b.coerce)
511   // A = a
512   // B = 0
513   // AARCH64-FASTMATH: [[C:%.*]] = extractvalue [2 x fp128] %b.coerce, 0
514   // AARCH64-FASTMATH: [[D:%.*]] = extractvalue [2 x fp128] %b.coerce, 1
515   //
516   // AARCH64-FASTMATH: [[AC:%.*]] = fmul fast fp128 [[C]], %a
517   // BD = 0
518   // ACpBD = AC
519   //
520   // AARCH64-FASTMATH: [[CC:%.*]] = fmul fast fp128 [[C]], [[C]]
521   // AARCH64-FASTMATH: [[DD:%.*]] = fmul fast fp128 [[D]], [[D]]
522   // AARCH64-FASTMATH: [[CCpDD:%.*]] = fadd fast fp128 [[CC]], [[DD]]
523   //
524   // BC = 0
525   // AARCH64-FASTMATH: [[NEGA:%.*]] = fsub fast fp128 0xL00000000000000008000000000000000, %a
526   // AARCH64-FASTMATH: [[AD:%.*]] = fmul fast fp128 [[D]], [[NEGA]]
527   //
528   // AARCH64-FASTMATH: fdiv fast fp128 [[AC]], [[CCpDD]]
529   // AARCH64-FASTMATH: fdiv fast fp128 [[AD]], [[CCpDD]]
530   // AARCH64-FASTMATH: ret
531   return a / b;
532 }
533 long double _Complex div_long_double_cc(long double _Complex a, long double _Complex b) {
534   // X86-LABEL: @div_long_double_cc(
535   // X86-NOT: fdiv
536   // X86: call {{.*}} @__divxc3(
537   // X86: ret
538   // PPC-LABEL: @div_long_double_cc(
539   // PPC-NOT: fdiv
540   // PPC: call {{.*}} @__divtc3(
541   // PPC: ret
542 
543   // a / b = (A+iB) / (C+iD) = ((AC+BD)/(CC+DD)) + i((BC-AD)/(CC+DD))
544   // AARCH64-FASTMATH-LABEL: @div_long_double_cc([2 x fp128] %a.coerce, [2 x fp128] %b.coerce)
545   // AARCH64-FASTMATH: [[A:%.*]] = extractvalue [2 x fp128] %a.coerce, 0
546   // AARCH64-FASTMATH: [[B:%.*]] = extractvalue [2 x fp128] %a.coerce, 1
547   // AARCH64-FASTMATH: [[C:%.*]] = extractvalue [2 x fp128] %b.coerce, 0
548   // AARCH64-FASTMATH: [[D:%.*]] = extractvalue [2 x fp128] %b.coerce, 1
549   //
550   // AARCH64-FASTMATH: [[AC:%.*]] = fmul fast fp128 [[C]], [[A]]
551   // AARCH64-FASTMATH: [[BD:%.*]] = fmul fast fp128 [[D]], [[B]]
552   // AARCH64-FASTMATH: [[ACpBD:%.*]] = fadd fast fp128 [[AC]], [[BD]]
553   //
554   // AARCH64-FASTMATH: [[CC:%.*]] = fmul fast fp128 [[C]], [[C]]
555   // AARCH64-FASTMATH: [[DD:%.*]] = fmul fast fp128 [[D]], [[D]]
556   // AARCH64-FASTMATH: [[CCpDD:%.*]] = fadd fast fp128 [[CC]], [[DD]]
557   //
558   // AARCH64-FASTMATH: [[BC:%.*]] = fmul fast fp128 [[C]], [[B]]
559   // AARCH64-FASTMATH: [[AD:%.*]] = fmul fast fp128 [[D]], [[A]]
560   // AARCH64-FASTMATH: [[BCmAD:%.*]] = fsub fast fp128 [[BC]], [[AD]]
561   //
562   // AARCH64-FASTMATH: fdiv fast fp128 [[ACpBD]], [[CCpDD]]
563   // AARCH64-FASTMATH: fdiv fast fp128 [[BCmAD]], [[CCpDD]]
564   // AARCH64-FASTMATH: ret
565   return a / b;
566 }
567 
568 // Comparison operators don't rely on library calls or have interseting math
569 // properties, but test that mixed types work correctly here.
570 _Bool eq_float_cr(float _Complex a, float b) {
571   // X86-LABEL: @eq_float_cr(
572   // X86: fcmp oeq
573   // X86: fcmp oeq
574   // X86: and i1
575   // X86: ret
576   return a == b;
577 }
578 _Bool eq_float_rc(float a, float _Complex b) {
579   // X86-LABEL: @eq_float_rc(
580   // X86: fcmp oeq
581   // X86: fcmp oeq
582   // X86: and i1
583   // X86: ret
584   return a == b;
585 }
586 _Bool eq_float_cc(float _Complex a, float _Complex b) {
587   // X86-LABEL: @eq_float_cc(
588   // X86: fcmp oeq
589   // X86: fcmp oeq
590   // X86: and i1
591   // X86: ret
592   return a == b;
593 }
594 _Bool ne_float_cr(float _Complex a, float b) {
595   // X86-LABEL: @ne_float_cr(
596   // X86: fcmp une
597   // X86: fcmp une
598   // X86: or i1
599   // X86: ret
600   return a != b;
601 }
602 _Bool ne_float_rc(float a, float _Complex b) {
603   // X86-LABEL: @ne_float_rc(
604   // X86: fcmp une
605   // X86: fcmp une
606   // X86: or i1
607   // X86: ret
608   return a != b;
609 }
610 _Bool ne_float_cc(float _Complex a, float _Complex b) {
611   // X86-LABEL: @ne_float_cc(
612   // X86: fcmp une
613   // X86: fcmp une
614   // X86: or i1
615   // X86: ret
616   return a != b;
617 }
618 
619 // Check that the libcall will obtain proper calling convention on ARM
620 _Complex double foo(_Complex double a, _Complex double b) {
621   // These functions are not defined as floating point helper functions in
622   // Run-time ABI for the ARM architecture document so they must not always
623   // use the base AAPCS.
624 
625   // ARM-LABEL: @foo(
626   // ARM: call void @__muldc3
627 
628   // ARMHF-LABEL: @foo(
629   // ARMHF: call { double, double } @__muldc3
630 
631   // ARM7K-LABEL: @foo(
632   // ARM7K: call { double, double } @__muldc3
633   return a*b;
634 }
635