aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target/i386/excess-precision-3.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target/i386/excess-precision-3.c')
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/i386/excess-precision-3.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/i386/excess-precision-3.c b/gcc-4.9/gcc/testsuite/gcc.target/i386/excess-precision-3.c
new file mode 100644
index 000000000..1fd038a87
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/i386/excess-precision-3.c
@@ -0,0 +1,237 @@
+/* Excess precision tests. Test excess precision is removed when
+ necessary. */
+/* { dg-do run } */
+/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
+
+#include <float.h>
+#include <stdarg.h>
+
+extern void abort (void);
+extern void exit (int);
+
+volatile float f1 = 1.0f;
+volatile float f2 = 0x1.0p-30f;
+volatile float f3 = 0x1.0p-60f;
+volatile double d1 = 1.0;
+volatile double d2 = 0x1.0p-30;
+volatile double d3 = 0x1.0p-60;
+volatile double d3d = 0x1.0p-52;
+volatile float fadd1 = 1.0f + 0x1.0p-30f;
+volatile double dadd2 = 1.0 + 0x1.0p-30 + 0x1.0p-60;
+volatile double dh = 0x1.0p-24;
+volatile float fha = 1.0f + 0x1.0p-23f;
+
+void
+test_assign (void)
+{
+ float f;
+ double d;
+ f = f1 + f2;
+ if (f != fadd1)
+ abort ();
+ d = f1 + f2;
+ if (d != dadd2)
+ abort ();
+ d = d1 + d2 + d3;
+ if (d != dadd2)
+ abort ();
+ /* Verify rounding direct to float without double rounding. */
+ if (sizeof(long double) > sizeof(double) ) {
+ f = d1 + dh + d3;
+ if (f != fha)
+ abort ();
+ } else {
+ f = d1 + dh + d3d;
+ if (f != fha)
+ abort ();
+ }
+}
+
+void
+test_init (void)
+{
+ float f = f1 + f2;
+ double d = d1 + d2 + d3;
+ if (f != fadd1)
+ abort ();
+ if (d != dadd2)
+ abort ();
+}
+
+volatile int i1 = 0x40000001;
+volatile unsigned int u1 = 0x80000001u;
+volatile long long ll1 = 0x4000000000000001ll;
+volatile unsigned long long ull1 = 0x8000000000000001ull;
+
+void
+test_cast (void)
+{
+ if ((float)(f1 + f2) != fadd1)
+ abort ();
+ if ((double)(d1 + d2 + d3) != dadd2)
+ abort ();
+ if ((double)(f1 + f2 + f3) != dadd2)
+ abort ();
+ if ((float)i1 != 0x1.0p30f)
+ abort ();
+ if ((float)u1 != 0x1.0p31f)
+ abort ();
+ if ((float)ll1 != 0x1.0p62f)
+ abort ();
+ if ((float)ull1 != 0x1.0p63f)
+ abort ();
+ if ((double)ll1 != 0x1.0p62)
+ abort ();
+ if ((double)ull1 != 0x1.0p63)
+ abort ();
+}
+
+static inline void
+check_float (float f)
+{
+ if (f != fadd1)
+ abort ();
+}
+
+static inline void
+check_double (double d)
+{
+ if (d != dadd2)
+ abort ();
+}
+
+static inline void
+check_float_nonproto (f)
+ float f;
+{
+ if (f != fadd1)
+ abort ();
+}
+
+static inline void
+check_double_nonproto (d)
+ double d;
+{
+ if (d != dadd2)
+ abort ();
+}
+
+static void
+check_double_va (int i, ...)
+{
+ va_list ap;
+ va_start (ap, i);
+ if (va_arg (ap, double) != dadd2)
+ abort ();
+ va_end (ap);
+}
+
+void
+test_call (void)
+{
+ check_float (f1 + f2);
+ check_double (d1 + d2 + d3);
+ check_double (f1 + f2 + f3);
+ check_float_nonproto (f1 + f2);
+ check_double_nonproto (d1 + d2 + d3);
+ check_double_nonproto (f1 + f2 + f3);
+ check_double_va (0, d1 + d2 + d3);
+ check_double_va (0, f1 + f2 + f3);
+}
+
+static inline float
+return_float (void)
+{
+ return f1 + f2;
+}
+
+static inline double
+return_double1 (void)
+{
+ return d1 + d2 + d3;
+}
+
+static inline double
+return_double2 (void)
+{
+ return f1 + f2 + f3;
+}
+
+void
+test_return (void)
+{
+ if (return_float () != fadd1)
+ abort ();
+ if (return_double1 () != dadd2)
+ abort ();
+ if (return_double2 () != dadd2)
+ abort ();
+}
+
+volatile float flt_min = FLT_MIN;
+volatile double dbl_min = DBL_MIN;
+volatile float flt_max = FLT_MAX;
+volatile double dbl_max = DBL_MAX;
+
+void
+test_builtin (void)
+{
+ /* Classification macros convert to the semantic type. signbit and
+ comparison macros do not. */
+ if (!__builtin_isinf (flt_max * flt_max))
+ abort ();
+ if (!__builtin_isinf (dbl_max * dbl_max))
+ abort ();
+ if (__builtin_isnormal (flt_max * flt_max))
+ abort ();
+ if (__builtin_isnormal (dbl_max * dbl_max))
+ abort ();
+ if (__builtin_isfinite (flt_max * flt_max))
+ abort ();
+ if (__builtin_isfinite (dbl_max * dbl_max))
+ abort ();
+ if (!__builtin_isgreater (flt_min * flt_min, 0.0f))
+ abort ();
+ if (!__builtin_isgreaterequal (flt_min * flt_min, 0.0f))
+ abort ();
+ if (!__builtin_isless (0.0f, flt_min * flt_min))
+ abort ();
+ if (__builtin_islessequal (flt_min * flt_min, 0.0f))
+ abort ();
+ if (!__builtin_islessgreater (flt_min * flt_min, 0.0f))
+ abort ();
+ if (!__builtin_isgreaterequal (dbl_min * dbl_min, 0.0))
+ abort ();
+ if (sizeof(long double) > sizeof(double) ) {
+ if (!__builtin_isgreater (dbl_min * dbl_min, 0.0))
+ abort ();
+ if (!__builtin_isless (0.0, dbl_min * dbl_min))
+ abort ();
+ if (__builtin_islessequal (dbl_min * dbl_min, 0.0))
+ abort ();
+ if (!__builtin_islessgreater (dbl_min * dbl_min, 0.0))
+ abort ();
+ }
+ else {
+ if (__builtin_isgreater (dbl_min * dbl_min, 0.0))
+ abort ();
+ if (__builtin_isless (0.0, dbl_min * dbl_min))
+ abort ();
+ if (!__builtin_islessequal (dbl_min * dbl_min, 0.0))
+ abort ();
+ if (__builtin_islessgreater (dbl_min * dbl_min, 0.0))
+ abort ();
+ }
+}
+
+int
+main (void)
+{
+ test_assign ();
+ test_init ();
+ test_cast ();
+ test_call ();
+ test_return ();
+ test_builtin ();
+ exit (0);
+}