This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: problem with alias-safe code
- To: rth at cygnus dot com
- Subject: Re: problem with alias-safe code
- From: Mark Mitchell <mark at markmitchell dot com>
- Date: Sun, 28 Jun 1998 10:38:50 -0700
- CC: drepper at cygnus dot com, egcs-patches at cygnus dot com
- References: <r2ogveu5ch.fsf.cygnus.egcs.bugs@happy.cygnus.com> <199806280549.WAA17031@dot.cygnus.com>
- Reply-to: mark at markmitchell dot com
>>>>> "Richard" == Richard Henderson <rth@cygnus.com> writes:
Richard> In article
Richard> <r2ogveu5ch.fsf.cygnus.egcs.bugs@happy.cygnus.com>,
Richard> Ulrich Drepper <drepper@cygnus.com> wrote:
>> (((union { double D; int I[2]; }) {D: x}).I[1]) = i &
>> 0x7fffffff;
Richard> This bit doesn't do what you think. It modifies x in the
Richard> same way `Constructor(x).I[1] = blah' doesn't in c++.
Oh, dear. I always get bogged down in these GCC extensions. I'm sure
there's a good reason for them, but in this case why not just write:
double my_fabs (double x)
{
union u_t { double d; int i[2]; };
((union u_t*) &x)->i[1] &= 0x7fffffff;
return x;
}
This code is more portable to other compilers (FWIW). The code I get
for this is:
my_fabs:
andb $127,11(%esp)
fldl 4(%esp)
ret
which looks reasonably close to optimal, to me, although I don't know
all the rules for cycle-counting on the x86.
I've guaranteed that accesses through a union type will always be
allowed to alias objects whose types are the same as one of the union
variants, thus permitting type-punning like this. (Unless, of course,
the compiler proves they don't alias for some other,
not-having-to-do-with-types, reason).
Richard> There was another extension I'd hoped would work --
Richard> casting to a union -- given that gcc has a
Richard> cast-is-still-an-lvalue extension as well. But it turned
Richard> out to do a copy as well.
Richard> I would up spending the day implementing this extension
Richard> to the union cast feature. I also made certain forms not
Richard> an lvalue, since I couldn't see how to make them work as
Richard> expected.
Richard> So now you can implement fabs as
Richard> double fabs (double x) { ((union { double d; int i[2];
Richard> })x).i[1] &= 0x7fffffff; return x; }
Richard> If this seems a sane kind of thing implementation-wise,
Richard> I'll update the documentation as well. Mark, I'm a
Richard> little fuzzy on where your alias stuff wants to hook in
Richard> -- is this safe wrt that, bypassing conversions as I am?
Richard, I'm not quite sure whether your proposed extension will work
with my stuff or not, but the note about type-punning above does
apply, so I think you're OK.
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com