This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

bug in latest egcs


Hi,

One of the last changes introduced a bug in egcs which is only
visible with high optimization.  This is the stripped down source:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef int int32_t __attribute__ ((__mode__ (  __SI__ ))) ;
typedef unsigned int u_int32_t __attribute__ ((__mode__ (  __SI__ ))) ;

typedef union
{
  float value;
  u_int32_t word;
} ieee_float_shape_type;

long long int
__llroundf (float x)
{
  int32_t j0;
  u_int32_t i;
  long long int result;
  int sign;

  do {	ieee_float_shape_type gf_u;	gf_u.value = (  x );	( i ) = gf_u.word;	} while (0) ;
  j0 = ((i >> 23) & 0xff) - 0x7f;
  sign = (i & 0x80000000) != 0 ? -1 : 1;
  i &= 0x7fffff;
  i |= 0x800000;

  if (j0 < (int32_t) (8 * sizeof (long long int)))
    {
      if (j0 < 0)
	return j0 < -1 ? 0 : sign;
      else if (j0 >= 23)
	result = (long int) i << (j0 - 23);
      else
	{
	  i += 0x400000 >> j0;

	  result = i >> (23 - j0);
	}
    }
  else
    return (long long int) x;

  return sign * result;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The problem is in the assignment to `sign'.  On i386 using -O3 -g I get

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  do {  ieee_float_shape_type gf_u;     gf_u.value = (  x );    ( i ) = gf_u.wor
d;      } while (0) ;
   c:   83 ec 04        subl   $0x4,%esp
   f:   d9 14 24        fsts   (%esp,1)
  12:   58              popl   %eax
  13:   89 c7           movl   %eax,%edi
  j0 = ((i >> 23) & 0xff) - 0x7f;
  15:   c1 ef 17        shrl   $0x17,%edi
  18:   81 e7 ff 00 00  andl   $0xff,%edi
  1d:   00 
  sign = (i & 0x80000000) != 0 ? -1 : 1;
  1e:   be 01 00 00 00  movl   $0x1,%esi
  23:   8d 5f 81        leal   0xffffff81(%edi),%ebx
  26:   85 ff           testl  %edi,%edi
  28:   7d 05           jnl    2f <__llroundf+0x2f>
  2a:   be ff ff ff ff  movl   $0xffffffff,%esi
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

(We should ignore the lame translation of the assignment to `i'
here, this is another topic).

The opcode at address 13: moves the real value from %eax to %edi.
In the following code the %edi value is modified and in line 23:
the value for the C variable `j0' is written to %ebx.

But in line 26: the `test' opcode examines the modified value and
not the unmodified value in %eax.  Therefore this test does not test
whether to MSB of `i' is set but it tests whether the MSB for

	(i >> 23) & 0xff

is set.


I guess the the code handling the aliases is wrong and that for
calculating `jo' %eax should have been used, leaving %edi unmodifed.

-- Uli
---------------.      drepper at gnu.org  ,-.   Rubensstrasse 5
Ulrich Drepper  \    ,-------------------'   \  76149 Karlsruhe/Germany
Cygnus Solutions `--' drepper at cygnus.com   `------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]