[gnu.gcc.bug] gcc 1.33 80386 condition code bug

pace@PREP.AI.MIT.EDU (Pace Willison) (02/04/89)

I think I've tracked down a bug where the condition codes
are not maintained properly.  I'll give a quick summary now,
then more tomorrow after I can work on it some more.  If you
see that I'm lost, please tell me before I waste too much time.

I'm using gcc 1.33 compiled with itself on a system 5 80386, using
COFF_ENCAPSULATE.

CC_REVERSED is set in i386.md for some instructions, but is cleared
only by CC_STATUS_INIT.  It should also be cleared by some of the
instructions that don't set it.  In the code below, I think that
CC_REVERSED gets set at point [2], but since none of the intervining
instructions do CC_STATUS_INIT, it is still set at [3].  [3] ought to
clear CC_REVERSED, and since it doesn't the following jump instruction
thinks it needs to be reversed.

The fix is to put "cc_status.flags &= ~CC_REVERSED" in several of
the i386.md templates.  I'll begin learning how to do that tomorrow...
(I expect it will involve comparing notice_update_cc() with i386.md.)

It's amazing that the compiler apparently successfully compiles itself,
all of the binutils, gas, and emacs.  The bug has only shown up in
uncompress when the input is a file (but not if it is the standard input.)

Pace


struct foo {
	int x;
	char *y;
};

struct foo i;
unsigned char a;
main()
{
	/* the original code was checking the magic number at the beginnin
	 * of the file:
	 *  if (getchar () != a || getchar () != b) continue;
	 */
	for (;;) {
		if ((--i.x < 0 ? foo() : i.x) != a)
			return;
		if ((--i.x < 0 ? foo() : i.x) != a)
			return;
	}
}

	.file	"x.c"
gcc_compiled.:
.text
	.align 2
.globl _main
_main:
	pushl %ebp
	movl %esp,%ebp
	pushl %ebx
	movl $_i,%ebx
L2:
	decl (%ebx)        [1]<----- first decrement
	jns L6
	call _foo
	movl %eax,%edx
	jmp L7
L6:
	movl (%ebx),%edx
L7:
	movzbl _a,%eax
	cmpl %edx,%eax    [2]<--- CC_REVERSED set here
	jne L1
	decl (%ebx)        [3]<---- second decrement, CC_REVERSED accidentally
				left on
	cmpl $0,(%ebx)     <- compare needlessly inserted
	jle L9             <- jump sense reversed
	call _foo
	movl %eax,%edx
	jmp L10
L9:
	movl (%ebx),%edx
L10:
	movzbl _a,%eax
	cmpl %edx,%eax
	je L2
L1:
	leal -4(%ebp),%esp
	popl %ebx
	leave
	ret
.comm _a,1
.comm _i,8