From: Jakub Jelinek Date: Tue, 10 May 2011 08:47:09 +0000 (+0200) Subject: backport: re PR tree-optimization/48837 (Wrong optimization of recursive function... X-Git-Tag: releases/gcc-4.4.7~409 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3811910a67506fb4ac3c7b0d5da745fdd731d8a;p=thirdparty%2Fgcc.git backport: re PR tree-optimization/48837 (Wrong optimization of recursive function calls) Backported from mainline 2011-05-07 Zdenek Dvorak 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. From-SVN: r173611 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe0fc6a1146f..145b36ab238b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-05-10 Jakub Jelinek + + Backported from mainline + 2011-05-07 Zdenek Dvorak + + PR tree-optimization/48837 + * tree-tailcall.c (tree_optimize_tail_calls_1): Do not mark tailcalls + when accumulator transformation is performed. + 2011-05-05 Jason Merrill PR c++/40975 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e22b269a4a20..8e1852893d18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-05-10 Jakub Jelinek + + Backported from mainline + 2011-05-07 Zdenek Dvorak + + PR tree-optimization/48837 + * gcc.dg/pr48837.c: New testcase. + 2011-05-09 Jason Merrill * g++.dg/template/nontype23.C: New. diff --git a/gcc/testsuite/gcc.dg/pr48837.c b/gcc/testsuite/gcc.dg/pr48837.c new file mode 100644 index 000000000000..ffc65b9dc8c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr48837.c @@ -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; +} + diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 9d2513d271dc..55cdc51042ca 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -953,6 +953,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;