This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/4844: Code generation bug for hppa64
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/4844: Code generation bug for hppa64
- From: Ross Alexander <ross dot alexander at uk dot neceur dot com>
- Date: Fri, 9 Nov 2001 17:50:41 GMT
>Number: 4844
>Category: c
>Synopsis: Code generation bug for hppa64
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Fri Nov 09 09:56:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Ross Alexander
>Release: 3.0.2
>Organization:
NEC Europe Limited
>Environment:
System: HP-UX styx B.11.00 U 9000/800 561706507 unlimited-user license
host: hppa64-hp-hpux11.00
build: hppa64-hp-hpux11.00
target: hppa64-hp-hpux11.00
configured with: /tmp/gcc-3.0.2/configure --prefix=/opt/dev64-hpld --with-gnu-as hppa64-hp-hpux11.00
>Description:
GCC produces incorrect code when compiling openssl-SNAP-011104. The optimizer
gets the code completely wrong (see below). I have a simple tset program that
works and then the real program and the incorrect assembly.
--- fred.c ---
#include <stdio.h>
struct BIGNUM {
int neg;
};
int main(){
struct BIGNUM a, b;
a.neg = 0;
b.neg = 1;
printf("%d %d\n", a, b);
a.neg = !a.neg;
b.neg = !b.neg;
printf("%d %d\n", a, b);
return 0;
}
--- fred.s --- ** lines of interest for a.neg != a.neg
.LEVEL 2.0w
.IMPORT printf,ENTRY
.IMPORT __main,ENTRY
.section .rodata
.align 4
L$C0000
.STRING "%d %d\x0a\x00"
.text
.align 8
.EXPORT main,ENTRY
main
.PROC
.CALLINFO FRAME=256,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.ENTRY
std %r2,-16(%r30)
copy %r3,%r1
copy %r30,%r3
std,ma %r1,256(%r30)
std %r27,24(%r3)
ldo -16(%r30),%r29
b,l __main,%r2
nop
ldd 24(%r3),%r27
stw %r0,8(%r3)
ldi 1,%r19
stw %r19,12(%r3)
addil LT'L$C0000,%r27
ldd RT'L$C0000(%r1),%r1
copy %r1,%r26
ldw 8(%r3),%r25
ldw 12(%r3),%r24
ldo -16(%r30),%r29
b,l printf,%r2
nop
** ldd 24(%r3),%r27
** stw %r0,32(%r3)
** ldw 8(%r3),%r19
** cmpib,<>,n 0,%r19,L$0002
** ldi 1,%r19
** stw %r19,32(%r3)
L$0002
** ldw 32(%r3),%r19
** stw %r19,8(%r3)
stw %r0,36(%r3)
ldw 12(%r3),%r19
cmpib,<>,n 0,%r19,L$0003
ldi 1,%r19
stw %r19,36(%r3)
L$0003
ldw 36(%r3),%r19
stw %r19,12(%r3)
addil LT'L$C0000,%r27
ldd RT'L$C0000(%r1),%r1
copy %r1,%r26
ldw 8(%r3),%r25
ldw 12(%r3),%r24
ldo -16(%r30),%r29
b,l printf,%r2
nop
ldd 24(%r3),%r27
ldi 0,%r28
ldd -16(%r3),%r2
ldo 64(%r3),%r30
ldd,mb -64(%r30),%r3
bve,n (%r2)
.EXIT
.PROCEND
--- fred.out ---
0 1
1 0
--- bntest.c --- abbreviated --
int test_add(BIO *bp)
{
BIGNUM a,b,c;
int i;
BN_init(&a);
BN_init(&b);
BN_init(&c);
BN_bntest_rand(&a,16,0,0);
for (i=0; i<num0; i++)
{
BN_bntest_rand(&b,10+i,0,0);
a.neg=rand_neg();
b.neg=rand_neg();
BN_add(&c,&a,&b);
if (bp != NULL)
{
if (!results)
{
BN_print(bp,&a);
BIO_puts(bp," + ");
BN_print(bp,&b);
BIO_puts(bp," = ");
}
BN_print(bp,&c);
BIO_puts(bp,"\n");
}
printf("%d %d\n", a.neg, b.neg);
time(0);
a.neg=!a.neg;
b.neg=!b.neg;
printf("%d %d\n", a.neg, b.neg);
BN_add(&c,&c,&b);
BN_add(&c,&c,&a);
if(!BN_is_zero(&c))
{
fprintf(stderr,"Add test failed!\n");
return 0;
}
}
BN_free(&a);
BN_free(&b);
BN_free(&c);
return(1);
}
--- bntest.s --- ** instructions of interest
copy %r1,%r26
ldw 24(%r3),%r25
ldw 48(%r3),%r24
ldo -16(%r30),%r29
b,l printf,%r2
nop
ldd 104(%r3),%r27
.loc 1 282 0
ldi 0,%r26
ldo -16(%r30),%r29
b,l time,%r2
nop
ldd 104(%r3),%r27
.loc 1 284 0
** stw %r0,24(%r3)
** ldw 24(%r3),%r19
** cmpib,<>,n 0,%r19,L$0042
** ldi 1,%r19
** stw %r19,24(%r3)
L$0042
.loc 1 285 0
stw %r0,48(%r3)
ldw 48(%r3),%r19
cmpib,<>,n 0,%r19,L$0043
ldi 1,%r19
stw %r19,48(%r3)
L$0043
.loc 1 287 0
addil LT'L$C0028,%r27
ldd RT'L$C0028(%r1),%r1
copy %r1,%r26
ldw 24(%r3),%r25
ldw 48(%r3),%r24
ldo -16(%r30),%r29
b,l printf,%r2
nop
--- bntest.out ---
test BN_add
Add test failed!
obase=16
ibase=16
print "test BN_add\n"
B535 + 200 = B735
0 0
1 1
B535 + -4FF = B036
0 1
1 1
1
As you can see in bntest.i
stw %r0,24(%r3)
This sets a.neg to 0 (this is a bad instruction)
ldw 24(%r3),%r19
This loads the variable (set to 0) into r19
cmpib,<>,n 0,%r19,L$0042
This will now also fail so will not branch
ldi 1, %r19
stw %r19, 24(%r3)
This store 1 into the local variable.
The result is a.neg is always set to 1.
>How-To-Repeat:
Always happens.
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: