| Submitter | Zdenek Dvorak |
|---|---|
| Date | May 6, 2011, 10:44 a.m. |
| Message ID | <20110506104417.GA8664@kam.mff.cuni.cz> |
| Download | mbox | patch |
| Permalink | /patch/94359/ |
| State | New |
| Headers | show |
Comments
On Fri, May 6, 2011 at 12:44 PM, Zdenek Dvorak <rakdver@kam.mff.cuni.cz> wrote: > 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. Ok. Thanks, Richard. > 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; > +} > + >
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 05/06/11 04:44, Zdenek Dvorak wrote: > 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. OK. Thanks, jeff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJNxA66AAoJEBRtltQi2kC7yysIAKZYUpU9JlyH2XwvvVslq8C1 CJ7E/akRDsBoYBS+syNsLMwkbGG0WoaFJzOd7vUmIknAHEusF6OasczsN8PD9aEB i8xJNTZm2yxhrVZh8m/KBX96r80RwzpAhr9L1WAspiS/xpw12lRoJoh3XeKXYXWw Z0aBL4ljCgLj6GKEyy7FbGHx0gEqaa1x7EDM1kJGCgZPAFJalJPozBiiriYL9/Th gHqLXZ0HUhXNGql5M2S+lfZG2d30Rj1KBXDrU8EOXedHRjxb+U9+WLGsUHZtkcTI j3//n6bjTr/YmyTe43voG3Rn6z6k0g2Eb8gF8UMvDbaSJlH9+xb6SuWLS8+mEhY= =luE9 -----END PGP SIGNATURE-----
Patch
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; +} +
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.