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]

Alpha memcpy bug


I encountered a bug with optimization of the memcpy() function using egcs 1.1b
on a alphaev56-unknown-linux-gnu system.  I was writing a routine that does
endian swapping for long variables and discovered that in the optimization 
for a memcpy() with a length of 8 doesn't always work correctly.

Here's my test case: 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define swab64(x) \
        ((unsigned long)( \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x00000000000000ffULL) << 56) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x000000000000ff00ULL) << 40) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x0000000000ff0000ULL) << 24) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x00000000ff000000ULL) <<  8) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x000000ff00000000ULL) >>  8) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x0000ff0000000000ULL) >> 24) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0x00ff000000000000ULL) >> 40) | \
                (unsigned long)(((unsigned long)(x) & (unsigned long)0xff00000000000000ULL) >> 56) ))


void hi(char *buf)
{
  unsigned long z = 1, y = 0x3333333333333333l;
  unsigned long cp;

  puts(buf);

  buf = (char *)&y;

  cp = swab64(z);

  printf("A: %.16lX\n", cp);

  printf("B: %.16lX\n", y);

  memcpy((buf), &cp, 8);

  printf("C: %.16lX\n", *(unsigned long *)buf);
  
  printf("D: %.16lX %.16lx\n", z, y);
}

int main()
{
  char buf[256]="hi";
  hi(buf);
  exit(EXIT_SUCCESS);
}

Yes, I know it's a bizarre way of doing things, but...  :^)

If I compile it without optimization, the results are correct, the numbers on
line D are endian opposites.

% cc -Wall hi.c -g 
% ./a.out
hi
A: 0100000000000000
B: 3333333333333333
C: 0100000000000000
D: 0000000000000001 0100000000000000

If I compile with optimization, a problem occurs:

% cc -Wall hi.c -g -O
% ./a.out
hi
A: 0100000000000000
B: 3333333333333333
C: 3333333333333300
D: 0000000000000001 3333333333333300

I looked at the assembly egcs spit out.

Without optimization, the memcpy line looks like:

	.stabn 68,0,32,$LM8
	addq $15,40,$1
	ldq $16,16($15)
	bis $1,$1,$17
	bis $31,8,$18
	jsr $26,memcpy
	ldgp $29,0($26)

With optimization, it looks like:

	.stabn 68,0,32,$LM7
	stb $9,16($30)

I assume the compiler should have used a "stq_u" instruction instead of "stb".
I'm not really a compiler person, so I don't know where to look in the source
to find and fix the problem, but I'm sure one of you can.

Thanks in advance for any help,

Ken Preslan
kpreslan@lcse.umn.edu





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