gcc-2.96-99 optimization bug?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I found gcc 2.96 (gcc-2.96-99.1.mipsel.rpm in H.J.Lu's RedHat 7.1)
outputs wrong code for this short program.

int foo(unsigned long long a, unsigned long long b)
{
	int as, bs;
	as = a >> 63;
	bs = b >> 63;
	if (as != bs)
		return as || !(b << 1);
	return (a == b) || as;
}

int main(int argc, char **argv)
{
	return foo(0, 0xffffffffffffffffull);
}

This program must return 0.  But compiling with -O2 it returns 1 !!

# gcc -O -o foo foo.c;./foo;echo $?
0
# gcc -O2 -o foo foo.c;./foo;echo $?
1

Output wth -O -g are:

00400780 <foo>:
  400780:	3c1c0fc0 	lui	gp,0xfc0
  400784:	279c78b0 	addiu	gp,gp,30896
  400788:	0399e021 	addu	gp,gp,t9
  40078c:	00804021 	move	t0,a0
  400790:	00a04821 	move	t1,a1
  400794:	000917c2 	srl	v0,t1,0x1f
  400798:	00402821 	move	a1,v0
  40079c:	000717c2 	srl	v0,a3,0x1f
  4007a0:	10a2000d 	beq	a1,v0,4007d8 <foo+0x58>
  4007a4:	00001821 	move	v1,zero
  4007a8:	14a00008 	bnez	a1,4007cc <foo+0x4c>
  4007ac:	00004021 	move	t0,zero
  4007b0:	00071840 	sll	v1,a3,0x1
  4007b4:	000627c2 	srl	a0,a2,0x1f
  4007b8:	00641825 	or	v1,v1,a0
  4007bc:	00061040 	sll	v0,a2,0x1
  4007c0:	00621025 	or	v0,v1,v0
  4007c4:	14400002 	bnez	v0,4007d0 <foo+0x50>
  4007c8:	00000000 	nop
  4007cc:	24080001 	li	t0,1
  4007d0:	03e00008 	jr	ra
  4007d4:	01001021 	move	v0,t0
  4007d8:	15060003 	bne	t0,a2,4007e8 <foo+0x68>
  4007dc:	00001021 	move	v0,zero
  4007e0:	11270003 	beq	t1,a3,4007f0 <foo+0x70>
  4007e4:	00000000 	nop
  4007e8:	10a00002 	beqz	a1,4007f4 <foo+0x74>
  4007ec:	00000000 	nop
  4007f0:	24020001 	li	v0,1
  4007f4:	03e00008 	jr	ra
  4007f8:	00000000 	nop

Output with -O2 -g are:

00400780 <foo>:
  400780:	3c1c0fc0 	lui	gp,0xfc0
  400784:	279c78b0 	addiu	gp,gp,30896
  400788:	0399e021 	addu	gp,gp,t9
  40078c:	00805021 	move	t2,a0
  400790:	00c04021 	move	t0,a2
  400794:	00a05821 	move	t3,a1
  400798:	00e04821 	move	t1,a3
  40079c:	000b17c2 	srl	v0,t3,0x1f
  4007a0:	000927c2 	srl	a0,t1,0x1f
  4007a4:	00001821 	move	v1,zero
  4007a8:	1044000a 	beq	v0,a0,4007d4 <foo+0x54>
  4007ac:	00002821 	move	a1,zero
  4007b0:	14400006 	bnez	v0,4007cc <foo+0x4c>
  4007b4:	24050001 	li	a1,1
  4007b8:	00091840 	sll	v1,t1,0x1
  4007bc:	000827c2 	srl	a0,t0,0x1f
  4007c0:	00641825 	or	v1,v1,a0
  4007c4:	00081040 	sll	v0,t0,0x1
  4007c8:	00621025 	or	v0,v1,v0
  4007cc:	03e00008 	jr	ra
  4007d0:	00a01021 	move	v0,a1
  4007d4:	15480003 	bne	t2,t0,4007e4 <foo+0x64>
  4007d8:	00001821 	move	v1,zero
  4007dc:	11690003 	beq	t3,t1,4007ec <foo+0x6c>
  4007e0:	00000000 	nop
  4007e4:	10400002 	beqz	v0,4007f0 <foo+0x70>
  4007e8:	00000000 	nop
  4007ec:	24030001 	li	v1,1
  4007f0:	03e00008 	jr	ra
  4007f4:	00601021 	move	v0,v1


It seems one 'bnez' in good code (at 4007c4) was lost in bad code.

Is this a know problem?  If so, is there any patches available?

Thank you.
---
Atsushi Nemoto


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux