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