This is the mail archive of the gcc-patches@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]

Re: problem with alias-safe code


>>>>> "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


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