diff options
Diffstat (limited to 'gcc/testsuite/gcc.c-torture/execute/ieee')
76 files changed, 2764 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c new file mode 100644 index 000000000..873a17df4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c @@ -0,0 +1,104 @@ +#if defined(__mips__) && defined(__sgi__) +#include <sys/fpu.h> +#endif /* defined(__mips__) && defined(__sgi__) */ +#if __INT_MAX__ != 2147483647 || (__LONG_LONG_MAX__ != 9223372036854775807ll && __LONG_MAX__ != 9223372036854775807ll) +int main(void) { exit (0); } +#else +#if __LONG_MAX__ != 9223372036854775807ll +typedef unsigned long long ull; +#else +typedef unsigned long ull; +#endif +typedef unsigned ul; + +union fl { + float f; + ul l; +} uf; +union dl { + double d; + ull ll; +} ud; + +int failed = 0; + +void c(ull d, ul f) +{ + ud.ll = d; + uf.f = (float) ud.d; + if (uf.l != f) + { + failed++; + } +} + +int main() +{ +#if defined(__mips__) && defined(__sgi__) + /* Many MIPS chips round denormalized floating point numbers to zero + rather than follow the IEEE standard. Change the rounding mode + to correspond to the IEEE rounding mode that rounds numbers to + the nearest representable mode, the most common IEEE rounding + mode. */ + set_fpc_csr(0); +#endif /* defined(__mips__) && defined(__sgi__) */ + + if (sizeof (float) != sizeof (ul) + || sizeof (double) != sizeof (ull)) + exit (0); + + c(0x3690000000000000ULL, 0x00000000U); +#if (defined __arm__ || defined __thumb__) && ! (defined __ARMEB__ || defined __VFP_FP__) + /* The ARM always stores FP numbers in big-wordian format, + even when running in little-byteian mode. */ + c(0x0000000136900000ULL, 0x00000001U); + c(0xffffffff369fffffULL, 0x00000001U); + c(0x0000000036A00000ULL, 0x00000001U); + c(0xffffffff36A7ffffULL, 0x00000001U); + c(0x0000000036A80000ULL, 0x00000002U); + c(0xffffffff36AfffffULL, 0x00000002U); + c(0x0000000036b00000ULL, 0x00000002U); + c(0x0000000136b00000ULL, 0x00000002U); + + c(0xdfffffff380fffffULL, 0x007fffffU); + c(0xe0000000380fffffULL, 0x00800000U); + c(0xe0000001380fffffULL, 0x00800000U); + c(0xffffffff380fffffULL, 0x00800000U); + c(0x0000000038100000ULL, 0x00800000U); + c(0x0000000138100000ULL, 0x00800000U); + c(0x1000000038100000ULL, 0x00800000U); + c(0x1000000138100000ULL, 0x00800001U); + c(0x2fffffff38100000ULL, 0x00800001U); + c(0x3000000038100000ULL, 0x00800002U); + c(0x5000000038100000ULL, 0x00800002U); + c(0x5000000138100000ULL, 0x00800003U); +#else + c(0x3690000000000001ULL, 0x00000001U); + c(0x369fffffffffffffULL, 0x00000001U); + c(0x36A0000000000000ULL, 0x00000001U); + c(0x36A7ffffffffffffULL, 0x00000001U); + c(0x36A8000000000000ULL, 0x00000002U); + c(0x36AfffffffffffffULL, 0x00000002U); + c(0x36b0000000000000ULL, 0x00000002U); + c(0x36b0000000000001ULL, 0x00000002U); + + c(0x380fffffdfffffffULL, 0x007fffffU); + c(0x380fffffe0000000ULL, 0x00800000U); + c(0x380fffffe0000001ULL, 0x00800000U); + c(0x380fffffffffffffULL, 0x00800000U); + c(0x3810000000000000ULL, 0x00800000U); + c(0x3810000000000001ULL, 0x00800000U); + c(0x3810000010000000ULL, 0x00800000U); + c(0x3810000010000001ULL, 0x00800001U); + c(0x381000002fffffffULL, 0x00800001U); + c(0x3810000030000000ULL, 0x00800002U); + c(0x3810000050000000ULL, 0x00800002U); + c(0x3810000050000001ULL, 0x00800003U); +#endif + + if (failed) + abort (); + else + exit (0); +} +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.x new file mode 100644 index 000000000..4535c611e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.x @@ -0,0 +1,10 @@ +if {[istarget "m68k-*-*"] && [check_effective_target_coldfire_fpu]} { + # ColdFire FPUs require software handling of subnormals. We are + # not aware of any system that has this. + set torture_execute_xfail "m68k-*-*" +} +if [istarget "avr-*-*"] { + # AVR doubles are floats + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20001122-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20001122-1.c new file mode 100644 index 000000000..fd7e70262 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20001122-1.c @@ -0,0 +1,22 @@ +volatile double a, *p; + +int main () +{ + double c, d; + volatile double b; + + d = 1.0; + p = &b; + do + { + c = d; + d = c * 0.5; + b = 1 + d; + } while (b != 1.0); + + a = 1.0 + c; + if (a == 1.0) + abort(); + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.c new file mode 100644 index 000000000..e5ab9485f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.c @@ -0,0 +1,31 @@ +extern void exit (int); +extern void abort (void); + +float +rintf (float x) +{ + static const float TWO23 = 8388608.0; + + if (__builtin_fabs (x) < TWO23) + { + if (x > 0.0) + { + x += TWO23; + x -= TWO23; + } + else if (x < 0.0) + { + x = TWO23 - x; + x = -(x - TWO23); + } + } + + return x; +} + +int main (void) +{ + if (rintf (-1.5) != -2.0) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x b/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x new file mode 100644 index 000000000..73b18d160 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x @@ -0,0 +1,6 @@ +if [istarget "spu-*-*"] { + # This doesn't work on the SPU because single precision floats are + # always rounded toward 0. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20010226-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20010226-1.c new file mode 100644 index 000000000..ec292aca3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20010226-1.c @@ -0,0 +1,24 @@ +#include <float.h> + +long double dfrom = 1.1L; +long double m1; +long double m2; +unsigned long mant_long; + +int main() +{ + /* Some targets don't support a conforming long double type. This is + common with very small parts which set long double == float. Look + to see if the type has at least 32 bits of precision. */ + if (LDBL_EPSILON > 0x1p-31L) + return 0; + + m1 = dfrom / 2.0L; + m2 = m1 * 4294967296.0L; + mant_long = ((unsigned long) m2) & 0xffffffff; + + if (mant_long == 0x8ccccccc) + return 0; + else + abort(); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20011123-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20011123-1.c new file mode 100644 index 000000000..e497251fe --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20011123-1.c @@ -0,0 +1,12 @@ +main() +{ + double db1 = 1.7976931348623157e+308; + long double ldb1 = db1; + + if (sizeof (double) != 8 || sizeof (long double) != 16) + exit (0); + + if (ldb1 != 1.7976931348623157e+308) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.c new file mode 100644 index 000000000..64d87e13b --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.c @@ -0,0 +1,32 @@ +extern void exit (int); +extern void abort (void); +float x = -1.5f; + +float +rintf () +{ + static const float TWO23 = 8388608.0; + + if (__builtin_fabs (x) < TWO23) + { + if (x > 0.0) + { + x += TWO23; + x -= TWO23; + } + else if (x < 0.0) + { + x = TWO23 - x; + x = -(x - TWO23); + } + } + + return x; +} + +int main (void) +{ + if (rintf () != -2.0) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x new file mode 100644 index 000000000..73b18d160 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x @@ -0,0 +1,6 @@ +if [istarget "spu-*-*"] { + # This doesn't work on the SPU because single precision floats are + # always rounded toward 0. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/20041213-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/20041213-1.c new file mode 100644 index 000000000..07bdf6860 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/20041213-1.c @@ -0,0 +1,17 @@ +extern double sqrt (double); +extern void abort (void); +int once; + +double foo (void) +{ + if (once++) + abort (); + return 0.0 / 0.0; +} + +double x; +int main (void) +{ + x = sqrt (foo ()); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.c new file mode 100644 index 000000000..7f072b298 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.c @@ -0,0 +1,8 @@ +unsigned u=2147483839;float f0=2147483648e0,f1=2147483904e0; +main() +{ + float f=u; + if(f==f0) + abort(); + exit(0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x new file mode 100644 index 000000000..73b18d160 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x @@ -0,0 +1,6 @@ +if [istarget "spu-*-*"] { + # This doesn't work on the SPU because single precision floats are + # always rounded toward 0. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/920810-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/920810-1.c new file mode 100644 index 000000000..62d22940a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/920810-1.c @@ -0,0 +1,3 @@ +#include <stdio.h> +double normalize(x)double x;{if(x==0)x=0;return x;} +main(){char b[9];sprintf(b,"%g",normalize(-0.0));if(strcmp(b,"0"))abort();exit(0);} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/930529-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/930529-1.c new file mode 100644 index 000000000..b96a3c064 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/930529-1.c @@ -0,0 +1,27 @@ +main () +{ + union { + double d; + unsigned char c[8]; + } d; + + d.d = 1.0/7.0; + + if (sizeof (char) * 8 == sizeof (double)) + { + if (d.c[0] == 0x92 && d.c[1] == 0x24 && d.c[2] == 0x49 && d.c[3] == 0x92 + && d.c[4] == 0x24 && d.c[5] == 0x49 && d.c[6] == 0xc2 && d.c[7] == 0x3f) + exit (0); + if (d.c[7] == 0x92 && d.c[6] == 0x24 && d.c[5] == 0x49 && d.c[4] == 0x92 + && d.c[3] == 0x24 && d.c[2] == 0x49 && d.c[1] == 0xc2 && d.c[0] == 0x3f) + exit (0); +#if defined __arm__ || defined __thumb__ + if (d.c[4] == 0x92 && d.c[5] == 0x24 && d.c[6] == 0x49 && d.c[7] == 0x92 + && d.c[0] == 0x24 && d.c[1] == 0x49 && d.c[2] == 0xc2 && d.c[3] == 0x3f) + exit (0); +#endif + abort (); + } + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.c new file mode 100644 index 000000000..0465ed51c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.c @@ -0,0 +1,23 @@ + int main(void) + { + float reale = 1.0f; + float oneplus; + int i; + + if (sizeof (float) != 4) + exit (0); + + for (i = 0; ; i++) + { + oneplus = 1.0f + reale; + if (oneplus == 1.0f) + break; + reale=reale/2.0f; + } + /* Assumes ieee754 accurate arithmetic above. */ + if (i != 24) + abort (); + else + exit (0); + } + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.x new file mode 100644 index 000000000..4e65f3abd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.x @@ -0,0 +1,15 @@ +# This used to fail on ia32, with or without -ffloat-store. +# It works now, but some people think that's a fluke, so I'm +# keeping this around just in case. + +#set torture_eval_before_execute { +# +# set compiler_conditional_xfail_data { +# "ia32 fp rounding isn't pedantic" \ +# "i?86-*-*" \ +# { "-O3" "-O2" "-O1" "-Os"} \ +# { "" } +# } +#} + +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/acc1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/acc1.c new file mode 100644 index 000000000..e0d969b9d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/acc1.c @@ -0,0 +1,18 @@ +/* Tail call optimizations would reverse the order of additions in func(). */ + +double func (const double *array) +{ + double d = *array; + if (d == 0.0) + return d; + else + return d + func (array + 1); +} + +int main () +{ + double values[] = { 0.1e-100, 1.0, -1.0, 0.0 }; + if (func (values) != 0.1e-100) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/acc2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/acc2.c new file mode 100644 index 000000000..2a44c8a01 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/acc2.c @@ -0,0 +1,19 @@ +/* Tail call optimizations would reverse the order of multiplications + in func(). */ + +double func (const double *array) +{ + double d = *array; + if (d == 1.0) + return d; + else + return d * func (array + 1); +} + +int main () +{ + double values[] = { __DBL_MAX__, 2.0, 0.5, 1.0 }; + if (func (values) != __DBL_MAX__) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/builtin-nan-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/builtin-nan-1.c new file mode 100644 index 000000000..a487dd4af --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/builtin-nan-1.c @@ -0,0 +1,17 @@ +/* PR middle-end/19983 */ + +typedef __SIZE_TYPE__ size_t; + +extern void abort(void); +extern int memcmp(const void *, const void *, size_t); + +double n1 = __builtin_nan("0x1"); +double n2 = __builtin_nan("0X1"); + +int main() +{ + if (memcmp (&n1, &n2, sizeof(double))) + abort(); + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.c new file mode 100644 index 000000000..81642534c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.c @@ -0,0 +1,189 @@ +/* Copyright (C) 2004 Free Software Foundation. + + Test for correctness of composite floating-point comparisons. + + Written by Paolo Bonzini, 26th May 2004. */ + +extern void abort (void); + +#define TEST(c) if ((c) != ok) abort (); +#define ORD(a, b) (!__builtin_isunordered ((a), (b))) +#define UNORD(a, b) (__builtin_isunordered ((a), (b))) +#define UNEQ(a, b) (__builtin_isunordered ((a), (b)) || ((a) == (b))) +#define UNLT(a, b) (__builtin_isunordered ((a), (b)) || ((a) < (b))) +#define UNLE(a, b) (__builtin_isunordered ((a), (b)) || ((a) <= (b))) +#define UNGT(a, b) (__builtin_isunordered ((a), (b)) || ((a) > (b))) +#define UNGE(a, b) (__builtin_isunordered ((a), (b)) || ((a) >= (b))) +#define LTGT(a, b) (__builtin_islessgreater ((a), (b))) + +float pinf; +float ninf; +float NaN; + +int iuneq (float x, float y, int ok) +{ + TEST (UNEQ (x, y)); + TEST (!LTGT (x, y)); + TEST (UNLE (x, y) && UNGE (x,y)); +} + +int ieq (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNEQ (x, y)); +} + +int iltgt (float x, float y, int ok) +{ + TEST (!UNEQ (x, y)); /* Not optimizable. */ + TEST (LTGT (x, y)); /* Same, __builtin_islessgreater does not trap. */ + TEST (ORD (x, y) && (UNLT (x, y) || UNGT (x,y))); +} + +int ine (float x, float y, int ok) +{ + TEST (UNLT (x, y) || UNGT (x, y)); +} + +int iunlt (float x, float y, int ok) +{ + TEST (UNLT (x, y)); + TEST (UNORD (x, y) || (x < y)); +} + +int ilt (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNLT (x, y)); /* Not optimized */ + TEST ((x <= y) && (x != y)); + TEST ((x <= y) && (y != x)); + TEST ((x != y) && (x <= y)); /* Not optimized */ + TEST ((y != x) && (x <= y)); /* Not optimized */ +} + +int iunle (float x, float y, int ok) +{ + TEST (UNLE (x, y)); + TEST (UNORD (x, y) || (x <= y)); +} + +int ile (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNLE (x, y)); /* Not optimized */ + TEST ((x < y) || (x == y)); + TEST ((y > x) || (x == y)); + TEST ((x == y) || (x < y)); /* Not optimized */ + TEST ((y == x) || (x < y)); /* Not optimized */ +} + +int iungt (float x, float y, int ok) +{ + TEST (UNGT (x, y)); + TEST (UNORD (x, y) || (x > y)); +} + +int igt (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNGT (x, y)); /* Not optimized */ + TEST ((x >= y) && (x != y)); + TEST ((x >= y) && (y != x)); + TEST ((x != y) && (x >= y)); /* Not optimized */ + TEST ((y != x) && (x >= y)); /* Not optimized */ +} + +int iunge (float x, float y, int ok) +{ + TEST (UNGE (x, y)); + TEST (UNORD (x, y) || (x >= y)); +} + +int ige (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNGE (x, y)); /* Not optimized */ + TEST ((x > y) || (x == y)); + TEST ((y < x) || (x == y)); + TEST ((x == y) || (x > y)); /* Not optimized */ + TEST ((y == x) || (x > y)); /* Not optimized */ +} + +int +main () +{ + pinf = __builtin_inf (); + ninf = -__builtin_inf (); + NaN = __builtin_nan (""); + + iuneq (ninf, pinf, 0); + iuneq (NaN, NaN, 1); + iuneq (pinf, ninf, 0); + iuneq (1, 4, 0); + iuneq (3, 3, 1); + iuneq (5, 2, 0); + + ieq (1, 4, 0); + ieq (3, 3, 1); + ieq (5, 2, 0); + + iltgt (ninf, pinf, 1); + iltgt (NaN, NaN, 0); + iltgt (pinf, ninf, 1); + iltgt (1, 4, 1); + iltgt (3, 3, 0); + iltgt (5, 2, 1); + + ine (1, 4, 1); + ine (3, 3, 0); + ine (5, 2, 1); + + iunlt (NaN, ninf, 1); + iunlt (pinf, NaN, 1); + iunlt (pinf, ninf, 0); + iunlt (pinf, pinf, 0); + iunlt (ninf, ninf, 0); + iunlt (1, 4, 1); + iunlt (3, 3, 0); + iunlt (5, 2, 0); + + ilt (1, 4, 1); + ilt (3, 3, 0); + ilt (5, 2, 0); + + iunle (NaN, ninf, 1); + iunle (pinf, NaN, 1); + iunle (pinf, ninf, 0); + iunle (pinf, pinf, 1); + iunle (ninf, ninf, 1); + iunle (1, 4, 1); + iunle (3, 3, 1); + iunle (5, 2, 0); + + ile (1, 4, 1); + ile (3, 3, 1); + ile (5, 2, 0); + + iungt (NaN, ninf, 1); + iungt (pinf, NaN, 1); + iungt (pinf, ninf, 1); + iungt (pinf, pinf, 0); + iungt (ninf, ninf, 0); + iungt (1, 4, 0); + iungt (3, 3, 0); + iungt (5, 2, 1); + + igt (1, 4, 0); + igt (3, 3, 0); + igt (5, 2, 1); + + iunge (NaN, ninf, 1); + iunge (pinf, NaN, 1); + iunge (ninf, pinf, 0); + iunge (pinf, pinf, 1); + iunge (ninf, ninf, 1); + iunge (1, 4, 0); + iunge (3, 3, 1); + iunge (5, 2, 1); + + ige (1, 4, 0); + ige (3, 3, 1); + ige (5, 2, 1); + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x new file mode 100644 index 000000000..2f7a4ecc5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x @@ -0,0 +1,6 @@ +if [istarget "spu-*-*"] { + # The SPU single-precision floating point format does not + # support Nan & Inf. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-2.c new file mode 100644 index 000000000..1f78a435a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-2.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2004 Free Software Foundation. + + Ensure that the composite comparison optimization doesn't misfire + and attempt to combine an integer comparison with a floating-point one. + + Written by Paolo Bonzini, 26th May 2004. */ + +extern void abort (void); + +int +foo (double x, double y) +{ + /* If miscompiled the following may become false. */ + return (x > y) && ((int)x == (int)y); +} + +int +main () +{ + if (! foo (1.3,1.0)) + abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.c b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.c new file mode 100644 index 000000000..03e6ff2c5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.c @@ -0,0 +1,97 @@ +/* Copyright (C) 2004 Free Software Foundation. + + Test for composite comparison always true/false optimization. + + Written by Paolo Bonzini, 26th May 2004. */ + +extern void link_error0 (); +extern void link_error1 (); + +void +test1 (float x, float y) +{ + if ((x==y) && (x!=y)) + link_error0(); +} + +void +test2 (float x, float y) +{ + if ((x<y) && (x>y)) + link_error0(); +} + +void +test3 (float x, float y) +{ + if ((x<y) && (y<x)) + link_error0(); +} + +void +test4 (float x, float y) +{ + if ((x==y) || (x!=y)) + { + } + else + link_error1 (); +} + +void +test5 (float x, float y) +{ + if (__builtin_isunordered (x, y) || (x>=y) || (x<y)) + { + } + else + link_error1 (); +} + +void +test6 (float x, float y) +{ + if (__builtin_isunordered (y, x) || (x<=y) || (y<x)) + { + } + else + link_error1 (); +} + +void +test7 (float x, float y) +{ + if (__builtin_isunordered (x, y) || !__builtin_isunordered (x, y)) + { + } + else + link_error1 (); +} + +void +all_tests (float x, float y) +{ + test1 (x, y); + test2 (x, y); + test3 (x, y); + test4 (x, y); + test5 (x, y); + test6 (x, y); + test7 (x, y); +} + +int +main () +{ + all_tests (0, 0); + all_tests (1, 2); + all_tests (4, 3); + + return 0; +} + +#ifndef __OPTIMIZE__ +void link_error0() {} +void link_error1() {} +#endif /* ! __OPTIMIZE__ */ + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.x b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.x new file mode 100644 index 000000000..35f7a0a7d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.x @@ -0,0 +1,2 @@ +lappend additional_flags "-fno-trapping-math" +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.c b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.c new file mode 100644 index 000000000..40fc9c0c3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.c @@ -0,0 +1,190 @@ +/* Copyright (C) 2004 Free Software Foundation. + + Test for correctness of composite floating-point comparisons. + + Written by Paolo Bonzini, 26th May 2004. */ + +extern void abort (void); + +#define TEST(c) if ((c) != ok) abort (); +#define ORD(a, b) (((a) < (b)) || (a) >= (b)) +#define UNORD(a, b) (!ORD ((a), (b))) +#define UNEQ(a, b) (!LTGT ((a), (b))) +#define UNLT(a, b) (((a) < (b)) || __builtin_isunordered ((a), (b))) +#define UNLE(a, b) (((a) <= (b)) || __builtin_isunordered ((a), (b))) +#define UNGT(a, b) (((a) > (b)) || __builtin_isunordered ((a), (b))) +#define UNGE(a, b) (((a) >= (b)) || __builtin_isunordered ((a), (b))) +#define LTGT(a, b) (((a) < (b)) || (a) > (b)) + +float pinf; +float ninf; +float NaN; + +int iuneq (float x, float y, int ok) +{ + TEST (UNEQ (x, y)); + TEST (!LTGT (x, y)); + TEST (UNLE (x, y) && UNGE (x,y)); +} + +int ieq (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNEQ (x, y)); +} + +int iltgt (float x, float y, int ok) +{ + TEST (!UNEQ (x, y)); + TEST (LTGT (x, y)); + TEST (ORD (x, y) && (UNLT (x, y) || UNGT (x,y))); +} + +int ine (float x, float y, int ok) +{ + TEST (UNLT (x, y) || UNGT (x, y)); + TEST ((x < y) || (x > y) || UNORD (x, y)); +} + +int iunlt (float x, float y, int ok) +{ + TEST (UNLT (x, y)); + TEST (UNORD (x, y) || (x < y)); +} + +int ilt (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNLT (x, y)); + TEST ((x <= y) && (x != y)); + TEST ((x <= y) && (y != x)); + TEST ((x != y) && (x <= y)); + TEST ((y != x) && (x <= y)); +} + +int iunle (float x, float y, int ok) +{ + TEST (UNLE (x, y)); + TEST (UNORD (x, y) || (x <= y)); +} + +int ile (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNLE (x, y)); + TEST ((x < y) || (x == y)); + TEST ((y > x) || (x == y)); + TEST ((x == y) || (x < y)); + TEST ((y == x) || (x < y)); +} + +int iungt (float x, float y, int ok) +{ + TEST (UNGT (x, y)); + TEST (UNORD (x, y) || (x > y)); +} + +int igt (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNGT (x, y)); + TEST ((x >= y) && (x != y)); + TEST ((x >= y) && (y != x)); + TEST ((x != y) && (x >= y)); + TEST ((y != x) && (x >= y)); +} + +int iunge (float x, float y, int ok) +{ + TEST (UNGE (x, y)); + TEST (UNORD (x, y) || (x >= y)); +} + +int ige (float x, float y, int ok) +{ + TEST (ORD (x, y) && UNGE (x, y)); + TEST ((x > y) || (x == y)); + TEST ((y < x) || (x == y)); + TEST ((x == y) || (x > y)); + TEST ((y == x) || (x > y)); +} + +int +main () +{ + pinf = __builtin_inf (); + ninf = -__builtin_inf (); + NaN = __builtin_nan (""); + + iuneq (ninf, pinf, 0); + iuneq (NaN, NaN, 1); + iuneq (pinf, ninf, 0); + iuneq (1, 4, 0); + iuneq (3, 3, 1); + iuneq (5, 2, 0); + + ieq (1, 4, 0); + ieq (3, 3, 1); + ieq (5, 2, 0); + + iltgt (ninf, pinf, 1); + iltgt (NaN, NaN, 0); + iltgt (pinf, ninf, 1); + iltgt (1, 4, 1); + iltgt (3, 3, 0); + iltgt (5, 2, 1); + + ine (1, 4, 1); + ine (3, 3, 0); + ine (5, 2, 1); + + iunlt (NaN, ninf, 1); + iunlt (pinf, NaN, 1); + iunlt (pinf, ninf, 0); + iunlt (pinf, pinf, 0); + iunlt (ninf, ninf, 0); + iunlt (1, 4, 1); + iunlt (3, 3, 0); + iunlt (5, 2, 0); + + ilt (1, 4, 1); + ilt (3, 3, 0); + ilt (5, 2, 0); + + iunle (NaN, ninf, 1); + iunle (pinf, NaN, 1); + iunle (pinf, ninf, 0); + iunle (pinf, pinf, 1); + iunle (ninf, ninf, 1); + iunle (1, 4, 1); + iunle (3, 3, 1); + iunle (5, 2, 0); + + ile (1, 4, 1); + ile (3, 3, 1); + ile (5, 2, 0); + + iungt (NaN, ninf, 1); + iungt (pinf, NaN, 1); + iungt (pinf, ninf, 1); + iungt (pinf, pinf, 0); + iungt (ninf, ninf, 0); + iungt (1, 4, 0); + iungt (3, 3, 0); + iungt (5, 2, 1); + + igt (1, 4, 0); + igt (3, 3, 0); + igt (5, 2, 1); + + iunge (NaN, ninf, 1); + iunge (pinf, NaN, 1); + iunge (ninf, pinf, 0); + iunge (pinf, pinf, 1); + iunge (ninf, ninf, 1); + iunge (1, 4, 0); + iunge (3, 3, 1); + iunge (5, 2, 1); + + ige (1, 4, 0); + ige (3, 3, 1); + ige (5, 2, 1); + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x new file mode 100644 index 000000000..d7ecd1100 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x @@ -0,0 +1,23 @@ +# The ARM VxWorks kernel uses an external floating-point library in +# which routines like __ledf2 are just aliases for __cmpdf2. These +# routines therefore don't handle NaNs correctly. +if [istarget "arm*-*-vxworks*"] { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "The ARM kernel uses a flawed floating-point library." + { "*-*-*" } + {} + { "-mrtp" } + } + } +} + +if [istarget "spu-*-*"] { + # The SPU single-precision floating point format does not + # support Nan & Inf. + return 1 +} + +lappend additional_flags "-fno-trapping-math" +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c new file mode 100644 index 000000000..fa4097a74 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c @@ -0,0 +1,76 @@ +#include <string.h> +#include <stdlib.h> +#include <float.h> + +#define fpsizeoff sizeof(float) +#define fpsizeof sizeof(double) +#define fpsizeofl sizeof(long double) + +/* Work around the fact that with the Intel double-extended precision, + we've got a 10 byte type stuffed into some amount of padding. And + the fact that -ffloat-store is going to stuff this value temporarily + into some bit of stack frame that we've no control over and can't zero. */ +#if LDBL_MANT_DIG == 64 +# if defined(__i386__) || defined(__x86_64__) || defined (__ia64__) +# undef fpsizeofl +# define fpsizeofl 10 +# endif +#endif + +/* Work around the fact that the sign of the second double in the IBM + double-double format is not strictly specified when it contains a zero. + For instance, -0.0L can be represented with either (-0.0, +0.0) or + (-0.0, -0.0). The former is what we'll get from the compiler when it + builds constants; the later is what we'll get from the negation operator + at runtime. */ +/* ??? This hack only works for big-endian, which is fortunately true for + all of AIX, Darwin, and Irix. */ +#if LDBL_MANT_DIG == 106 +# undef fpsizeofl +# define fpsizeofl sizeof(double) +#endif + + +#define TEST(TYPE, EXT) \ +TYPE c##EXT (TYPE x, TYPE y) \ +{ \ + return __builtin_copysign##EXT (x, y); \ +} \ + \ +struct D##EXT { TYPE x, y, z; }; \ + \ +static const struct D##EXT T##EXT[] = { \ + { 1.0, 2.0, 1.0 }, \ + { 1.0, -2.0, -1.0 }, \ + { -1.0, -2.0, -1.0 }, \ + { 0.0, -2.0, -0.0 }, \ + { -0.0, -2.0, -0.0 }, \ + { -0.0, 2.0, 0.0 }, \ + { __builtin_inf##EXT (), -0.0, -__builtin_inf##EXT () }, \ + { -__builtin_nan##EXT (""), __builtin_inf##EXT (), \ + __builtin_nan##EXT ("") } \ +}; \ + \ +void test##EXT (void) \ +{ \ + int i, n = sizeof (T##EXT) / sizeof (T##EXT[0]); \ + TYPE r; \ + for (i = 0; i < n; ++i) \ + { \ + r = c##EXT (T##EXT[i].x, T##EXT[i].y); \ + if (memcmp (&r, &T##EXT[i].z, fpsizeof##EXT) != 0) \ + abort (); \ + } \ +} + +TEST(float, f) +TEST(double, ) +TEST(long double, l) + +int main() +{ + testf(); + test(); + testl(); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c new file mode 100644 index 000000000..fac7ab3a5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c @@ -0,0 +1,70 @@ +#include <string.h> +#include <stdlib.h> +#include <float.h> + +#define fpsizeoff sizeof(float) +#define fpsizeof sizeof(double) +#define fpsizeofl sizeof(long double) + +/* Work around the fact that with the Intel double-extended precision, + we've got a 10 byte type stuffed into some amount of padding. And + the fact that -ffloat-store is going to stuff this value temporarily + into some bit of stack frame that we've no control over and can't zero. */ +#if LDBL_MANT_DIG == 64 +# if defined(__i386__) || defined(__x86_64__) || defined (__ia64__) +# undef fpsizeofl +# define fpsizeofl 10 +# endif +#endif + +/* Work around the fact that the sign of the second double in the IBM + double-double format is not strictly specified when it contains a zero. + For instance, -0.0L can be represented with either (-0.0, +0.0) or + (-0.0, -0.0). The former is what we'll get from the compiler when it + builds constants; the later is what we'll get from the negation operator + at runtime. */ +/* ??? This hack only works for big-endian, which is fortunately true for + all of AIX, Darwin, and Irix. */ +#if LDBL_MANT_DIG == 106 +# undef fpsizeofl +# define fpsizeofl sizeof(double) +#endif + + +#define TEST(TYPE, EXT) \ +static TYPE Y##EXT[] = { \ + 2.0, -2.0, -2.0, -2.0, -2.0, 2.0, -0.0, __builtin_inf##EXT () \ +}; \ +static const TYPE Z##EXT[] = { \ + 1.0, -1.0, -1.0, -0.0, -0.0, 0.0, -__builtin_inf##EXT (), \ + __builtin_nan##EXT ("") \ +}; \ + \ +void test##EXT (void) \ +{ \ + TYPE r[8]; \ + int i; \ + r[0] = __builtin_copysign##EXT (1.0, Y##EXT[0]); \ + r[1] = __builtin_copysign##EXT (1.0, Y##EXT[1]); \ + r[2] = __builtin_copysign##EXT (-1.0, Y##EXT[2]); \ + r[3] = __builtin_copysign##EXT (0.0, Y##EXT[3]); \ + r[4] = __builtin_copysign##EXT (-0.0, Y##EXT[4]); \ + r[5] = __builtin_copysign##EXT (-0.0, Y##EXT[5]); \ + r[6] = __builtin_copysign##EXT (__builtin_inf##EXT (), Y##EXT[6]); \ + r[7] = __builtin_copysign##EXT (-__builtin_nan##EXT (""), Y##EXT[7]); \ + for (i = 0; i < 8; ++i) \ + if (memcmp (r+i, Z##EXT+i, fpsizeof##EXT) != 0) \ + abort (); \ +} + +TEST(float, f) +TEST(double, ) +TEST(long double, l) + +int main() +{ + testf(); + test(); + testl(); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.c new file mode 100644 index 000000000..0655c73a1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.c @@ -0,0 +1,43 @@ +#ifndef SIGNAL_SUPPRESS +#include <signal.h> +#endif + +double dnan = 1.0/0.0 - 1.0/0.0; +double x = 1.0; + +void leave () +{ + exit (0); +} + +main () +{ +#if ! defined (__vax__) && ! defined (_CRAY) + /* Move this line earlier, for architectures (like alpha) that issue + SIGFPE on the first comparisons. */ +#ifndef SIGNAL_SUPPRESS + /* Some machines catches a SIGFPE when a NaN is compared. + Let this test succeed o such machines. */ + signal (SIGFPE, leave); +#endif + /* NaN is an IEEE unordered operand. All these test should be false. */ + if (dnan == dnan) + abort (); + if (dnan != x) + x = 1.0; + else + abort (); + + if (dnan < x) + abort (); + if (dnan > x) + abort (); + if (dnan <= x) + abort (); + if (dnan >= x) + abort (); + if (dnan == x) + abort (); +#endif + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.x new file mode 100644 index 000000000..84c193fe0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.x @@ -0,0 +1,16 @@ +# The ARM VxWorks kernel uses an external floating-point library in +# which routines like __ledf2 are just aliases for __cmpdf2. These +# routines therefore don't handle NaNs correctly. +if [istarget "arm*-*-vxworks*"] { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "The ARM kernel uses a flawed floating-point library." + { "*-*-*" } + {} + { "-mrtp" } + } + } +} + +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.c new file mode 100644 index 000000000..0f4c6f145 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.c @@ -0,0 +1,43 @@ +#ifndef SIGNAL_SUPPRESS +#include <signal.h> +#endif + +float fnan = 1.0f/0.0f - 1.0f/0.0f; +float x = 1.0f; + +void leave () +{ + exit (0); +} + +main () +{ +#if ! defined (__vax__) && ! defined (_CRAY) + /* Move this line earlier, for architectures (like alpha) that issue + SIGFPE on the first comparisons. */ +#ifndef SIGNAL_SUPPRESS + /* Some machines catches a SIGFPE when a NaN is compared. + Let this test succeed o such machines. */ + signal (SIGFPE, leave); +#endif + /* NaN is an IEEE unordered operand. All these test should be false. */ + if (fnan == fnan) + abort (); + if (fnan != x) + x = 1.0; + else + abort (); + + if (fnan < x) + abort (); + if (fnan > x) + abort (); + if (fnan <= x) + abort (); + if (fnan >= x) + abort (); + if (fnan == x) + abort (); +#endif + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x new file mode 100644 index 000000000..0fe5a98d3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x @@ -0,0 +1,22 @@ +# The ARM VxWorks kernel uses an external floating-point library in +# which routines like __ledf2 are just aliases for __cmpdf2. These +# routines therefore don't handle NaNs correctly. +if [istarget "arm*-*-vxworks*"] { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "The ARM kernel uses a flawed floating-point library." + { "*-*-*" } + {} + { "-mrtp" } + } + } +} + +if [istarget "spu-*-*"] { + # The SPU single-precision floating point format does not + # support Nan & Inf. + return 1 +} + +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.c new file mode 100644 index 000000000..710b85ccb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.c @@ -0,0 +1,43 @@ +#ifndef SIGNAL_SUPPRESS +#include <signal.h> +#endif + +long double dnan = 1.0l/0.0l - 1.0l/0.0l; +long double x = 1.0l; + +void leave () +{ + exit (0); +} + +main () +{ +#if ! defined (__vax__) && ! defined (_CRAY) + /* Move this line earlier, for architectures (like alpha) that issue + SIGFPE on the first comparisons. */ +#ifndef SIGNAL_SUPPRESS + /* Some machines catches a SIGFPE when a NaN is compared. + Let this test succeed o such machines. */ + signal (SIGFPE, leave); +#endif + /* NaN is an IEEE unordered operand. All these test should be false. */ + if (dnan == dnan) + abort (); + if (dnan != x) + x = 1.0; + else + abort (); + + if (dnan < x) + abort (); + if (dnan > x) + abort (); + if (dnan <= x) + abort (); + if (dnan >= x) + abort (); + if (dnan == x) + abort (); +#endif + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.x new file mode 100644 index 000000000..84c193fe0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.x @@ -0,0 +1,16 @@ +# The ARM VxWorks kernel uses an external floating-point library in +# which routines like __ledf2 are just aliases for __cmpdf2. These +# routines therefore don't handle NaNs correctly. +if [istarget "arm*-*-vxworks*"] { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "The ARM kernel uses a flawed floating-point library." + { "*-*-*" } + {} + { "-mrtp" } + } + } +} + +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4.c new file mode 100644 index 000000000..d4bb9c6c6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4.c @@ -0,0 +1,135 @@ +#ifndef FLOAT +#define FLOAT double +#endif + +void +test_isunordered(FLOAT x, FLOAT y, int true) +{ + if (__builtin_isunordered(x, y)) + { + if (! true) + abort (); + } + else + { + if (true) + abort (); + } +} + +void +test_isless(FLOAT x, FLOAT y, int true) +{ + if (__builtin_isless(x, y)) + { + if (! true) + abort (); + } + else + { + if (true) + abort (); + } +} + +void +test_islessequal(FLOAT x, FLOAT y, int true) +{ + if (__builtin_islessequal(x, y)) + { + if (! true) + abort (); + } + else + { + if (true) + abort (); + } +} + +void +test_isgreater(FLOAT x, FLOAT y, int true) +{ + if (__builtin_isgreater(x, y)) + { + if (! true) + abort (); + } + else + { + if (true) + abort (); + } +} + +void +test_isgreaterequal(FLOAT x, FLOAT y, int true) +{ + if (__builtin_isgreaterequal(x, y)) + { + if (! true) + abort (); + } + else + { + if (true) + abort (); + } +} + +void +test_islessgreater(FLOAT x, FLOAT y, int true) +{ + if (__builtin_islessgreater(x, y)) + { + if (! true) + abort (); + } + else + { + if (true) + abort (); + } +} + +#define NAN (0.0 / 0.0) + +int +main() +{ + struct try + { + FLOAT x, y; + unsigned unord : 1; + unsigned lt : 1; + unsigned le : 1; + unsigned gt : 1; + unsigned ge : 1; + unsigned lg : 1; + }; + + static struct try const data[] = + { + { NAN, NAN, 1, 0, 0, 0, 0, 0 }, + { 0.0, NAN, 1, 0, 0, 0, 0, 0 }, + { NAN, 0.0, 1, 0, 0, 0, 0, 0 }, + { 0.0, 0.0, 0, 0, 1, 0, 1, 0 }, + { 1.0, 2.0, 0, 1, 1, 0, 0, 1 }, + { 2.0, 1.0, 0, 0, 0, 1, 1, 1 }, + }; + + const int n = sizeof(data) / sizeof(data[0]); + int i; + + for (i = 0; i < n; ++i) + { + test_isunordered (data[i].x, data[i].y, data[i].unord); + test_isless (data[i].x, data[i].y, data[i].lt); + test_islessequal (data[i].x, data[i].y, data[i].le); + test_isgreater (data[i].x, data[i].y, data[i].gt); + test_isgreaterequal (data[i].x, data[i].y, data[i].ge); + test_islessgreater (data[i].x, data[i].y, data[i].lg); + } + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4e.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4e.c new file mode 100644 index 000000000..c8cacb27a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4e.c @@ -0,0 +1,10 @@ +#if defined (__ia64__) && defined (__hpux__) +#define FLOAT __float80 +#include "fp-cmp-4.c" +#else +int +main () +{ + return 0; +} +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.c new file mode 100644 index 000000000..6221b250d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.c @@ -0,0 +1,2 @@ +#define FLOAT float +#include "fp-cmp-4.c" diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x new file mode 100644 index 000000000..2f7a4ecc5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x @@ -0,0 +1,6 @@ +if [istarget "spu-*-*"] { + # The SPU single-precision floating point format does not + # support Nan & Inf. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4l.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4l.c new file mode 100644 index 000000000..5ac8b7565 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4l.c @@ -0,0 +1,2 @@ +#define FLOAT long double +#include "fp-cmp-4.c" diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-5.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-5.c new file mode 100644 index 000000000..9c70072f4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-5.c @@ -0,0 +1,131 @@ +/* Like fp-cmp-4.c, but test that the setcc patterns are correct. */ + +static int +test_isunordered(double x, double y) +{ + return __builtin_isunordered(x, y); +} + +static int +test_not_isunordered(double x, double y) +{ + return !__builtin_isunordered(x, y); +} + +static int +test_isless(double x, double y) +{ + return __builtin_isless(x, y); +} + +static int +test_not_isless(double x, double y) +{ + return !__builtin_isless(x, y); +} + +static int +test_islessequal(double x, double y) +{ + return __builtin_islessequal(x, y); +} + +static int +test_not_islessequal(double x, double y) +{ + return !__builtin_islessequal(x, y); +} + +static int +test_isgreater(double x, double y) +{ + return __builtin_isgreater(x, y); +} + +static int +test_not_isgreater(double x, double y) +{ + return !__builtin_isgreater(x, y); +} + +static int +test_isgreaterequal(double x, double y) +{ + return __builtin_isgreaterequal(x, y); +} + +static int +test_not_isgreaterequal(double x, double y) +{ + return !__builtin_isgreaterequal(x, y); +} + +static int +test_islessgreater(double x, double y) +{ + return __builtin_islessgreater(x, y); +} + +static int +test_not_islessgreater(double x, double y) +{ + return !__builtin_islessgreater(x, y); +} + +static void +one_test(double x, double y, int expected, + int (*pos) (double, double), int (*neg) (double, double)) +{ + if ((*pos)(x, y) != expected) + abort (); + if ((*neg)(x, y) != !expected) + abort (); +} + +#define NAN (0.0 / 0.0) + +int +main() +{ + struct try + { + double x, y; + int result[6]; + }; + + static struct try const data[] = + { + { NAN, NAN, { 1, 0, 0, 0, 0, 0 } }, + { 0.0, NAN, { 1, 0, 0, 0, 0, 0 } }, + { NAN, 0.0, { 1, 0, 0, 0, 0, 0 } }, + { 0.0, 0.0, { 0, 0, 1, 0, 1, 0 } }, + { 1.0, 2.0, { 0, 1, 1, 0, 0, 1 } }, + { 2.0, 1.0, { 0, 0, 0, 1, 1, 1 } }, + }; + + struct test + { + int (*pos)(double, double); + int (*neg)(double, double); + }; + + static struct test const tests[] = + { + { test_isunordered, test_not_isunordered }, + { test_isless, test_not_isless }, + { test_islessequal, test_not_islessequal }, + { test_isgreater, test_not_isgreater }, + { test_isgreaterequal, test_not_isgreaterequal }, + { test_islessgreater, test_not_islessgreater } + }; + + const int n = sizeof(data) / sizeof(data[0]); + int i, j; + + for (i = 0; i < n; ++i) + for (j = 0; j < 6; ++j) + one_test (data[i].x, data[i].y, data[i].result[j], + tests[j].pos, tests[j].neg); + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.c new file mode 100644 index 000000000..782455831 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.c @@ -0,0 +1,39 @@ + +const double dnan = 1.0/0.0 - 1.0/0.0; +double x = 1.0; + +extern void link_error (void); +extern void abort (void); + +main () +{ +#if ! defined (__vax__) && ! defined (_CRAY) + /* NaN is an IEEE unordered operand. All these test should be false. */ + if (dnan == dnan) + link_error (); + if (dnan != x) + x = 1.0; + else + link_error (); + + if (dnan < x) + link_error (); + if (dnan > x) + link_error (); + if (dnan <= x) + link_error (); + if (dnan >= x) + link_error (); + if (dnan == x) + link_error (); +#endif + exit (0); +} + +#ifndef __OPTIMIZE__ +void link_error (void) +{ + abort (); +} +#endif + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x new file mode 100644 index 000000000..e7c051d8f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x @@ -0,0 +1,16 @@ +# The ARM VxWorks kernel uses an external floating-point library in +# which routines like __ledf2 are just aliases for __cmpdf2. These +# routines therefore don't handle NaNs correctly. +if [istarget "arm*-*-vxworks*"] { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "The ARM kernel uses a flawed floating-point library." + { "*-*-*" } + { "-O0" } + { "-mrtp" } + } + } +} + +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.c new file mode 100644 index 000000000..385acafc2 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.c @@ -0,0 +1,14 @@ +extern void link_error (); + +void foo(double x) +{ + if (x > __builtin_inf()) + link_error (); +} + +int main () +{ + foo (1.0); + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8.c new file mode 100644 index 000000000..7e24c66d9 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8.c @@ -0,0 +1,145 @@ +#ifndef FLOAT +#define FLOAT double +#endif + +/* Like fp-cmp-4.c, but test that the cmove patterns are correct. */ + +static FLOAT +test_isunordered(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return __builtin_isunordered(x, y) ? a : b; +} + +static FLOAT +test_not_isunordered(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return !__builtin_isunordered(x, y) ? a : b; +} + +static FLOAT +test_isless(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return __builtin_isless(x, y) ? a : b; +} + +static FLOAT +test_not_isless(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return !__builtin_isless(x, y) ? a : b; +} + +static FLOAT +test_islessequal(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return __builtin_islessequal(x, y) ? a : b; +} + +static FLOAT +test_not_islessequal(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return !__builtin_islessequal(x, y) ? a : b; +} + +static FLOAT +test_isgreater(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return __builtin_isgreater(x, y) ? a : b; +} + +static FLOAT +test_not_isgreater(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return !__builtin_isgreater(x, y) ? a : b; +} + +static FLOAT +test_isgreaterequal(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return __builtin_isgreaterequal(x, y) ? a : b; +} + +static FLOAT +test_not_isgreaterequal(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return !__builtin_isgreaterequal(x, y) ? a : b; +} + +static FLOAT +test_islessgreater(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return __builtin_islessgreater(x, y) ? a : b; +} + +static FLOAT +test_not_islessgreater(FLOAT x, FLOAT y, FLOAT a, FLOAT b) +{ + return !__builtin_islessgreater(x, y) ? a : b; +} + +static void +one_test(FLOAT x, FLOAT y, int expected, + FLOAT (*pos) (FLOAT, FLOAT, FLOAT, FLOAT), + FLOAT (*neg) (FLOAT, FLOAT, FLOAT, FLOAT)) +{ + if (((*pos)(x, y, 1.0, 2.0) == 1.0) != expected) + abort (); + if (((*neg)(x, y, 3.0, 4.0) == 4.0) != expected) + abort (); +} + +#define NAN (0.0 / 0.0) +#define INF (1.0 / 0.0) + +int +main() +{ + struct try + { + FLOAT x, y; + int result[6]; + }; + + static struct try const data[] = + { + { NAN, NAN, { 1, 0, 0, 0, 0, 0 } }, + { 0.0, NAN, { 1, 0, 0, 0, 0, 0 } }, + { NAN, 0.0, { 1, 0, 0, 0, 0, 0 } }, + { 0.0, 0.0, { 0, 0, 1, 0, 1, 0 } }, + { 1.0, 2.0, { 0, 1, 1, 0, 0, 1 } }, + { 2.0, 1.0, { 0, 0, 0, 1, 1, 1 } }, + { INF, 0.0, { 0, 0, 0, 1, 1, 1 } }, + { 1.0, INF, { 0, 1, 1, 0, 0, 1 } }, + { INF, INF, { 0, 0, 1, 0, 1, 0 } }, + { 0.0, -INF, { 0, 0, 0, 1, 1, 1 } }, + { -INF, 1.0, { 0, 1, 1, 0, 0, 1 } }, + { -INF, -INF, { 0, 0, 1, 0, 1, 0 } }, + { INF, -INF, { 0, 0, 0, 1, 1, 1 } }, + { -INF, INF, { 0, 1, 1, 0, 0, 1 } }, + }; + + struct test + { + FLOAT (*pos)(FLOAT, FLOAT, FLOAT, FLOAT); + FLOAT (*neg)(FLOAT, FLOAT, FLOAT, FLOAT); + }; + + static struct test const tests[] = + { + { test_isunordered, test_not_isunordered }, + { test_isless, test_not_isless }, + { test_islessequal, test_not_islessequal }, + { test_isgreater, test_not_isgreater }, + { test_isgreaterequal, test_not_isgreaterequal }, + { test_islessgreater, test_not_islessgreater } + }; + + const int n = sizeof(data) / sizeof(data[0]); + int i, j; + + for (i = 0; i < n; ++i) + for (j = 0; j < 6; ++j) + one_test (data[i].x, data[i].y, data[i].result[j], + tests[j].pos, tests[j].neg); + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8e.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8e.c new file mode 100644 index 000000000..acb83f67f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8e.c @@ -0,0 +1,10 @@ +#if defined (__ia64__) && defined (__hpux__) +#define FLOAT __float80 +#include "fp-cmp-8.c" +#else +int +main () +{ + return 0; +} +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.c new file mode 100644 index 000000000..9826ec916 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.c @@ -0,0 +1,2 @@ +#define FLOAT float +#include "fp-cmp-8.c" diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x new file mode 100644 index 000000000..2f7a4ecc5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x @@ -0,0 +1,6 @@ +if [istarget "spu-*-*"] { + # The SPU single-precision floating point format does not + # support Nan & Inf. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8l.c b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8l.c new file mode 100644 index 000000000..528eeb0ab --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8l.c @@ -0,0 +1,2 @@ +#define FLOAT long double +#include "fp-cmp-8.c" diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.c b/gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.c new file mode 100644 index 000000000..15f7088e1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.c @@ -0,0 +1,27 @@ +#include <math.h> + +static const double zero = 0.0; +static const double pone = 1.0; +static const double none = -1.0; +static const double pinf = 1.0 / 0.0; +static const double ninf = -1.0 / 0.0; + +int +main () +{ + if (pinf != pone/zero) + abort (); + + if (ninf != none/zero) + abort (); + +#ifdef HUGE_VAL + if (HUGE_VAL != pinf) + abort (); + + if (-HUGE_VAL != ninf) + abort (); +#endif + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.x b/gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.x new file mode 100644 index 000000000..ee4ac4feb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.x @@ -0,0 +1,23 @@ +# This test fails under hpux 9.X and 10.X because HUGE_VAL is DBL_MAX +# instead of +Infinity. + +global target_triplet +if { [istarget "hppa*-*-hpux9*"] || [istarget "hppa*-*-hpux10*"] } { + set torture_execute_xfail "$target_triplet" +} + +# VxWorks kernel mode has the same problem. +if {[istarget "*-*-vxworks*"]} { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "The kernel HUGE_VAL is defined to DBL_MAX instead of +Inf." + { "*-*-*" } + {} + { "-mrtp" } + } + } +} + +return 0 + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp new file mode 100644 index 000000000..25009e47c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp @@ -0,0 +1,79 @@ +# +# Expect driver script for GCC Regression Tests +# Copyright (C) 1993, 1996, 2001, 2005, 2007, 2008, 2010 Free Software Foundation +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. +# +# Written by Jeffrey Wheat (cassidy@cygnus.com) +# + +# Load support procs. +load_lib gcc-dg.exp +load_lib torture-options.exp +load_lib c-torture.exp + +# These tests come from Torbjorn Granlund's (tege@cygnus.com) +# C torture test suite, and other contributors. + +# Disable tests on machines with no hardware support for IEEE arithmetic. +if { [istarget "vax-*-*"] || [ istarget "powerpc-*-*spe"] || [istarget "pdp11-*-*"] } { return } + +if $tracelevel then { + strace $tracelevel +} + +torture-init +set-torture-options $C_TORTURE_OPTIONS {{}} $LTO_TORTURE_OPTIONS + +set additional_flags "-fno-inline" + +# We must use -ffloat-store/-mieee to ensure that excess precision on some +# machines does not cause problems +if [istarget "i\[34567\]86-*-*"] then { + lappend additional_flags "-ffloat-store" +} +if { [istarget "x86_64-*-*"] && [check_effective_target_ilp32] } then { + lappend additional_flags "-ffloat-store" +} +if [istarget "m68k-*-*"] then { + lappend additional_flags "-ffloat-store" +} +if { [istarget "alpha*-*-*"] + || [istarget "sh*-*-*"] } then { + lappend additional_flags "-mieee" +} + +# load support procs +load_lib c-torture.exp + +# initialize harness +gcc_init + +# +# main test loop +# + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $src] then { + continue + } + + c-torture-execute $src $additional_flags +} + +# All done. +torture-finish +gcc_finish diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c new file mode 100644 index 000000000..eee8c0130 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c @@ -0,0 +1,44 @@ +extern void abort (void); + +int main() +{ +#ifndef __SPU__ + /* The SPU single-precision floating point format does not support Inf. */ + float fi = __builtin_inff(); +#endif + double di = __builtin_inf(); + long double li = __builtin_infl(); + + float fh = __builtin_huge_valf(); + double dh = __builtin_huge_val(); + long double lh = __builtin_huge_vall(); + +#ifndef __SPU__ + if (fi + fi != fi) + abort (); +#endif + if (di + di != di) + abort (); + if (li + li != li) + abort (); + +#ifndef __SPU__ + if (fi != fh) + abort (); +#endif + if (di != dh) + abort (); + if (li != lh) + abort (); + +#ifndef __SPU__ + if (fi <= 0) + abort (); +#endif + if (di <= 0) + abort (); + if (li <= 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c new file mode 100644 index 000000000..dafd95835 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c @@ -0,0 +1,83 @@ +extern void abort (void); + +void test(double f, double i) +{ + if (f == __builtin_inf()) + abort (); + if (f == -__builtin_inf()) + abort (); + if (i == -__builtin_inf()) + abort (); + if (i != __builtin_inf()) + abort (); + + if (f >= __builtin_inf()) + abort (); + if (f > __builtin_inf()) + abort (); + if (i > __builtin_inf()) + abort (); + if (f <= -__builtin_inf()) + abort (); + if (f < -__builtin_inf()) + abort (); +} + +void testf(float f, float i) +{ +#ifndef __SPU__ + /* The SPU single-precision floating point format does not support Inf. */ + + if (f == __builtin_inff()) + abort (); + if (f == -__builtin_inff()) + abort (); + if (i == -__builtin_inff()) + abort (); + if (i != __builtin_inff()) + abort (); + + if (f >= __builtin_inff()) + abort (); + if (f > __builtin_inff()) + abort (); + if (i > __builtin_inff()) + abort (); + if (f <= -__builtin_inff()) + abort (); + if (f < -__builtin_inff()) + abort (); +#endif +} + +void testl(long double f, long double i) +{ + if (f == __builtin_infl()) + abort (); + if (f == -__builtin_infl()) + abort (); + if (i == -__builtin_infl()) + abort (); + if (i != __builtin_infl()) + abort (); + + if (f >= __builtin_infl()) + abort (); + if (f > __builtin_infl()) + abort (); + if (i > __builtin_infl()) + abort (); + if (f <= -__builtin_infl()) + abort (); + if (f < -__builtin_infl()) + abort (); +} + +int main() +{ + test (34.0, __builtin_inf()); + testf (34.0f, __builtin_inff()); + testl (34.0l, __builtin_infl()); + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/inf-3.c b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-3.c new file mode 100644 index 000000000..f2ee48062 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/inf-3.c @@ -0,0 +1,79 @@ +extern void abort (void); + +void test(double f, double i) +{ + if (f == __builtin_huge_val()) + abort (); + if (f == -__builtin_huge_val()) + abort (); + if (i == -__builtin_huge_val()) + abort (); + if (i != __builtin_huge_val()) + abort (); + + if (f >= __builtin_huge_val()) + abort (); + if (f > __builtin_huge_val()) + abort (); + if (i > __builtin_huge_val()) + abort (); + if (f <= -__builtin_huge_val()) + abort (); + if (f < -__builtin_huge_val()) + abort (); +} + +void testf(float f, float i) +{ + if (f == __builtin_huge_valf()) + abort (); + if (f == -__builtin_huge_valf()) + abort (); + if (i == -__builtin_huge_valf()) + abort (); + if (i != __builtin_huge_valf()) + abort (); + + if (f >= __builtin_huge_valf()) + abort (); + if (f > __builtin_huge_valf()) + abort (); + if (i > __builtin_huge_valf()) + abort (); + if (f <= -__builtin_huge_valf()) + abort (); + if (f < -__builtin_huge_valf()) + abort (); +} + +void testl(long double f, long double i) +{ + if (f == __builtin_huge_vall()) + abort (); + if (f == -__builtin_huge_vall()) + abort (); + if (i == -__builtin_huge_vall()) + abort (); + if (i != __builtin_huge_vall()) + abort (); + + if (f >= __builtin_huge_vall()) + abort (); + if (f > __builtin_huge_vall()) + abort (); + if (i > __builtin_huge_vall()) + abort (); + if (f <= -__builtin_huge_vall()) + abort (); + if (f < -__builtin_huge_vall()) + abort (); +} + +int main() +{ + test (34.0, __builtin_huge_val()); + testf (34.0f, __builtin_huge_valf()); + testl (34.0l, __builtin_huge_vall()); + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/minuszero.c b/gcc/testsuite/gcc.c-torture/execute/ieee/minuszero.c new file mode 100644 index 000000000..85715261d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/minuszero.c @@ -0,0 +1,22 @@ +main () +{ + union + { + double d; + unsigned short i[sizeof (double) / sizeof (short)]; + } u; + int a = 0; + int b = -5; + int j; + + u.d = (double) a / b; + + /* Look for the right pattern, but be sloppy since + we don't know the byte order. */ + for (j = 0; j < sizeof (double) / sizeof (short); j++) + { + if (u.i[j] == 0x8000) + exit (0); + } + abort (); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.c new file mode 100644 index 000000000..d5f3fb45b --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.c @@ -0,0 +1,75 @@ +/* Check that certain subnormal numbers (formerly known as denormalized + numbers) are rounded to within 0.5 ulp. PR other/14354. */ + +/* This test requires that float and unsigned int are the same size and + that the sign-bit of the float is at MSB of the unsigned int. */ + +#if __INT_MAX__ != 2147483647L +int main () { exit (0); } +#else + +union uf +{ + unsigned int u; + float f; +}; + +static float +u2f (unsigned int v) +{ + union uf u; + u.u = v; + return u.f; +} + +static unsigned int +f2u (float v) +{ + union uf u; + u.f = v; + return u.u; +} + +int ok = 1; + +static void +tstmul (unsigned int ux, unsigned int uy, unsigned int ur) +{ + float x = u2f (ux); + float y = u2f (uy); + + if (f2u (x * y) != ur) + /* Set a variable rather than aborting here, to simplify tracing when + several computations are wrong. */ + ok = 0; +} + +/* We don't want to make this const and static, or else we risk inlining + causing the test to fold as constants at compile-time. */ +struct +{ + unsigned int p1, p2, res; +} expected[] = + { + {0xfff, 0x3f800400, 0xfff}, + {0xf, 0x3fc88888, 0x17}, + {0xf, 0x3f844444, 0xf} + }; + +int +main (int argc, char *argv[], char *envp[]) +{ + unsigned int i; + + for (i = 0; i < sizeof (expected) / sizeof (expected[0]); i++) + { + tstmul (expected[i].p1, expected[i].p2, expected[i].res); + tstmul (expected[i].p2, expected[i].p1, expected[i].res); + } + + if (!ok) + abort (); + + exit (0); +} +#endif diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x new file mode 100644 index 000000000..5978c94a8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x @@ -0,0 +1,16 @@ +if [istarget "mips-sgi-irix6*"] { + # IRIX 6 sets the MIPS IV flush to zero bit by default, so this test + # isn't expected to work for n32 and n64 on MIPS IV targets. + return 1 +} +if {[istarget "m68k-*-*"] && [check_effective_target_coldfire_fpu]} { + # ColdFire FPUs require software handling of subnormals. We are + # not aware of any system that has this. + set torture_execute_xfail "m68k-*-*" +} +if [istarget "spu-*-*"] { + # The SPU single-precision floating point format does not + # support subnormals. + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.c new file mode 100644 index 000000000..0da53d247 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.c @@ -0,0 +1,58 @@ +/* Test IEEE +0/-0 rules */ + +static double pzero = +0.0; +static double nzero = -0.0; +static double pinf = +1.0 / 0.0; +static double ninf = -1.0 / 0.0; +static double nan = 0.0 / 0.0; + +void +expect (double value, double expected) +{ + if (expected != expected) /* expected value is Not a number */ + { + if (value == value) /* actual value is a number */ + abort (); + } + + else if (value != value) + abort (); /* actual value is a NaN */ + + else if (memcmp ((void *)&value, (void *)&expected, sizeof (double)) != 0) + abort (); /* values don't match */ +} + +main () +{ + expect (pzero + pzero, pzero); + expect (pzero + nzero, pzero); + expect (nzero + pzero, pzero); + expect (nzero + nzero, nzero); + + expect (pzero - pzero, pzero); + expect (pzero - nzero, pzero); + expect (nzero - pzero, nzero); + expect (nzero - nzero, pzero); + + expect (pzero * pzero, pzero); + expect (pzero * nzero, nzero); + expect (nzero * pzero, nzero); + expect (nzero * nzero, pzero); + + expect (+1.00 * pzero, pzero); + expect (-1.00 * pzero, nzero); + expect (+1.00 * nzero, nzero); + expect (-1.00 * nzero, pzero); + + expect (pzero / pzero, nan); + expect (pzero / nzero, nan); + expect (nzero / pzero, nan); + expect (nzero / nzero, nan); + + expect (+1.00 / pzero, pinf); + expect (-1.00 / pzero, ninf); + expect (+1.00 / nzero, ninf); + expect (-1.00 / nzero, pinf); + + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.x b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.x new file mode 100644 index 000000000..0b3ec4c00 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.x @@ -0,0 +1,6 @@ +# freebsd sets up the fpu with a different precision control which causes +# this test to "fail". +if { [istarget "i?86-*-freebsd*\[123\]\.*"] } { + set torture_execute_xfail "i?86-*-freebsd*" +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mzero3.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero3.c new file mode 100644 index 000000000..fdfb8a118 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero3.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2002 Free Software Foundation. + by Hans-Peter Nilsson <hp@bitrange.com>, derived from mzero2.c + + In the MMIX port, negdf2 was bogusly expanding -x into 0 - x. */ + +double nzerod = -0.0; +float nzerof = -0.0; +double zerod = 0.0; +float zerof = 0.0; + +void expectd (double, double); +void expectf (float, float); +double negd (double); +float negf (float); + +main () +{ + expectd (negd (zerod), nzerod); + expectf (negf (zerof), nzerof); + expectd (negd (nzerod), zerod); + expectf (negf (nzerof), zerof); + exit (0); +} + +void +expectd (double value, double expected) +{ + if (value != expected + || memcmp ((void *)&value, (void *) &expected, sizeof (double)) != 0) + abort (); +} + +void +expectf (float value, float expected) +{ + if (value != expected + || memcmp ((void *)&value, (void *) &expected, sizeof (float)) != 0) + abort (); +} + +double +negd (double v) +{ + return -v; +} + +float +negf (float v) +{ + return -v; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mzero4.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero4.c new file mode 100644 index 000000000..0ede7ec95 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero4.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2003 Free Software Foundation. + by Roger Sayle <roger@eyesopen.com>, derived from mzero3.c + + Constant folding of sin(-0.0), tan(-0.0) and atan(-0.0) should + all return -0.0, for both double and float forms. */ + +void abort (void); +typedef __SIZE_TYPE__ size_t; +extern int memcmp (const void *, const void *, size_t); + +double sin (double); +double tan (double); +double atan (double); + +float sinf (float); +float tanf (float); +float atanf (float); + +void expectd (double, double); +void expectf (float, float); + +void +expectd (double value, double expected) +{ + if (value != expected + || memcmp ((void *)&value, (void *) &expected, sizeof (double)) != 0) + abort (); +} + +void +expectf (float value, float expected) +{ + if (value != expected + || memcmp ((void *)&value, (void *) &expected, sizeof (float)) != 0) + abort (); +} + +int main () +{ + expectd (sin (0.0), 0.0); + expectd (tan (0.0), 0.0); + expectd (atan (0.0), 0.0); + + expectd (sin (-0.0), -0.0); + expectd (tan (-0.0), -0.0); + expectd (atan (-0.0), -0.0); + + expectf (sinf (0.0f), 0.0f); + expectf (tanf (0.0f), 0.0f); + expectf (atanf (0.0f), 0.0f); + + expectf (sinf (-0.0f), -0.0f); + expectf (tanf (-0.0f), -0.0f); + expectf (atanf (-0.0f), -0.0f); + + return 0; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mzero5.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero5.c new file mode 100644 index 000000000..3804c08a8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero5.c @@ -0,0 +1,29 @@ +/* Test gcse handling of IEEE 0/-0 rules. */ +static double zero = 0.0; + +int +negzero_check (double d) +{ + if (d == 0) + return !!memcmp ((void *)&zero, (void *)&d, sizeof (double)); + return 0; +} + +int +sub (double d, double e) +{ + if (d == 0.0 && e == 0.0 + && negzero_check (d) == 0 && negzero_check (e) == 0) + return 1; + else + return 0; +} + +int +main (void) +{ + double minus_zero = -0.0; + if (sub (minus_zero, 0)) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/mzero6.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero6.c new file mode 100644 index 000000000..59ba6fee1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero6.c @@ -0,0 +1,24 @@ +/* Tail call optimizations would convert func() into the moral equivalent of: + + double acc = 0.0; + for (int i = 0; i <= n; i++) + acc += d; + return acc; + + which mishandles the case where 'd' is -0. They also initialised 'acc' + to a zero int rather than a zero double. */ + +double func (double d, int n) +{ + if (n == 0) + return d; + else + return d + func (d, n - 1); +} + +int main () +{ + if (__builtin_copysign (1.0, func (0.0 / -5.0, 10)) != -1.0) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr28634.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr28634.c new file mode 100644 index 000000000..a0c525497 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr28634.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/28634. On targets with delayed branches, + dbr_schedule could do the next iteration's addition in the + branch delay slot, then subtract the value again if the branch + wasn't taken. This can lead to rounding errors. */ +double x = -0x1.0p53; +double y = 1; +int +main (void) +{ + while (y > 0) + y += x; + if (y != x + 1) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr29302-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr29302-1.c new file mode 100644 index 000000000..f6f3dd2cd --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr29302-1.c @@ -0,0 +1,16 @@ +extern void abort (void); + +int main (void) +{ + int n; + long double x; + + x = 1/0.0; + + n = (x == 1/0.0); + + if (n == 1) + return 0; + else + abort (); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.c new file mode 100644 index 000000000..2b63e67a0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.c @@ -0,0 +1,55 @@ +/* PR middle-end/30704 */ + +typedef __SIZE_TYPE__ size_t; +extern void abort (void); +extern int memcmp (const void *, const void *, size_t); +extern void *memcpy (void *, const void *, size_t); + +long long +f1 (void) +{ + long long t; + double d = 0x0.fffffffffffff000p-1022; + memcpy (&t, &d, sizeof (long long)); + return t; +} + +double +f2 (void) +{ + long long t = 0x000fedcba9876543LL; + double d; + memcpy (&d, &t, sizeof (long long)); + return d; +} + +int +main () +{ + union + { + long long ll; + double d; + } u; + + if (sizeof (long long) != sizeof (double) || __DBL_MIN_EXP__ != -1021) + return 0; + + u.ll = f1 (); + if (u.d != 0x0.fffffffffffff000p-1022) + abort (); + + u.d = f2 (); + if (u.ll != 0x000fedcba9876543LL) + abort (); + + double b = 234.0; + long long c; + double d = b; + memcpy (&c, &b, sizeof (double)); + long long e = c; + if (memcmp (&e, &d, sizeof (double)) != 0) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.x b/gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.x new file mode 100644 index 000000000..1e111fc2c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.x @@ -0,0 +1,5 @@ +if [istarget "avr-*-*"] {
+ # AVR doubles are floats
+ return 1
+}
+return 0
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr36332.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr36332.c new file mode 100644 index 000000000..325ac88b8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr36332.c @@ -0,0 +1,15 @@ +/* PR target/36332 */ + +int +foo (long double ld) +{ + return ld == __builtin_infl (); +} + +int +main () +{ + if (foo (__LDBL_MAX__)) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.c new file mode 100644 index 000000000..1fc083488 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.c @@ -0,0 +1 @@ +#include "fp-cmp-8.c" diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.x b/gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.x new file mode 100644 index 000000000..b70c87439 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.x @@ -0,0 +1,2 @@ +lappend additional_flags "-fno-ivopts" "-fno-gcse" +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr50310.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr50310.c new file mode 100644 index 000000000..8d323ca78 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr50310.c @@ -0,0 +1,73 @@ +/* PR target/50310 */ + +extern void abort (void); +double s1[4], s2[4], s3[64]; + +void +foo (void) +{ + int i; + for (i = 0; i < 4; i++) + s3[0 * 4 + i] = __builtin_isgreater (s1[i], s2[i]) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[1 * 4 + i] = (!__builtin_isgreater (s1[i], s2[i])) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[2 * 4 + i] = __builtin_isgreaterequal (s1[i], s2[i]) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[3 * 4 + i] = (!__builtin_isgreaterequal (s1[i], s2[i])) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[4 * 4 + i] = __builtin_isless (s1[i], s2[i]) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[5 * 4 + i] = (!__builtin_isless (s1[i], s2[i])) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[6 * 4 + i] = __builtin_islessequal (s1[i], s2[i]) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[7 * 4 + i] = (!__builtin_islessequal (s1[i], s2[i])) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[8 * 4 + i] = __builtin_islessgreater (s1[i], s2[i]) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[9 * 4 + i] = (!__builtin_islessgreater (s1[i], s2[i])) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[10 * 4 + i] = __builtin_isunordered (s1[i], s2[i]) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[11 * 4 + i] = (!__builtin_isunordered (s1[i], s2[i])) ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[12 * 4 + i] = s1[i] > s2[i] ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[13 * 4 + i] = s1[i] <= s2[i] ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[14 * 4 + i] = s1[i] < s2[i] ? -1.0 : 0.0; + for (i = 0; i < 4; i++) + s3[15 * 4 + i] = s1[i] >= s2[i] ? -1.0 : 0.0; +} + +int +main () +{ + int i; + s1[0] = 5.0; + s1[1] = 6.0; + s1[2] = 5.0; + s1[3] = __builtin_nan (""); + s2[0] = 6.0; + s2[1] = 5.0; + s2[2] = 5.0; + s2[3] = 5.0; + asm volatile ("" : : : "memory"); + foo (); + asm volatile ("" : : : "memory"); + for (i = 0; i < 16 * 4; i++) + if (i >= 12 * 4 && (i & 3) == 3) + { + if (s3[i] != 0.0) abort (); + } + else + { + static int masks[] = { 2, 2|4, 1, 1|4, 1|2, 8, 2, 1 }; + if (s3[i] + != (((1 << (i & 3)) & ((i & 4) ? ~masks[i / 8] : masks[i / 8])) + ? -1.0 : 0.0)) + abort (); + } + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c b/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c new file mode 100644 index 000000000..1586bd7d4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c @@ -0,0 +1,55 @@ +#if defined(__i386__) && defined(__FreeBSD__) +#include <ieeefp.h> +#endif + +double d (unsigned long long k) +{ + double x; + + x = (double) k; + return x; +} + +float s (unsigned long long k) +{ + float x; + + x = (float) k; + return x; +} + +main () +{ + unsigned long long int k; + double x; + +#if defined(__i386__) && defined(__FreeBSD__) + /* This test case assumes extended-precision, but FreeBSD defaults to + double-precision. Make it so. */ + fpsetprec (FP_PE); +#endif + + if (sizeof (double) >= 8) + { + k = 0x8693ba6d7d220401ULL; + x = d (k); + k = (unsigned long long) x; + if (k != 0x8693ba6d7d220800ULL) + abort (); + } + + k = 0x8234508000000001ULL; + x = s (k); + k = (unsigned long long) x; +#ifdef __SPU__ + /* SPU float rounds towards zero. */ + if (k != 0x8234500000000000ULL) + abort (); +#else + if (k != 0x8234510000000000ULL) + abort (); +#endif + + exit (0); +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.x b/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.x new file mode 100644 index 000000000..2664174e0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/rbug.x @@ -0,0 +1,10 @@ +# This doesn't work on d10v if doubles are not 64 bits + +if { [istarget "d10v-*-*"] && ! [string-match "*-mdouble64*" $CFLAGS] } { + set torture_execute_xfail "d10v-*-*" +} +if [istarget "avr-*-*"] { + # AVR doubles are floats + return 1 +} +return 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c new file mode 100644 index 000000000..7021b99ad --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c @@ -0,0 +1,39 @@ +extern void abort(); + +typedef union { + struct { + unsigned int hi; + unsigned int lo; + } i; + double d; +} hexdouble; + +static const double twoTo52 = 0x1.0p+52; + +void func ( double x ) +{ + hexdouble argument; + register double y, z; + unsigned int xHead; + argument.d = x; + xHead = argument.i.hi & 0x7fffffff; + if (__builtin_expect(!!(xHead < 0x43300000u), 1)) + { + y = ( x - twoTo52 ) + twoTo52; + if ( y != x ) + abort(); + z = x - 0.5; + y = ( z - twoTo52 ) + twoTo52; + if ( y == (( x - twoTo52 ) + twoTo52) ) + abort(); + } + return; +} + +int main() +{ + if (sizeof (double) == 4) + return 0; + func((double)1.00); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.x b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.x new file mode 100644 index 000000000..1e111fc2c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.x @@ -0,0 +1,5 @@ +if [istarget "avr-*-*"] {
+ # AVR doubles are floats
+ return 1
+}
+return 0
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc.c b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc.c new file mode 100644 index 000000000..d67fef023 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc.c @@ -0,0 +1,19 @@ +#include <float.h> + +extern void abort(void); + +static const double C = DBL_MAX; + +double foo(double x) +{ + return ( ( (x * C) * C ) * C); +} + +int main () +{ + double d = foo (0.0); + if (d != 0.0) + abort (); + + return 0; +} |