aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-09-10 12:00:33 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-09-10 12:00:33 +0000
commit85d625202998b5153d40cf1fbc36a400e8e013dd (patch)
tree24cd45cd4c7f9788733ecbef21298e2e39bb35a6 /gcc
parent315fcf9741b611fa84902ae28b52863d0009da42 (diff)
downloadgcc-85d625202998b5153d40cf1fbc36a400e8e013dd.zip
gcc-85d625202998b5153d40cf1fbc36a400e8e013dd.tar.gz
gcc-85d625202998b5153d40cf1fbc36a400e8e013dd.tar.bz2
tree-tailcall.c (process_assignment): Only do accumulator transforms for floating-point types if...
* tree-tailcall.c (process_assignment): Only do accumulator transforms for floating-point types if flag_unsafe_math_optimizations. From-SVN: r87297
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog6
-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/mzero6.c24
-rw-r--r--gcc/tree-tailcall.c7
6 files changed, 79 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71223aa..e44ffc5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2004-09-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * tree-tailcall.c (process_assignment): Only do accumulator transforms
+ for floating-point types if flag_unsafe_math_optimizations.
+
2004-09-10 Kazu Hirata <kazu@cs.umass.edu>
* config/darwin.c, config/alpha/alpha.h, config/arm/arm.c,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c33d260b..80dd8b0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcc.c-torture/execute/ieee/acc1.c: New test.
+ * gcc.c-torture/execute/ieee/acc2.c: New test.
+ * gcc.c-torture/execute/ieee/mzero6.c: New test.
+
2004-09-10 Joseph S. Myers <jsm@polyomino.org.uk>
* gcc.dg/deprecated-2.c: New test.
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 0000000..e0d969b
--- /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 0000000..2a44c8a
--- /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/mzero6.c b/gcc/testsuite/gcc.c-torture/execute/ieee/mzero6.c
new file mode 100644
index 0000000..59ba6fe
--- /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/tree-tailcall.c b/gcc/tree-tailcall.c
index e3f491e..d6cfe4c 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -282,6 +282,13 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
if (TREE_CODE_CLASS (code) != '2')
return false;
+ /* Accumulator optimizations will reverse the order of operations.
+ We can only do that for floating-point types if we're assuming
+ that addition and multiplication are associative. */
+ if (!flag_unsafe_math_optimizations)
+ if (FLOAT_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
+ return false;
+
/* We only handle the code like
x = call ();