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]

Probable optimization bug in gcc 2.95.2


The program at the end seems to trigger an optimization bug
in gcc 2.95.2. As an example I show the also appended script under
Linux.

When compiling with -O2 I get the output

    (null): s=3051870873, 0.02667 usec/call

while I am expecting

    mwc32: s=3051870873, 0.02667 usec/call

-O and -O3 give the expected output. The same thing happens on
DOS with DJGPP (also gcc 2.95.2): -O and -O3 works, -O2 fails.

(The s=305..., was only for me to verify some code changes.)

My processor is AMD K6-2. I have not compiled Gcc myself.

If you need precompiled sources for either platform, I will be happy 
to send them.

As a side note, after uncommenting
 
/* if (description == NULL)
    printf("NULL pointer\n");  */

the program works as expected with all optimization options.

Regards,
Dieter Buerssner

localhost:[gccbug]> uname -a
Linux localhost.localdomain 2.2.14 #5 Mon Feb 14 05:06:37 CET 2000 
i586 unknown
localhost:[gccbug]> gcc -v
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux/2.95.2/specs
gcc version 2.95.2 19991024 (release)
localhost:[gccbug]> gcc -O2 gccbug.c
localhost:[gccbug]> ./a.out
description (pointer): (nil)
    (null): s=3051870873, 0.02667 usec/call
localhost:[gccbug]> gcc -O gccbug.c
localhost:[gccbug]> ./a.out
description (pointer): 0x80485e0
     mwc32: s=3051870873, 0.02667 usec/call
localhost:[gccbug]> gcc -O3 gccbug.c
localhost:[gccbug]> ./a.out
description (pointer): 0x8048658
     mwc32: s=3051870873, 0.02667 usec/call
localhost:[gccbug]> cat gccbug.c
#include <stdio.h>
#include <time.h>

unsigned long speed_loop(unsigned long (*tr)(void), unsigned long n)
{
  unsigned long s;
  s = 0;
  do
    s+=tr();
  while (--n != 0);
  return s;
}

/* Test the speed of function tr, take function call and loop
   overhead into account */
void speed(unsigned long (*tr)(void), unsigned long (*dummy)(void),
	   unsigned long n, const char *description)
{
  clock_t anf, anfdum;
  unsigned long s;

  /* if (description == NULL)
    printf("NULL pointer\n");  */
  printf("description (pointer): %p\n", description);
  anfdum = clock();
  speed_loop(dummy, n);
  anfdum = clock() - anfdum;
  anf = clock();
  s = speed_loop(tr, n);
  anf = clock() - anf;
  anf -= anfdum;
  printf("%10s: s=%lu, %.5f usec/call\n", description,
	 s, 1e6/n*(double)anf/CLOCKS_PER_SEC);
}

#define CALLS (1UL << 27)  /* Tune this as appropriate */

/* avoid inlining of these functions */
unsigned long dum_rand(void);
unsigned long mwc32(void);

int main(void)
{
  speed(mwc32, dum_rand, CALLS, "mwc32");
  return 0;
}

unsigned long dum_rand(void)
{
  return 0UL;
}

typedef unsigned long long ul64;

/* Multiply with carry RNG. */

static ul64 zseed = ((ul64)0x12345678UL<<32) | 0x87654321UL;

unsigned long mwc32(void)
{
  unsigned long l1, l2;
  ul64 res;
  /* Uncommenting const can make this function an order of
     magnitude slower on my AMD K6-2 (depends on
     compiler options an insignificant source changes) */
  static /* const */unsigned long mul=999996864UL;
  l1 = (unsigned long)(zseed & 0xffffffffUL);
  l2 = zseed>>32;
  res = l2+l1*(ul64)mul;
  zseed = res;
  return (unsigned long)(res & 0xffffffffUL);
}


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