aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZdenek Dvorak <ook@ucw.cz>2011-05-07 21:43:18 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2011-05-07 19:43:18 +0000
commit1400c8e5013a0901298b3adfeb9c5dbfcef2f494 (patch)
tree691ff75d958a92205fca691305a1ba3940706a5e /gcc
parent5d0878e70dc34446015c4f2908869ad9e85cab8c (diff)
downloadgcc-1400c8e5013a0901298b3adfeb9c5dbfcef2f494.zip
gcc-1400c8e5013a0901298b3adfeb9c5dbfcef2f494.tar.gz
gcc-1400c8e5013a0901298b3adfeb9c5dbfcef2f494.tar.bz2
re PR tree-optimization/48837 (Wrong optimization of recursive function calls)
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: r173534
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr48837.c30
-rw-r--r--gcc/tree-tailcall.c8
4 files changed, 49 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6534bbc..a3f6a11 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-05-07 Zdenek Dvorak <ook@ucw.cz>
+
+ PR tree-optimization/48837
+ * tree-tailcall.c (tree_optimize_tail_calls_1): Do not mark tailcalls
+ when accumulator transformation is performed.
+
2011-05-06 Jan Hubicka <jh@suse.cz>
* i386.h (ix86_tune_indices): Add X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ea142c2..735ac68 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-05-07 Zdenek Dvorak <ook@ucw.cz>
+
+ PR tree-optimization/48837
+ * gcc.dg/pr48837.c: New testcase.
+
2011-05-06 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-condition2.C: New.
diff --git a/gcc/testsuite/gcc.dg/pr48837.c b/gcc/testsuite/gcc.dg/pr48837.c
new file mode 100644
index 0000000..ffc65b9
--- /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 c94d6ca..6a23080 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -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;