[PATCH] Fix expand_errno_check with tail calls (PR rtl-optimization/36017)

Jakub Jelinek jakub@redhat.com
Wed Apr 23 02:37:00 GMT 2008


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?

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