This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Bad optimization of a function pointer call with GCC 2.8.1


/*********************************************************************
Bad loop-invariant optimization of a function pointer call with GCC 
2.8.1.

The following code, when compiled using the GCC compiler version 2.8.1 with 
optimization level -O1 or greater, generates incorrect code.

With the work-around disabled, fputc('*', stdout) is only called once 
instead of 10 times. The function pointed to by *fp_fputc should be called 
on each pass through the loop, but it is pulled out of the loop, and 
called only once which is wrong.

A work-around is to volatize a fp_fputc argument. It is unclear why this 
work-around is successful as the variable being volatized should make no 
difference to the optimizer -- the variable is a local automatic, address 
is not shared, etc. But it does work.

Running optimization level -O0 is another work-around.

Problem is seen with target machines: Motorola MPC860, SUN Sparc

Compile:    gcc -O1 -g -o gcc_fpopt_bug gcc_fpopt_bug.c
Run:        ./gcc_fpopt_bug

- Jeff Byers - jeff.byers@ada.com -

**********************************************************************/

/* gcc_fpopt_bug.c */
#include <stdio.h>

#ifndef USE_WORK_AROUND
#define USE_WORK_AROUND 0
#endif

typedef int tfd_fputc(int, FILE *);

static int
padit(int n, int c, const tfd_fputc *fp_putc, FILE *pFile)
{
   volatile int vol_c = c; // For work-around.
   while ( n-- > 0 )
   {
#     if (!USE_WORK_AROUND)
      if ( ((*fp_putc)( c, pFile )) != c )
#     else
      if ( ((*fp_putc)( vol_c, pFile )) != c )
#     endif
         return( 1 );
   }
   return( 0 );
}


int main(char *argv[], int argc)
{
   printf("Should see 10 '*'s, - %susing work-around.\n",
           USE_WORK_AROUND ? " " : "not ");
   padit( 10, '*', (const tfd_fputc *)fputc, stdout );
   printf("\nDone.\n");
   return(0);
}





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]