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