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