[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#322218: gcc -O2 optimization bug



Package: gcc
Version: 3.3.5-3

When compiled with -O2, the appended test program goes into an
infinite loop at run-time. When compiled with -O or with no
optimization, it runs correctly, exiting immediately and
generating no output.

I am using Debian GNU/Linux 3.1, with a 2.4.28 kernel and
libc6-2.3.2.ds1-22

#include <math.h>
#include <float.h>
#include <stdio.h>

/* gcc optimization bug
 *
 * Problem:  Program goes into an infinite loop when
 *           compiled with -O2 optimization.
 *
 * compile:  gcc $OPT bug.c -lm
 *     run:  ./a.out
 *
 * gcc -O  bug.c -lm   => works with 2.95.4, 3.3.5, 3.4.4, 4.0.0
 * gcc -O2 bug.c -lm   => infinite loop with 3.3.5 and 3.4.4
 *                     => works with 2.95.4 and 4.0.0
 */

static int bisection (double (*func)(double, void *), double a, double b, void *cd, double *xp)
{
   unsigned int count = 1;
   unsigned int bisect_count = 5;
   double fa, fb;
   double x = a;

   if (a > b)
     {
        double tmp = a; a = b; b = tmp;
     }

   fa = (*func)(a, cd);
   fb = (*func)(b, cd);

   if (fa * fb > 0)
     {
        *xp = a;
        return -1;
     }

   while (b > a)
     {
        double fx;

        if (fb == 0.0)
          {
             x = b;
             break;
          }
        if (fa == 0.0)
          {
             x = a;
             break;
          }

        if (count % bisect_count)
          {
             x = (a*fb - b*fa) / (fb - fa);
             if ((x <= a) || (x >= b))
               x = 0.5 * (a + b);
          }
        else
          x = 0.5 * (a + b);

        if ((x <= a) || (x >= b))
          break;

        fx = (*func)(x, cd);
        count++;

        if (fx*fa < 0.0)
          {
             fb = fx;
             b = x;
          }
        else
          {
             fa = fx;
             a = x;
          }
     }

   *xp = x;
   return 0;
}

static double f (double x, void *cd)
{
   (void) cd;

   return x - cos(x);
}

int main (void)
{
   double x;

   (void) bisection (&f, 0.0, 1.0, NULL, &x);

   if (fabs(f(x,NULL)) > DBL_EPSILON)
     fprintf (stdout, "Error\n");

   return 0;
}



Reply to: