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