This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Alpha memcpy bug
- To: egcs-bugs at cygnus dot com
- Subject: Alpha memcpy bug
- From: Kenneth Preslan <kpreslan at lcse dot umn dot edu>
- Date: Thu, 10 Sep 1998 14:46:48 -0500 (CDT)
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