PR middle-end/PR36584
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 23 Jun 2008 17:31:12 +0000 (19:31 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 23 Jun 2008 17:31:12 +0000 (19:31 +0200)
PR middle-end/PR36584
* calls.c (expand_call): Increase alignment for recursive functions.

testsuite/ChangeLog:

PR middle-end/PR36584
* testsuite/gcc.dg/pr36584.c: New test.
* testsuite/gcc.target/i386/local2.c: Remove invalid test.

From-SVN: r137045

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr36584.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/local2.c [deleted file]

index c3b92392843c07f8c22c47e087b3c3e572ad52c8..9ab80e03a9fac4794966e72389716ad215bb61bd 100644 (file)
@@ -1,3 +1,8 @@
+2008-06-23  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR middle-end/PR36584
+       * calls.c (expand_call): Increase alignment for recursive functions.
+
 2008-06-23  Anatoly Sokolov  <aesok@post.ru>
 
        * config/avr/avr.c (avr_function_value): Add new 'outgoing' argument.
 
        * ggc.h (GGC_RESIZEVAR): New, reorder macros.
        * tracer.c (tail_duplicate): Fix for -Wc++-compat.
-       * tree-affine.c (aff_combination_expand, free_name_expansion):
-       Likewise.
+       * tree-affine.c (aff_combination_expand, free_name_expansion): Likewise.
        * tree-cfg.c (replace_by_duplicate_decl, replace_ssa_name,
        move_stmt_r, new_label_mapper): Likewise.
        * tree-complex.c (cvc_lookup): Likewise.
index e7799f0e2ad1c25f48406625cd9041d93018aaed..92ff9050e3bf4ea6414bb48971d4a73ff3ad875d 100644 (file)
@@ -2298,11 +2298,9 @@ expand_call (tree exp, rtx target, int ignore)
       || !lang_hooks.decls.ok_for_sibcall (fndecl))
     try_tail_call = 0;
 
-  /* Ensure current function's preferred stack boundary is at least
-     what we need.  We don't have to increase alignment for recursive
-     functions.  */
-  if (crtl->preferred_stack_boundary < preferred_stack_boundary
-      && fndecl != current_function_decl)
+  /* Ensure current function's preferred stack
+     boundary is at least what we need.  */
+  if (crtl->preferred_stack_boundary < preferred_stack_boundary)
     crtl->preferred_stack_boundary = preferred_stack_boundary;
 
   preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
index 4e8d0e78020baf11cb6b0391f15742d5aa75d09d..a377829b6744e7b342eb323992713a69bce74de0 100644 (file)
@@ -1,3 +1,9 @@
+2008-06-23  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR middle-end/PR36584
+       * testsuite/gcc.dg/pr36584.c: New test.
+       * testsuite/gcc.target/i386/local2.c: Remove invalid test.
+
 2008-06-23  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/36533
diff --git a/gcc/testsuite/gcc.dg/pr36584.c b/gcc/testsuite/gcc.dg/pr36584.c
new file mode 100644 (file)
index 0000000..7d83ece
--- /dev/null
@@ -0,0 +1,281 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -lm" } */
+/* { dg-options "-O2 -msse2 -mfpmath=sse" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+
+#ifdef __i386__
+#include "cpuid.h"
+#endif
+
+extern double fabs (double);
+extern void abort (void);
+
+const int MAX_ITERATIONS = 50;
+const double SMALL_ENOUGH = 1.0e-10;
+const double RELERROR = 1.0e-12;
+
+typedef struct p
+{
+  int ord;
+  double coef[7];
+}
+polynomial;
+
+static double
+polyeval (double x, int n, double *Coeffs)
+{
+  register int i;
+  double val;
+
+  val = Coeffs[n];
+  for (i = n - 1; i >= 0; i--)
+    val = val * x + Coeffs[i];
+
+  return (val);
+}
+
+static int
+regula_falsa (int order, double *coef, double a, double b, double *val)
+{
+  int its;
+  double fa, fb, x, fx, lfx;
+
+  fa = polyeval (a, order, coef);
+  fb = polyeval (b, order, coef);
+
+  if (fa * fb > 0.0)
+    return 0;
+
+  if (fabs (fa) < SMALL_ENOUGH)
+    {
+      *val = a;
+      return 1;
+    }
+
+  if (fabs (fb) < SMALL_ENOUGH)
+    {
+      *val = b;
+      return 1;
+    }
+
+  lfx = fa;
+
+  for (its = 0; its < MAX_ITERATIONS; its++)
+    {
+      x = (fb * a - fa * b) / (fb - fa);
+      fx = polyeval (x, order, coef);
+      if (fabs (x) > RELERROR)
+       {
+         if (fabs (fx / x) < RELERROR)
+           {
+             *val = x;
+             return 1;
+           }
+       }
+      else
+       {
+         if (fabs (fx) < RELERROR)
+           {
+             *val = x;
+             return 1;
+           }
+       }
+
+      if (fa < 0)
+       {
+         if (fx < 0)
+           {
+             a = x;
+             fa = fx;
+             if ((lfx * fx) > 0)
+               fb /= 2;
+           }
+         else
+           {
+             b = x;
+             fb = fx;
+             if ((lfx * fx) > 0)
+               fa /= 2;
+           }
+       }
+      else
+       {
+         if (fx < 0)
+           {
+             b = x;
+             fb = fx;
+             if ((lfx * fx) > 0)
+               fa /= 2;
+           }
+         else
+           {
+             a = x;
+             fa = fx;
+             if ((lfx * fx) > 0)
+               fb /= 2;
+           }
+       }
+
+      if (fabs (b - a) < RELERROR)
+       {
+         *val = x;
+         return 1;
+       }
+
+      lfx = fx;
+    }
+
+  return 0;
+}
+
+static int
+numchanges (int np, polynomial * sseq, double a)
+{
+  int changes;
+  double f, lf;
+  polynomial *s;
+  changes = 0;
+
+  lf = polyeval (a, sseq[0].ord, sseq[0].coef);
+
+  for (s = sseq + 1; s <= sseq + np; s++)
+    {
+      f = polyeval (a, s->ord, s->coef);
+      if (lf == 0.0 || lf * f < 0)
+       changes++;
+
+      lf = f;
+    }
+
+  return changes;
+}
+
+int
+sbisect (int np, polynomial * sseq, double min_value, double max_value,
+        int atmin, int atmax, double *roots)
+{
+  double mid;
+  int n1, n2, its, atmid;
+
+  if ((atmin - atmax) == 1)
+    {
+      if (regula_falsa (sseq->ord, sseq->coef, min_value, max_value, roots))
+       return 1;
+      else
+       {
+         for (its = 0; its < MAX_ITERATIONS; its++)
+           {
+             mid = (min_value + max_value) / 2;
+             atmid = numchanges (np, sseq, mid);
+             if ((atmid < atmax) || (atmid > atmin))
+               return 0;
+
+             if (fabs (mid) > RELERROR)
+               {
+                 if (fabs ((max_value - min_value) / mid) < RELERROR)
+                   {
+                     roots[0] = mid;
+                     return 1;
+                   }
+               }
+             else
+               {
+                 if (fabs (max_value - min_value) < RELERROR)
+                   {
+                     roots[0] = mid;
+                     return 1;
+                   }
+               }
+
+             if ((atmin - atmid) == 0)
+               min_value = mid;
+             else
+               max_value = mid;
+           }
+
+         roots[0] = mid;
+         return 1;
+       }
+    }
+
+  for (its = 0; its < MAX_ITERATIONS; its++)
+    {
+      mid = (min_value + max_value) / 2;
+      atmid = numchanges (np, sseq, mid);
+      if ((atmid < atmax) || (atmid > atmin))
+       return 0;
+
+      if (fabs (mid) > RELERROR)
+       {
+         if (fabs ((max_value - min_value) / mid) < RELERROR)
+           {
+             roots[0] = mid;
+             return 1;
+           }
+       }
+      else
+       {
+         if (fabs (max_value - min_value) < RELERROR)
+           {
+             roots[0] = mid;
+             return 1;
+           }
+       }
+
+      n1 = atmin - atmid;
+      n2 = atmid - atmax;
+
+      if ((n1 != 0) && (n2 != 0))
+       {
+         n1 = sbisect (np, sseq, min_value, mid, atmin, atmid, roots);
+         n2 = sbisect (np, sseq, mid, max_value, atmid, atmax, &roots[n1]);
+
+         return (n1 + n2);
+       }
+
+      if (n1 == 0)
+       min_value = mid;
+      else
+       max_value = mid;
+    }
+
+  roots[0] = mid;
+  return 1;
+}
+
+int
+main ()
+{
+  polynomial sseq[7] = {
+    {6, {0.15735259075109281, -5.1185263411378736, 1.8516070705868664,
+        7.348009172322695, -2.2152395279161343, -2.7543325329350692, 1.0}},
+    {5, {-0.8530877235229789, 0.61720235686228875, 3.6740045861613475,
+        -1.4768263519440896, -2.2952771107792245, 1.0}},
+    {4, {0.13072124257049417, 2.2220687798791126, -1.6299431586726509,
+        -1.6718404582408546, 1.0}},
+    {3, {0.86776597575462633, -2.1051099695282511, -0.49008580100694688,
+        1.0}},
+    {2, {-11.117984175064155, 10.89886635045883, 1.0}},
+    {1, {0.94453099602191237, -1.0}},
+    {0, {-0.068471716890574186}}
+  };
+
+  double roots[7];
+  int nroots;
+
+#ifdef __i386__
+  unsigned int eax, ebx, ecx, edx;
+
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  if (!(edx & bit_SSE2))
+    return 0;
+#endif
+
+  nroots = sbisect (6, sseq, 0.0, 10000000.0, 5, 1, roots);
+  if (nroots != 4)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/local2.c b/gcc/testsuite/gcc.target/i386/local2.c
deleted file mode 100644 (file)
index b6d960c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-require-effective-target nonpic } */
-/* { dg-options "-O2 -funit-at-a-time -fomit-frame-pointer" } */
-/* { dg-final { scan-assembler-not "sub\[^\\n\]*sp" } } */
-
-static __attribute__ ((noinline)) q ();
-int a;
-
-/* This function should not require any stack manipulation
-   for preferred stack bounday.  */
-void
-e ()
-{
-  if (a)
-  {
-    e ();
-    a--;
-  }
-  q ();
-}
-
-static __attribute__ ((noinline)) q ()
-{
-}