Subject: 3.1 sparc64 codegen bug?
To: None <port-sparc64@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: port-sparc64
Date: 09/24/2007 03:45:56
I ran into a problem on sparc64. Adding debugging code, I found my
debugging code was broken. It looks to me like a codegen bug, and I'm
wondering if anyone else can agree, disagree, reproduce, etc. In
particular, if others using sparc64 3.1 *can't* reproduce this, that
would be very interesting information.
z.c:
#include <stdio.h>
typedef unsigned long int int64_t;
#define BYTES_PER_64 8
static void check(int64_t a, int64_t b, int64_t c, int64_t d)
{
unsigned char cb[BYTES_PER_64];
unsigned char db[BYTES_PER_64];
unsigned char pb[2*BYTES_PER_64];
int i;
int j;
int k;
int s;
for (i=0;i<BYTES_PER_64;i++)
{ cb[i] = (c >> (i*8)) & 0xff;
db[i] = (d >> (i*8)) & 0xff;
pb[i] = 0;
pb[i+BYTES_PER_64] = 0;
}
for (i=0;i<BYTES_PER_64;i++)
{ for (j=0;j<BYTES_PER_64;j++)
{ s = cb[i] * db[j];
k = i + j;
while (s)
{ s += pb[k];
pb[k] = s & 0xff;
s >>= 8;
k ++;
}
}
}
for (i=0;i<BYTES_PER_64;i++)
{ if ( (pb[i] != (b >> (i*8)) & 0xff) ||
( (pb[i+BYTES_PER_64] != (a >> (i*8)) & 0xff) &&
((i+=BYTES_PER_64),1) ) )
{ fprintf(stderr,"mul failed at %d\n",i);
for (i=BYTES_PER_64-1;i>=0;i--) fprintf(stderr,"%02x",cb[i]);
fprintf(stderr," * ");
for (i=BYTES_PER_64-1;i>=0;i--) fprintf(stderr,"%02x",db[i]);
fprintf(stderr,"\ngot ");
for (i=BYTES_PER_64-1;i>=0;i--) fprintf(stderr,"%02x",(a>>(i*8))&0xff);
for (i=BYTES_PER_64-1;i>=0;i--) fprintf(stderr,"%02x",(b>>(i*8))&0xff);
fprintf(stderr,"\nnot ");
for (i=(2*BYTES_PER_64)-1;i>=0;i--) fprintf(stderr,"%02x",pb[i]);
fprintf(stderr,"\n");
abort();
}
}
}
If I compile this with "cc -S z.c -g", I get z.s, which is over 1500
lines, but the relevant part is the beginning of the body of the last
loop:
.loc 1 36 0
ld [%fp+1979], %g1
sra %g1, 0, %g2
add %fp, 2031, %g1
add %g1, %g2, %g1
ldub [%g1-48], %g1
and %g1, 0xff, %g3
ld [%fp+1979], %g1
sll %g1, 3, %g2
ldx [%fp+2183], %g1
srlx %g1, %g2, %g1
cmp %g3, %g1
bne %xcc, .LL26
nop
As I read it, this code corresponds to
{ if ( (pb[i] & 0xff != (b >> (i*8))) ||
....
which is not what the source says.
In case it matters, the hardware is an Ultra 5:
cpu0 at mainbus0: SUNW,UltraSPARC-IIi @ 269.805 MHz, version 0 FPU
cpu0: 32K instruction (32 b/l), 16K data (32 b/l), 256K external (64 b/l)
Any thoughts? Apply a patch? Send-pr?
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML mouse@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B