tree-tailcall.c (process_assignment): Only do accumulator transforms for floating...
authorRichard Sandiford <rsandifo@redhat.com>
Fri, 10 Sep 2004 12:00:33 +0000 (12:00 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 10 Sep 2004 12:00:33 +0000 (12:00 +0000)
* tree-tailcall.c (process_assignment): Only do accumulator transforms
for floating-point types if flag_unsafe_math_optimizations.

From-SVN: r87297

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/ieee/acc1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/ieee/acc2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/ieee/mzero6.c [new file with mode: 0644]
gcc/tree-tailcall.c

index 71223aa95412e3b2b1db9288ee6bd372c33cf23c..e44ffc55ad99e0c834ba81161fe05ae1b4eaf248 100644 (file)
@@ -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,
index c33d260b5b3cbf70a53b774e06571b0b23c6516d..80dd8b05c5d08d37393eb2bfc552b7c7acddc5c0 100644 (file)
@@ -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 (file)
index 0000000..e0d969b
--- /dev/null
@@ -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 (file)
index 0000000..2a44c8a
--- /dev/null
@@ -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 (file)
index 0000000..59ba6fe
--- /dev/null
@@ -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);
+}
index e3f491e2be1cc8251d2cff188e09d97e641b0b30..d6cfe4c49ed3d8fc0739029cdc24632bb6b60dae 100644 (file)
@@ -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 ();