summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.c-torture/execute/ieee
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/gcc.c-torture/execute/ieee')
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.c104
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20000320-1.x10
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20001122-1.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.c31
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20010114-2.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20010226-1.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20011123-1.c12
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.c32
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20030331-1.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/20041213-1.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.c8
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/920518-1.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/920810-1.c3
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/930529-1.c27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/980619-1.x15
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/acc1.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/acc2.c19
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/builtin-nan-1.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.c189
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-1.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-2.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.c97
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-3.x2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.c190
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/compare-fp-4.x23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/copysign1.c76
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/copysign2.c70
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.c43
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-1.x16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.c43
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-2.x22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.c43
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-3.x16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4.c135
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4e.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4f.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-4l.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-5.c131
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.c39
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-6.x16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.c14
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8.c145
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8e.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8f.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-8l.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.c27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/hugeval.x23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp79
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/inf-1.c44
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/inf-2.c83
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/inf-3.c79
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/minuszero.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.c75
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mul-subnormal-single-1.x16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.c58
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mzero2.x6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mzero3.c51
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mzero4.c58
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mzero5.c29
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/mzero6.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr28634.c15
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr29302-1.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.c55
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr30704.x5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr36332.c15
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr38016.x2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/pr50310.c73
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c55
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/rbug.x10
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c39
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.x5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/unsafe-fp-assoc.c19
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;
+}