This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Thread-safe profiling
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