Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Aug 2002 03:08:53 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        David Malone <dwmalone@maths.tcd.ie>
Cc:        Dan Lukes <dan@obluda.cz>, <freebsd-bugs@FreeBSD.org>, <bde@FreeBSD.org>
Subject:   Re: bin/40209: __dtoa broken with -O2 or -O3 optimisation 
Message-ID:  <20020813024056.R25046-100000@gamplex.bde.org>
In-Reply-To: <200208121047.aa31878@salmon.maths.tcd.ie>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 12 Aug 2002, David Malone wrote:

> > > I guess that changing x by accessing word0 or word1 is a violation
> > > of the aliasing rules. The deinitions might work:
>
> > I never listen about "aliasing rules". Where I can found something to
> > read about it ?
>
> It is a part of the C standard which was little known until gcc
> started using it for optimisation ;-) In section 6.5 (paragraph 7)
> of the C99 standard it say:
>
> 	An object shall have its stored value accessed only by an lvalue
> 	expression that has one of the following types:
>
>	[types quite similar to the original type, plus character types]
>
> This means that if you access a ULong then the compiler can assume
> that no doubles change their value 'cos their types are not compatible.
> By makeing them a member of a union, the compiler then knows that
> they may alias one another and so has to be more conservative.

I think of aliasing as having more to do with pointers than with accesses
Accessing an object through a pointer of type different from &object has
always been on thin ice, and the above rule just clarifies the limited
number of cases that are required to work.

> If Bruce thinks the new definitions for word0 and word1 look OK
> then I can commit them.

I wondered why msun doesn't have similar problems (it has many similar
accesses to the bits of doubles).  Well, it is because it once had the
problem but was fixed long ago.  From math_private.h:

% /*
%  * The original fdlibm code used statements like:
%  *	n0 = ((*(int*)&one)>>29)^1;		* index of high word *
%  *	ix0 = *(n0+(int*)&x);			* high word of x *
%  *	ix1 = *((1-n0)+(int*)&x);		* low word of x *
%  * to dig two 32 bit words out of the 64 bit IEEE floating point
%  * value.  That is non-ANSI, and, moreover, the gcc instruction
%  * scheduler gets it wrong.  We instead use the following macros.
%  * Unlike the original code, we determine the endianness at compile
%  * time, not at run time; I don't see much benefit to selecting
%  * endianness at run time.
%  */
% ...
% typedef union
% {
%   double value;
%   struct
%   {
%     u_int32_t lsw;
%     u_int32_t msw;
%   } parts;
% } ieee_double_shape_type;
%
% ...
% /* Get two 32 bit ints from a double.  */
%
% #define EXTRACT_WORDS(ix0,ix1,d)				\
% do {								\
%   ieee_double_shape_type ew_u;					\
%   ew_u.value = (d);						\
%   (ix0) = ew_u.parts.msw;					\
%   (ix1) = ew_u.parts.lsw;					\
% } while (0)

So I agree with changes to use a union even if theu only indirectly
fix a bug in gcc (I thought that gcc tries to make traditional hacks
dubious pointer accesses work).  The union accesses used in msun may
be more robust than the accesses through even the less dubious pointers
in the proposed patches.  I think they are equivalent but this depends
on even more details in the standard.

Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020813024056.R25046-100000>