[PATCH] Fix expand_errno_check with tail calls (PR rtl-optimization/36017)
Richard Guenther
richard.guenther@gmail.com
Wed Apr 23 05:56:00 GMT 2008
On Wed, Apr 23, 2008 at 12:00 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> If a math builtin is called as a tail call with CALL_EXPR_TAILCALL
> set and errno check is done using a library call, in GCC 4.3+ the original
> CALL_EXPR is used with a modified argument (SAVE_EXPR) and thus it can
> be expanded as a tail call. But expand_errno_check in the non-error case
> jumps around it, and the tail call doesn't return. Fixed by making
> sure the error handling library call isn't a tail call (which is what
> 4.2 and earlier did because it recreated a CALL_EXPR). The likely code
> path is to jump around the library call, so if it doesn't end up being
> a tail call, it shouldn't be a big deal.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
Ok.
Thanks,
Richard.
> 2008-04-22 Jakub Jelinek <jakub@redhat.com>
>
> PR rtl-optimization/36017
> * builtins.c (expand_errno_check): Clear CALL_EXPR_TAILCALL before
> expanding the library call.
>
> * gcc.dg/pr36017.c: New test.
>
> --- gcc/builtins.c.jj 2008-04-08 11:27:38.000000000 +0200
> +++ gcc/builtins.c 2008-04-22 22:13:00.000000000 +0200
> @@ -1804,6 +1804,9 @@ expand_errno_check (tree exp, rtx target
> }
> #endif
>
> + /* Make sure the library call isn't expanded as a tail call. */
> + CALL_EXPR_TAILCALL (exp) = 0;
> +
> /* We can't set errno=EDOM directly; let the library call do it.
> Pop the arguments right away in case the call gets deleted. */
> NO_DEFER_POP;
> --- gcc/testsuite/gcc.dg/pr36017.c.jj 2008-04-22 22:11:49.000000000 +0200
> +++ gcc/testsuite/gcc.dg/pr36017.c 2008-04-22 22:11:25.000000000 +0200
> @@ -0,0 +1,29 @@
> +/* PR rtl-optimization/36017 */
> +/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
> +/* { dg-options "-O2 -lm" } */
> +
> +extern double sqrt (double);
> +extern void abort (void);
> +
> +__attribute__((noinline)) double
> +foo (double a)
> +{
> + double b, c, d = 0.7;
> + if (a <= d)
> + b = sqrt (d * a);
> + else
> + {
> + c = (1.0 - d) * (1.0 - a);
> + b = c > 0 ? 1.0 - sqrt (c) : 1.0;
> + }
> + return b;
> +}
> +
> +int
> +main (void)
> +{
> + double c = foo (0.5);
> + if (c > 0.5917)
> + abort ();
> + return 0;
> +}
>
> Jakub
>
More information about the Gcc-patches
mailing list