1  /* Excess precision tests.  Test excess precision is removed when
       2     necessary.  */
       3  /* { dg-do run } */
       4  /* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
       5  
       6  #include <float.h>
       7  #include <stdarg.h>
       8  
       9  #ifdef __cplusplus
      10  extern "C" {
      11  #endif
      12  extern void abort (void);
      13  extern void exit (int);
      14  #ifdef __cplusplus
      15  }
      16  #endif
      17  
      18  volatile float f1 = 1.0f;
      19  volatile float f2 = 0x1.0p-30f;
      20  volatile float f3 = 0x1.0p-60f;
      21  volatile double d1 = 1.0;
      22  volatile double d2 = 0x1.0p-30;
      23  volatile double d3 = 0x1.0p-60;
      24  volatile double d3d = 0x1.0p-52;
      25  volatile float fadd1 = 1.0f + 0x1.0p-30f;
      26  volatile double dadd2 = 1.0 + 0x1.0p-30 + 0x1.0p-60;
      27  volatile double dh = 0x1.0p-24;
      28  volatile float fha = 1.0f + 0x1.0p-23f;
      29  
      30  void
      31  test_assign (void)
      32  {
      33    float f;
      34    double d;
      35    f = f1 + f2;
      36    if (f != fadd1)
      37      abort ();
      38    d = f1 + f2;
      39    if (d != dadd2)
      40      abort ();
      41    d = d1 + d2 + d3;
      42    if (d != dadd2)
      43      abort ();
      44    /* Verify rounding direct to float without double rounding.  */
      45    if (sizeof(long double) > sizeof(double)  )  {
      46      f = d1 + dh + d3;
      47      if (f != fha)
      48        abort ();
      49    } else {
      50        f = d1 + dh + d3d;
      51        if (f != fha)
      52          abort ();
      53    }
      54  }
      55  
      56  void
      57  test_init (void)
      58  {
      59    float f = f1 + f2;
      60    double d = d1 + d2 + d3;
      61    if (f != fadd1)
      62      abort ();
      63    if (d != dadd2)
      64      abort ();
      65  }
      66  
      67  volatile int i1 = 0x40000001;
      68  volatile unsigned int u1 = 0x80000001u;
      69  volatile long long ll1 = 0x4000000000000001ll;
      70  volatile unsigned long long ull1 = 0x8000000000000001ull;
      71  
      72  void
      73  test_cast (void)
      74  {
      75    if ((float)(f1 + f2) != fadd1)
      76      abort ();
      77    if ((double)(d1 + d2 + d3) != dadd2)
      78      abort ();
      79    if ((double)(f1 + f2 + f3) != dadd2)
      80      abort ();
      81    if ((float)i1 != 0x1.0p30f)
      82      abort ();
      83    if ((float)u1 != 0x1.0p31f)
      84      abort ();
      85    if ((float)ll1 != 0x1.0p62f)
      86      abort ();
      87    if ((float)ull1 != 0x1.0p63f)
      88      abort ();
      89    if ((double)ll1 != 0x1.0p62)
      90      abort ();
      91    if ((double)ull1 != 0x1.0p63)
      92      abort ();
      93  }
      94  
      95  static inline void
      96  check_float (float f)
      97  {
      98    if (f != fadd1)
      99      abort ();
     100  }
     101  
     102  static inline void
     103  check_double (double d)
     104  {
     105    if (d != dadd2)
     106      abort ();
     107  }
     108  
     109  #ifndef __cplusplus
     110  static inline void
     111  check_float_nonproto (f)
     112       float f;
     113  {
     114    if (f != fadd1)
     115      abort ();
     116  }
     117  
     118  static inline void
     119  check_double_nonproto (d)
     120       double d;
     121  {
     122    if (d != dadd2)
     123      abort ();
     124  }
     125  #endif
     126  
     127  static void
     128  check_double_va (int i, ...)
     129  {
     130    va_list ap;
     131    va_start (ap, i);
     132    if (va_arg (ap, double) != dadd2)
     133      abort ();
     134    va_end (ap);
     135  }
     136  
     137  void
     138  test_call (void)
     139  {
     140    check_float (f1 + f2);
     141    check_double (d1 + d2 + d3);
     142    check_double (f1 + f2 + f3);
     143  #ifndef __cplusplus
     144    check_float_nonproto (f1 + f2);
     145    check_double_nonproto (d1 + d2 + d3);
     146    check_double_nonproto (f1 + f2 + f3);
     147  #endif
     148    check_double_va (0, d1 + d2 + d3);
     149    check_double_va (0, f1 + f2 + f3);
     150  }
     151  
     152  static inline float
     153  return_float (void)
     154  {
     155    return f1 + f2;
     156  }
     157  
     158  static inline double
     159  return_double1 (void)
     160  {
     161    return d1 + d2 + d3;
     162  }
     163  
     164  static inline double
     165  return_double2 (void)
     166  {
     167    return f1 + f2 + f3;
     168  }
     169  
     170  void
     171  test_return (void)
     172  {
     173    if (return_float () != fadd1)
     174      abort ();
     175    if (return_double1 () != dadd2)
     176      abort ();
     177    if (return_double2 () != dadd2)
     178      abort ();
     179  }
     180  
     181  volatile float flt_min = FLT_MIN;
     182  volatile double dbl_min = DBL_MIN;
     183  volatile float flt_max = FLT_MAX;
     184  volatile double dbl_max = DBL_MAX;
     185  
     186  void
     187  test_builtin (void)
     188  {
     189    /* Classification macros convert to the semantic type.  signbit and
     190       comparison macros do not.  */
     191    if (!__builtin_isinf (flt_max * flt_max))
     192      abort ();
     193    if (!__builtin_isinf (dbl_max * dbl_max))
     194      abort ();
     195    if (__builtin_isnormal (flt_max * flt_max))
     196      abort ();
     197    if (__builtin_isnormal (dbl_max * dbl_max))
     198      abort ();
     199    if (__builtin_isfinite (flt_max * flt_max))
     200      abort ();
     201    if (__builtin_isfinite (dbl_max * dbl_max))
     202      abort ();
     203    if (!__builtin_isgreater (flt_min * flt_min, 0.0f))
     204      abort ();
     205    if (!__builtin_isgreaterequal (flt_min * flt_min, 0.0f))
     206      abort ();
     207    if (!__builtin_isless (0.0f, flt_min * flt_min))
     208      abort ();
     209    if (__builtin_islessequal (flt_min * flt_min, 0.0f))
     210      abort ();
     211    if (!__builtin_islessgreater (flt_min * flt_min, 0.0f))
     212      abort ();
     213    if (!__builtin_isgreaterequal (dbl_min * dbl_min, 0.0))
     214      abort ();
     215    if (sizeof(long double) > sizeof(double)  ) {
     216      if (!__builtin_isgreater (dbl_min * dbl_min, 0.0))
     217        abort ();
     218      if (!__builtin_isless (0.0, dbl_min * dbl_min))
     219        abort ();
     220      if (__builtin_islessequal (dbl_min * dbl_min, 0.0))
     221        abort ();
     222      if (!__builtin_islessgreater (dbl_min * dbl_min, 0.0))
     223        abort ();
     224    }
     225    else {
     226      if (__builtin_isgreater (dbl_min * dbl_min, 0.0))
     227        abort ();
     228      if (__builtin_isless (0.0, dbl_min * dbl_min))
     229        abort ();
     230      if (!__builtin_islessequal (dbl_min * dbl_min, 0.0))
     231        abort ();
     232      if (__builtin_islessgreater (dbl_min * dbl_min, 0.0))
     233        abort ();
     234    }
     235  }
     236  
     237  int
     238  main (void)
     239  {
     240    test_assign ();
     241    test_init ();
     242    test_cast ();
     243    test_call ();
     244    test_return ();
     245    test_builtin ();
     246    exit (0);
     247  }