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
      10  flt_mul_add (float a, float b, float c)
      11  {
      12    return (a * b) + c;
      13  }
      14  
      15  double
      16  dbl_mul_add (double a, double b, double c)
      17  {
      18    return (a * b) + c;
      19  }
      20  
      21  float
      22  flt_mul_sub (float a, float b, float c)
      23  {
      24    return (a * b) - c;
      25  }
      26  
      27  double
      28  dbl_mul_sub (double a, double b, double c)
      29  {
      30    return (a * b) - c;
      31  }
      32  
      33  float
      34  flt_neg_mul_add (float a, float b, float c)
      35  {
      36    return (-(a * b)) + c;
      37  }
      38  
      39  double
      40  dbl_neg_mul_add (double a, double b, double c)
      41  {
      42    return (-(a * b)) + c;
      43  }
      44  
      45  float
      46  flt_neg_mul_sub (float a, float b, float c)
      47  {
      48    return (-(a * b)) - c;
      49  }
      50  
      51  double
      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  
      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" } } */