1 /* Test that the compiler properly optimizes floating point multiply
2 and add instructions FMA3 systems. */
3
4 /* { dg-do compile { target { ! ia32 } } } */
5 /* { dg-options "-O2 -mfma -mno-fma4" } */
6
7 extern void exit (int);
8
9 float
flt_mul_add(float a,float b,float c)10 flt_mul_add (float a, float b, float c)
11 {
12 return (a * b) + c;
13 }
14
15 double
dbl_mul_add(double a,double b,double c)16 dbl_mul_add (double a, double b, double c)
17 {
18 return (a * b) + c;
19 }
20
21 float
flt_mul_sub(float a,float b,float c)22 flt_mul_sub (float a, float b, float c)
23 {
24 return (a * b) - c;
25 }
26
27 double
dbl_mul_sub(double a,double b,double c)28 dbl_mul_sub (double a, double b, double c)
29 {
30 return (a * b) - c;
31 }
32
33 float
flt_neg_mul_add(float a,float b,float c)34 flt_neg_mul_add (float a, float b, float c)
35 {
36 return (-(a * b)) + c;
37 }
38
39 double
dbl_neg_mul_add(double a,double b,double c)40 dbl_neg_mul_add (double a, double b, double c)
41 {
42 return (-(a * b)) + c;
43 }
44
45 float
flt_neg_mul_sub(float a,float b,float c)46 flt_neg_mul_sub (float a, float b, float c)
47 {
48 return (-(a * b)) - c;
49 }
50
51 double
dbl_neg_mul_sub(double a,double b,double c)52 dbl_neg_mul_sub (double a, double b, double c)
53 {
54 return (-(a * b)) - c;
55 }
56
57 float f[10] = { 2, 3, 4 };
58 double d[10] = { 2, 3, 4 };
59
main()60 int main ()
61 {
62 f[3] = flt_mul_add (f[0], f[1], f[2]);
63 f[4] = flt_mul_sub (f[0], f[1], f[2]);
64 f[5] = flt_neg_mul_add (f[0], f[1], f[2]);
65 f[6] = flt_neg_mul_sub (f[0], f[1], f[2]);
66
67 d[3] = dbl_mul_add (d[0], d[1], d[2]);
68 d[4] = dbl_mul_sub (d[0], d[1], d[2]);
69 d[5] = dbl_neg_mul_add (d[0], d[1], d[2]);
70 d[6] = dbl_neg_mul_sub (d[0], d[1], d[2]);
71 exit (0);
72 }
73
74 /* { dg-final { scan-assembler "vfmadd...ss" } } */
75 /* { dg-final { scan-assembler "vfmadd...sd" } } */
76 /* { dg-final { scan-assembler "vfmsub...ss" } } */
77 /* { dg-final { scan-assembler "vfmsub...sd" } } */
78 /* { dg-final { scan-assembler "vfnmadd...ss" } } */
79 /* { dg-final { scan-assembler "vfnmadd...sd" } } */
80 /* { dg-final { scan-assembler "vfnmsub...ss" } } */
81 /* { dg-final { scan-assembler "vfnmsub...sd" } } */
82