Clang Project

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