another bug

Ulrich Drepper drepper@gnu.org
Sat Dec 13 22:36:00 GMT 1997


Hi,

I think I found another bug which was introduced in egcs by the gcc
2.8 merge.  So this might also effect gcc 2.8.  I sincerely hope that
none of my modifications to my local gcc repository caused this
problem.

I appended a preprocessed file which you must compile on ix86 using


	gcc e_hypotf.i -c -O3 -g -momit-leaf-frame-pointer -fPIC


The problematic code is right at the start

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   0:   83 ec 04        subl   $0x4,%esp
   3:   56              pushl  %esi
   4:   53              pushl  %ebx
   5:   e8 00 00 00 00  call   a <__ieee754_hypotf+0xa>
   a:   5b              popl   %ebx
   b:   81 c3 03 00 00  addl   $0x3,%ebx
  10:   00 
        float a,b,t1,t2,y1,y2,w;
        int32_t j,k,ha,hb;

        do {    ieee_float_shape_type gf_u;     gf_u.value = ( x );     ( ha ) =
 gf_u.word;     } while (0) ;
        ha &= 0x7fffffff;
  11:   8b 4c 24 0c     movl   0xc(%esp,1),%ecx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The load in the last line loads the word at offset 12 but the stack
layout is like this:

	+--------------+
	| param #2     |
	+--------------+
	| param #1     |
	+--------------+
	| return addr  |    <---- %esp + 12
	+--------------+
	| <not init.>  | <---------------------- created by the subl $4
	+--------------+
	| old %esi     |
	+--------------+
	| old %ebx     |    <---- %esp
	+--------------+

By some optimization the subl $4 moved before the prologue and this
kills all the parameter loading.

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

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
extern __inline    float         __ieee754_sqrtf     (  float  );	extern __inline    float         __ieee754_sqrtf     (  float   __x)	{	register   float   __result;	__asm __volatile__ (      "fsqrt"    : "=t" (__result) :   "0" (__x) );	return __result;	}

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;


	float __ieee754_hypotf(float x, float y)




{
	float a,b,t1,t2,y1,y2,w;
	int32_t j,k,ha,hb;

	do {	ieee_float_shape_type gf_u;	gf_u.value = ( x );	( ha ) = gf_u.word;	} while (0) ;
	ha &= 0x7fffffff;
	do {	ieee_float_shape_type gf_u;	gf_u.value = ( y );	( hb ) = gf_u.word;	} while (0) ;
	hb &= 0x7fffffff;
	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
	do {	ieee_float_shape_type sf_u;	sf_u.word = ( ha );	( a ) = sf_u.value;	} while (0) ;	 
	do {	ieee_float_shape_type sf_u;	sf_u.word = ( hb );	( b ) = sf_u.value;	} while (0) ;	 
	if((ha-hb)>0xf000000) {return a+b;}  
	k=0;
	if(ha > 0x58800000) {	 
	   if(ha >= 0x7f800000) {	 
	       w = a+b;			 
	       if(ha == 0x7f800000) w = a;
	       if(hb == 0x7f800000) w = b;
	       return w;
	   }
	    
	   ha -= 0x5d800000; hb -= 0x5d800000;	k += 60;
	   do {	ieee_float_shape_type sf_u;	sf_u.word = ( ha );	( a ) = sf_u.value;	} while (0) ;
	   do {	ieee_float_shape_type sf_u;	sf_u.word = ( hb );	( b ) = sf_u.value;	} while (0) ;
	}
	if(hb < 0x26800000) {	 
	    if(hb <= 0x007fffff) {	 
	        if(hb==0) return a;
		do {	ieee_float_shape_type sf_u;	sf_u.word = ( 0x3f000000 );	( t1 ) = sf_u.value;	} while (0) ;	 
		b *= t1;
		a *= t1;
		k -= 126;
	    } else {		 
	        ha += 0x5d800000; 	 
		hb += 0x5d800000;	 
		k -= 60;
		do {	ieee_float_shape_type sf_u;	sf_u.word = ( ha );	( a ) = sf_u.value;	} while (0) ;
		do {	ieee_float_shape_type sf_u;	sf_u.word = ( hb );	( b ) = sf_u.value;	} while (0) ;
	    }
	}
     
	w = a-b;
	if (w>b) {
	    do {	ieee_float_shape_type sf_u;	sf_u.word = ( ha&0xfffff000 );	( t1 ) = sf_u.value;	} while (0) ;
	    t2 = a-t1;
	    w  = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
	} else {
	    a  = a+a;
	    do {	ieee_float_shape_type sf_u;	sf_u.word = ( hb&0xfffff000 );	( y1 ) = sf_u.value;	} while (0) ;
	    y2 = b - y1;
	    do {	ieee_float_shape_type sf_u;	sf_u.word = ( ha+0x00800000 );	( t1 ) = sf_u.value;	} while (0) ;
	    t2 = a - t1;
	    w  = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
	}
	if(k!=0) {
	    do {	ieee_float_shape_type sf_u;	sf_u.word = ( 0x3f800000+(k<<23) );	( t1 ) = sf_u.value;	} while (0) ;
	    return t1*w;
	} else return w;
}



More information about the Gcc mailing list