Thread-safe profiling

Ian Lance Taylor iant@google.com
Thu Mar 15 17:40:00 GMT 2007


Michael Matz <matz@suse.de> writes:

> Without this change, this call will be miscompiled on 32bit hosts:
> 
> __sync_fetch_and_add_8 (ptr, -(unsigned long long)1);
> 
> Because the -1LL will be 0xffffffffffffffff in the tree expression.  Now 
> the expand_expr call above will turn that tree constant into a RTL 
> constant, namely (const_int -1 [0xffffffff]), that is correct as far as I 
> can see, as RTL constants are implicitely sign extended.
> 
> Now, without my change the convert_to_mode() call will turn that RTL 
> constant into the wrong 64bit unsigned variant of this (mode is DImode, 
> and due to the unsigned flag being set for the convert_to_mode call), 
> namely (const_int [0xffffffff] [0] [0] [0]), i.e. it's zero extended.

Hmmm, interesting problem.  This kind of thing isn't usually a problem
at the RTL level because we don't usually see CONST_INTs which are
larger than HOST_BITS_PER_WIDE_INT, so we don't get much opportunity
to mess them up.  It's increasingly painful to not have correct modes
for CONST_INTs.

> The tree argument 1 will be: <integer_cst <unsigned char> 255>, which is 
> correct, as the prototype for this builtin indeed has an unsigned char 
> integer type in arguments.  Now the expand_expr above will turn that into 
> (const_int 255 [0xff]), also still sort of correct.

That doesn't sound right.  immed_double_const with QImode should
return const_int 0xffffffff here.  Why do we have 0xff?

Ian



More information about the Gcc-patches mailing list