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 
9 float _Complex add_float_rr(float a, float b) {
10   // X86-LABEL: @add_float_rr(
11   // X86: fadd
12   // X86-NOT: fadd
13   // X86: ret
14   return a + b;
15 }
16 float _Complex add_float_cr(float _Complex a, float b) {
17   // X86-LABEL: @add_float_cr(
18   // X86: fadd
19   // X86-NOT: fadd
20   // X86: ret
21   return a + b;
22 }
23 float _Complex add_float_rc(float a, float _Complex b) {
24   // X86-LABEL: @add_float_rc(
25   // X86: fadd
26   // X86-NOT: fadd
27   // X86: ret
28   return a + b;
29 }
30 float _Complex add_float_cc(float _Complex a, float _Complex b) {
31   // X86-LABEL: @add_float_cc(
32   // X86: fadd
33   // X86: fadd
34   // X86-NOT: fadd
35   // X86: ret
36   return a + b;
37 }
38 
39 float _Complex sub_float_rr(float a, float b) {
40   // X86-LABEL: @sub_float_rr(
41   // X86: fsub
42   // X86-NOT: fsub
43   // X86: ret
44   return a - b;
45 }
46 float _Complex sub_float_cr(float _Complex a, float b) {
47   // X86-LABEL: @sub_float_cr(
48   // X86: fsub
49   // X86-NOT: fsub
50   // X86: ret
51   return a - b;
52 }
53 float _Complex sub_float_rc(float a, float _Complex b) {
54   // X86-LABEL: @sub_float_rc(
55   // X86: fsub
56   // X86: fsub float -0.{{0+}}e+00,
57   // X86-NOT: fsub
58   // X86: ret
59   return a - b;
60 }
61 float _Complex sub_float_cc(float _Complex a, float _Complex b) {
62   // X86-LABEL: @sub_float_cc(
63   // X86: fsub
64   // X86: fsub
65   // X86-NOT: fsub
66   // X86: ret
67   return a - b;
68 }
69 
70 float _Complex mul_float_rr(float a, float b) {
71   // X86-LABEL: @mul_float_rr(
72   // X86: fmul
73   // X86-NOT: fmul
74   // X86: ret
75   return a * b;
76 }
77 float _Complex mul_float_cr(float _Complex a, float b) {
78   // X86-LABEL: @mul_float_cr(
79   // X86: fmul
80   // X86: fmul
81   // X86-NOT: fmul
82   // X86: ret
83   return a * b;
84 }
85 float _Complex mul_float_rc(float a, float _Complex b) {
86   // X86-LABEL: @mul_float_rc(
87   // X86: fmul
88   // X86: fmul
89   // X86-NOT: fmul
90   // X86: ret
91   return a * b;
92 }
93 float _Complex mul_float_cc(float _Complex a, float _Complex b) {
94   // X86-LABEL: @mul_float_cc(
95   // X86: %[[AC:[^ ]+]] = fmul
96   // X86: %[[BD:[^ ]+]] = fmul
97   // X86: %[[AD:[^ ]+]] = fmul
98   // X86: %[[BC:[^ ]+]] = fmul
99   // X86: %[[RR:[^ ]+]] = fsub float %[[AC]], %[[BD]]
100   // X86: %[[RI:[^ ]+]] = fadd float
101   // X86-DAG: %[[AD]]
102   // X86-DAG: ,
103   // X86-DAG: %[[BC]]
104   // X86: fcmp uno float %[[RR]]
105   // X86: fcmp uno float %[[RI]]
106   // X86: call {{.*}} @__mulsc3(
107   // X86: ret
108   return a * b;
109 }
110 
111 float _Complex div_float_rr(float a, float b) {
112   // X86-LABEL: @div_float_rr(
113   // X86: fdiv
114   // X86-NOT: fdiv
115   // X86: ret
116   return a / b;
117 }
118 float _Complex div_float_cr(float _Complex a, float b) {
119   // X86-LABEL: @div_float_cr(
120   // X86: fdiv
121   // X86: fdiv
122   // X86-NOT: fdiv
123   // X86: ret
124   return a / b;
125 }
126 float _Complex div_float_rc(float a, float _Complex b) {
127   // X86-LABEL: @div_float_rc(
128   // X86-NOT: fdiv
129   // X86: call {{.*}} @__divsc3(
130   // X86: ret
131   return a / b;
132 }
133 float _Complex div_float_cc(float _Complex a, float _Complex b) {
134   // X86-LABEL: @div_float_cc(
135   // X86-NOT: fdiv
136   // X86: call {{.*}} @__divsc3(
137   // X86: ret
138   return a / b;
139 }
140 
141 double _Complex add_double_rr(double a, double b) {
142   // X86-LABEL: @add_double_rr(
143   // X86: fadd
144   // X86-NOT: fadd
145   // X86: ret
146   return a + b;
147 }
148 double _Complex add_double_cr(double _Complex a, double b) {
149   // X86-LABEL: @add_double_cr(
150   // X86: fadd
151   // X86-NOT: fadd
152   // X86: ret
153   return a + b;
154 }
155 double _Complex add_double_rc(double a, double _Complex b) {
156   // X86-LABEL: @add_double_rc(
157   // X86: fadd
158   // X86-NOT: fadd
159   // X86: ret
160   return a + b;
161 }
162 double _Complex add_double_cc(double _Complex a, double _Complex b) {
163   // X86-LABEL: @add_double_cc(
164   // X86: fadd
165   // X86: fadd
166   // X86-NOT: fadd
167   // X86: ret
168   return a + b;
169 }
170 
171 double _Complex sub_double_rr(double a, double b) {
172   // X86-LABEL: @sub_double_rr(
173   // X86: fsub
174   // X86-NOT: fsub
175   // X86: ret
176   return a - b;
177 }
178 double _Complex sub_double_cr(double _Complex a, double b) {
179   // X86-LABEL: @sub_double_cr(
180   // X86: fsub
181   // X86-NOT: fsub
182   // X86: ret
183   return a - b;
184 }
185 double _Complex sub_double_rc(double a, double _Complex b) {
186   // X86-LABEL: @sub_double_rc(
187   // X86: fsub
188   // X86: fsub double -0.{{0+}}e+00,
189   // X86-NOT: fsub
190   // X86: ret
191   return a - b;
192 }
193 double _Complex sub_double_cc(double _Complex a, double _Complex b) {
194   // X86-LABEL: @sub_double_cc(
195   // X86: fsub
196   // X86: fsub
197   // X86-NOT: fsub
198   // X86: ret
199   return a - b;
200 }
201 
202 double _Complex mul_double_rr(double a, double b) {
203   // X86-LABEL: @mul_double_rr(
204   // X86: fmul
205   // X86-NOT: fmul
206   // X86: ret
207   return a * b;
208 }
209 double _Complex mul_double_cr(double _Complex a, double b) {
210   // X86-LABEL: @mul_double_cr(
211   // X86: fmul
212   // X86: fmul
213   // X86-NOT: fmul
214   // X86: ret
215   return a * b;
216 }
217 double _Complex mul_double_rc(double a, double _Complex b) {
218   // X86-LABEL: @mul_double_rc(
219   // X86: fmul
220   // X86: fmul
221   // X86-NOT: fmul
222   // X86: ret
223   return a * b;
224 }
225 double _Complex mul_double_cc(double _Complex a, double _Complex b) {
226   // X86-LABEL: @mul_double_cc(
227   // X86: %[[AC:[^ ]+]] = fmul
228   // X86: %[[BD:[^ ]+]] = fmul
229   // X86: %[[AD:[^ ]+]] = fmul
230   // X86: %[[BC:[^ ]+]] = fmul
231   // X86: %[[RR:[^ ]+]] = fsub double %[[AC]], %[[BD]]
232   // X86: %[[RI:[^ ]+]] = fadd double
233   // X86-DAG: %[[AD]]
234   // X86-DAG: ,
235   // X86-DAG: %[[BC]]
236   // X86: fcmp uno double %[[RR]]
237   // X86: fcmp uno double %[[RI]]
238   // X86: call {{.*}} @__muldc3(
239   // X86: ret
240   return a * b;
241 }
242 
243 double _Complex div_double_rr(double a, double b) {
244   // X86-LABEL: @div_double_rr(
245   // X86: fdiv
246   // X86-NOT: fdiv
247   // X86: ret
248   return a / b;
249 }
250 double _Complex div_double_cr(double _Complex a, double b) {
251   // X86-LABEL: @div_double_cr(
252   // X86: fdiv
253   // X86: fdiv
254   // X86-NOT: fdiv
255   // X86: ret
256   return a / b;
257 }
258 double _Complex div_double_rc(double a, double _Complex b) {
259   // X86-LABEL: @div_double_rc(
260   // X86-NOT: fdiv
261   // X86: call {{.*}} @__divdc3(
262   // X86: ret
263   return a / b;
264 }
265 double _Complex div_double_cc(double _Complex a, double _Complex b) {
266   // X86-LABEL: @div_double_cc(
267   // X86-NOT: fdiv
268   // X86: call {{.*}} @__divdc3(
269   // X86: ret
270   return a / b;
271 }
272 
273 long double _Complex add_long_double_rr(long double a, long double b) {
274   // X86-LABEL: @add_long_double_rr(
275   // X86: fadd
276   // X86-NOT: fadd
277   // X86: ret
278   return a + b;
279 }
280 long double _Complex add_long_double_cr(long double _Complex a, long double b) {
281   // X86-LABEL: @add_long_double_cr(
282   // X86: fadd
283   // X86-NOT: fadd
284   // X86: ret
285   return a + b;
286 }
287 long double _Complex add_long_double_rc(long double a, long double _Complex b) {
288   // X86-LABEL: @add_long_double_rc(
289   // X86: fadd
290   // X86-NOT: fadd
291   // X86: ret
292   return a + b;
293 }
294 long double _Complex add_long_double_cc(long double _Complex a, long double _Complex b) {
295   // X86-LABEL: @add_long_double_cc(
296   // X86: fadd
297   // X86: fadd
298   // X86-NOT: fadd
299   // X86: ret
300   return a + b;
301 }
302 
303 long double _Complex sub_long_double_rr(long double a, long double b) {
304   // X86-LABEL: @sub_long_double_rr(
305   // X86: fsub
306   // X86-NOT: fsub
307   // X86: ret
308   return a - b;
309 }
310 long double _Complex sub_long_double_cr(long double _Complex a, long double b) {
311   // X86-LABEL: @sub_long_double_cr(
312   // X86: fsub
313   // X86-NOT: fsub
314   // X86: ret
315   return a - b;
316 }
317 long double _Complex sub_long_double_rc(long double a, long double _Complex b) {
318   // X86-LABEL: @sub_long_double_rc(
319   // X86: fsub
320   // X86: fsub x86_fp80 0xK8{{0+}},
321   // X86-NOT: fsub
322   // X86: ret
323   return a - b;
324 }
325 long double _Complex sub_long_double_cc(long double _Complex a, long double _Complex b) {
326   // X86-LABEL: @sub_long_double_cc(
327   // X86: fsub
328   // X86: fsub
329   // X86-NOT: fsub
330   // X86: ret
331   return a - b;
332 }
333 
334 long double _Complex mul_long_double_rr(long double a, long double b) {
335   // X86-LABEL: @mul_long_double_rr(
336   // X86: fmul
337   // X86-NOT: fmul
338   // X86: ret
339   return a * b;
340 }
341 long double _Complex mul_long_double_cr(long double _Complex a, long double b) {
342   // X86-LABEL: @mul_long_double_cr(
343   // X86: fmul
344   // X86: fmul
345   // X86-NOT: fmul
346   // X86: ret
347   return a * b;
348 }
349 long double _Complex mul_long_double_rc(long double a, long double _Complex b) {
350   // X86-LABEL: @mul_long_double_rc(
351   // X86: fmul
352   // X86: fmul
353   // X86-NOT: fmul
354   // X86: ret
355   return a * b;
356 }
357 long double _Complex mul_long_double_cc(long double _Complex a, long double _Complex b) {
358   // X86-LABEL: @mul_long_double_cc(
359   // X86: %[[AC:[^ ]+]] = fmul
360   // X86: %[[BD:[^ ]+]] = fmul
361   // X86: %[[AD:[^ ]+]] = fmul
362   // X86: %[[BC:[^ ]+]] = fmul
363   // X86: %[[RR:[^ ]+]] = fsub x86_fp80 %[[AC]], %[[BD]]
364   // X86: %[[RI:[^ ]+]] = fadd x86_fp80
365   // X86-DAG: %[[AD]]
366   // X86-DAG: ,
367   // X86-DAG: %[[BC]]
368   // X86: fcmp uno x86_fp80 %[[RR]]
369   // X86: fcmp uno x86_fp80 %[[RI]]
370   // X86: call {{.*}} @__mulxc3(
371   // X86: ret
372   // PPC-LABEL: @mul_long_double_cc(
373   // PPC: %[[AC:[^ ]+]] = fmul
374   // PPC: %[[BD:[^ ]+]] = fmul
375   // PPC: %[[AD:[^ ]+]] = fmul
376   // PPC: %[[BC:[^ ]+]] = fmul
377   // PPC: %[[RR:[^ ]+]] = fsub ppc_fp128 %[[AC]], %[[BD]]
378   // PPC: %[[RI:[^ ]+]] = fadd ppc_fp128
379   // PPC-DAG: %[[AD]]
380   // PPC-DAG: ,
381   // PPC-DAG: %[[BC]]
382   // PPC: fcmp uno ppc_fp128 %[[RR]]
383   // PPC: fcmp uno ppc_fp128 %[[RI]]
384   // PPC: call {{.*}} @__multc3(
385   // PPC: ret
386   return a * b;
387 }
388 
389 long double _Complex div_long_double_rr(long double a, long double b) {
390   // X86-LABEL: @div_long_double_rr(
391   // X86: fdiv
392   // X86-NOT: fdiv
393   // X86: ret
394   return a / b;
395 }
396 long double _Complex div_long_double_cr(long double _Complex a, long double b) {
397   // X86-LABEL: @div_long_double_cr(
398   // X86: fdiv
399   // X86: fdiv
400   // X86-NOT: fdiv
401   // X86: ret
402   return a / b;
403 }
404 long double _Complex div_long_double_rc(long double a, long double _Complex b) {
405   // X86-LABEL: @div_long_double_rc(
406   // X86-NOT: fdiv
407   // X86: call {{.*}} @__divxc3(
408   // X86: ret
409   // PPC-LABEL: @div_long_double_rc(
410   // PPC-NOT: fdiv
411   // PPC: call {{.*}} @__divtc3(
412   // PPC: ret
413   return a / b;
414 }
415 long double _Complex div_long_double_cc(long double _Complex a, long double _Complex b) {
416   // X86-LABEL: @div_long_double_cc(
417   // X86-NOT: fdiv
418   // X86: call {{.*}} @__divxc3(
419   // X86: ret
420   // PPC-LABEL: @div_long_double_cc(
421   // PPC-NOT: fdiv
422   // PPC: call {{.*}} @__divtc3(
423   // PPC: ret
424   return a / b;
425 }
426 
427 // Comparison operators don't rely on library calls or have interseting math
428 // properties, but test that mixed types work correctly here.
429 _Bool eq_float_cr(float _Complex a, float b) {
430   // X86-LABEL: @eq_float_cr(
431   // X86: fcmp oeq
432   // X86: fcmp oeq
433   // X86: and i1
434   // X86: ret
435   return a == b;
436 }
437 _Bool eq_float_rc(float a, float _Complex b) {
438   // X86-LABEL: @eq_float_rc(
439   // X86: fcmp oeq
440   // X86: fcmp oeq
441   // X86: and i1
442   // X86: ret
443   return a == b;
444 }
445 _Bool eq_float_cc(float _Complex a, float _Complex b) {
446   // X86-LABEL: @eq_float_cc(
447   // X86: fcmp oeq
448   // X86: fcmp oeq
449   // X86: and i1
450   // X86: ret
451   return a == b;
452 }
453 _Bool ne_float_cr(float _Complex a, float b) {
454   // X86-LABEL: @ne_float_cr(
455   // X86: fcmp une
456   // X86: fcmp une
457   // X86: or i1
458   // X86: ret
459   return a != b;
460 }
461 _Bool ne_float_rc(float a, float _Complex b) {
462   // X86-LABEL: @ne_float_rc(
463   // X86: fcmp une
464   // X86: fcmp une
465   // X86: or i1
466   // X86: ret
467   return a != b;
468 }
469 _Bool ne_float_cc(float _Complex a, float _Complex b) {
470   // X86-LABEL: @ne_float_cc(
471   // X86: fcmp une
472   // X86: fcmp une
473   // X86: or i1
474   // X86: ret
475   return a != b;
476 }
477 
478 // Check that the libcall will obtain proper calling convention on ARM
479 _Complex double foo(_Complex double a, _Complex double b) {
480   // These functions are not defined as floating point helper functions in
481   // Run-time ABI for the ARM architecture document so they must not always
482   // use the base AAPCS.
483 
484   // ARM-LABEL: @foo(
485   // ARM: call void { double, double } @__muldc3
486 
487   // ARMHF-LABEL: @foo(
488   // ARMHF: call { double, double } @__muldc3
489 
490   // ARM7K-LABEL: @foo(
491   // ARM7K: call { double, double } @__muldc3
492   return a*b;
493 }
494