Possible explanation for rbug.c failure on alpha

Brad Lucier lucier@math.purdue.edu
Fri Jan 21 14:24:00 GMT 2000


gcc/testsuite/gcc.c-torture/execute/ieee/rbug.c aborts on
alphaev6-unknown-linux-gnu with -mieee, but not without.  (And, since
Richard Henderson has stated that he runs all the tests in the ieee
directory with -mieee on the alpha, so do I.)  I've been trying to figure
out why, and may have an answer.

At one point in the code, you want to convert x, a double, to k, an
unsigned long long int, which is 8 bytes on the alpha.  x is in $f10,
and it wants k to be in $2, and the code that is generated with -g -O0
-mieee is:

	cvttqsvc $f10,$f11
	fmov $f11,$f10
	stt $f10,16($15)
$LM16:
	.stabn 68,0,28,$LM16
	ldq $2,16($15)

Now, the value of k is supposed to be 0x8693ba6d7d220800ULL, so it
will not fit in a long long int, it needs an unsigned long long int.
However, the documentation of the cvttq* instruction in version 4 of the
"Alpha Architecture Handbook" states (page 4-117):

The floating operand in register Fb is converted to a two's-complement
number ...

So this particular value will overflow when cvttq tries to convert it to
an integer.  The manual is not very clear on what happens on overflow;
it says:

See Section 4.7.7 for details of the stored result on integer overflow
and inexact result.

However, if you start following pointers, you end up in Section 4.7.10,
which says:

Conversion of ... an Infinity value to an integer gives a result of zero.

Section 4.7.10 does not mention integer overflow, but my guess is that it
converts any overlarge float, not just infinite values, to integer zero.
In fact, this is the value that register $2 ends up with.

In other words, a more complicated code sequence is needed to convert
a float to an unsigned long int (or, the same, an unsigned long long int)
with -mieee to get the correct answer.

Brad Lucier


More information about the Gcc-bugs mailing list