public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] PR 48837
@ 2011-05-06 10:47 Zdenek Dvorak
  2011-05-06 11:49 ` Richard Guenther
  2011-05-06 15:19 ` Jeff Law
  0 siblings, 2 replies; 3+ messages in thread
From: Zdenek Dvorak @ 2011-05-06 10:47 UTC (permalink / raw)
  To: gcc-patches

Hi,

when accumulator transformation is performed on a function like

foo(a)
{
  if (a > 0)
    return 1 + foo (a - 1)

  return bla();
}

this becomes

foo(a)
{
  int tmp = 0;

  while (a > 0)
    tm = 1 + tmp;

  return tmp + bla();
}

Before, bla was a tail-call, but after the optimization, it is not (since an addition
has to be performed after the result of bla is known).  However, we used to mark bla
as tail-call, leading to a misscompilation later.  Fixed by not marking tail-calls
when the transformation is performed.  Bootstrapped and regtested on i686.

Zdenek

	PR tree-optimization/48837
	* tree-tailcall.c (tree_optimize_tail_calls_1): Do not mark tailcalls
	when accumulator transformation is performed.

	* gcc.dg/pr48837.c: New testcase.

Index: tree-tailcall.c
===================================================================
--- tree-tailcall.c	(revision 173354)
+++ tree-tailcall.c	(working copy)
@@ -1021,6 +1021,14 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
 					     integer_one_node);
     }
 
+  if (a_acc || m_acc)
+    {
+      /* When the tail call elimination using accumulators is performed,
+	 statements adding the accumulated value are inserted at all exits.
+	 This turns all other tail calls to non-tail ones.  */
+      opt_tailcalls = false;
+    }
+
   for (; tailcalls; tailcalls = next)
     {
       next = tailcalls->next;
Index: testsuite/gcc.dg/pr48837.c
===================================================================
--- testsuite/gcc.dg/pr48837.c	(revision 0)
+++ testsuite/gcc.dg/pr48837.c	(revision 0)
@@ -0,0 +1,30 @@
+/* PR tree-optimization/48837 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+void abort (void);
+
+__attribute__((noinline))
+int baz(void)
+{
+  return 1;
+}
+
+inline const int *bar(const int *a, const int *b)
+{
+ return *a ? a : b;
+}
+
+int foo(int a, int b)
+{
+   return a || b ? baz() : foo(*bar(&a, &b), 1) + foo(1, 0);
+}
+
+int main(void)
+{
+ if (foo(0, 0) != 2)
+   abort();
+
+ return 0;
+}
+

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-05-06 15:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-06 10:47 [patch] PR 48837 Zdenek Dvorak
2011-05-06 11:49 ` Richard Guenther
2011-05-06 15:19 ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).