Is this (gasp) a chip bug?

Darryl Richman darryl at ism780c.isc.com
Tue Jul 31 02:16:53 AEST 1990


In article <1990Jul23.223341.26431 at cbnewsc.att.com> imdave at cbnewsc.att.com (david.e.bodenstab) writes:
"	main()
"	{
"	    unsigned y = 0x7ffff0ff;
"	    unsigned x = 0x7ffff000;
"
"	    while (1) {
"		if ( ((int)(y - x)) < 0 )
"		    printf("WRONG x=%x y=%x (y - x)=%x\n",x,y,y-x);
"		x++;
"		y++;
"	    }
"	}
"
"This program `fails' on both a 386 and another cpu in-house -- the
"range of values for the `failure' are:
"
"	0x80000000 <= y <= 0x800000fe
"	0x7fffff01 <= x <= 0x7fffffff

You have uncovered a very subtle bug in your compilers.  As the
assembly language shows, you do a subtraction and then a conditional
branch based on the result as if the subtraction were signed.  Your C
code asks the compiler to do an unsigned subtraction, and then test the
result in a signed fashion.  This would require the compiler to
generate code approximately like:

	movl	y, %eax
	subl	x, %eax
	cmpl	$0, %eax
	bge	skip
	  ...
skip:

In your cases, the compiler (or perhaps the optimizer) has not done the
separate compare (on line 3), knowing that the subtract produced
condition codes, but it failed to note that they weren't correct for
the cast you requested.  So, when y becomes "negative", and until x goes
"negative", you will get incorrect results.

I'd be very interested to know the rationale for this code.  If y > x,
the result of the subtraction will have a potential range of
[1..max_unsigned], and if y < x, it will also have a range of
[1..max_unsigned], but with a borrow.  But you are asking to cast
only the result, not including the borrow, so the ranges are
indistinguishable.  What do you *really* want to do?

		--Darryl Richman

-- 
Copyright (c) 1990 Darryl Richman    The views expressed are the author's alone
darryl at ism780c.isc.com 		      INTERACTIVE Systems Corp.-A Kodak Company
 "For every problem, there is a solution that is simple, elegant, and wrong."
	-- H. L. Mencken



More information about the Comp.unix.i386 mailing list