This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Thread-safe profiling
Hi,
On Thu, 15 Mar 2007, Paolo Bonzini wrote:
> > 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.
>
> This is actually a special case in convert_modes. The code looks
> like:
Right, I noticed that, but thought it might have a reason to exist ;-) The
comment above explains some reasons, and on first thought, they seem
valid. You basically have the problem, that when you're faced with
(const_int -1 [0xffffffff]) (let's say coming from an input 0xffffffff),
and explicitely request it to be converted into DImode, and want it
unsigned, then you need to have (const_double [0xffffffff] [0] [0] [0]).
Except if the input (const_int -1 [0xffffffff]) resulted from a
shortening of 0xffffffffffffffffULL, because then you want
(const_double [0xffffffff] [0xffffffff] [0] [0]), or (const_int -1) again
:-(
Seems to me like a target conflict.
> Without your patch, oldmode is VOIDmode. It looks to me like the
> correct thing to do would be not to do the truncate and zero extension
> in this case:
>
> if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
> && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
> && GET_CODE (x) == CONST_INT && INTVAL (x) < 0
>
> /* If oldmode is VOIDmode, all we can do is hope that the
> constant was indeed signed and thus truncated to a
> CONST_INT. In other words, we have to assume that X
> does not need sign- or zero-extension as we do below. */
> && oldmode != VOIDmode)
> {
> HOST_WIDE_INT val = INTVAL (x);
> int width = GET_MODE_BITSIZE (oldmode);
>
> /* Test if we need to zero extend the low part too. */
> if (width < HOST_BITS_PER_WIDE_INT)
> val &= ((HOST_WIDE_INT) 1 << width) - 1;
>
> return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
> }
This will probably pessimize code. The condition below that isn't reached
in our case:
if ((GET_CODE (x) == CONST_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|| (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_CLASS (oldmode) == MODE_INT
...
MODE_BITSIZE(mode) in our case is > HOST_BITS_PER_WIDE_INT, and oldmode is
VOIDmode (hence not MODE_INT class), so we fall through. It's also no
VECTOR_MODE_P, so we reach:
temp = gen_reg_rtx (mode);
convert_move (temp, x, unsignedp);
return temp;
which explicitely goes over a register.
Sigh.
Ciao,
Michael.