This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: [PATCH] Add new target-hook truncated_to_mode


Paolo Bonzini <paolo.bonzini@lu.unisi.ch> writes:
>>> bool
>>> truncated_to_mode (enum machine_mode mode, rtx x)
>>> {
>>>    if (REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x))
>>>      return true;
>>>
>>>    gcc_assert (!TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
>>>                                        GET_MODE_BITSIZE (GET_MODE (x)));
>>>    return num_sign_bit_copies (x, GET_MODE (x)) >
>>> 	 GET_MODE_BITSIZE (GET_MODE (x)) - GET_MODE_BITSIZE (mode);
>>> }
>>>
>>> In the MIPS case, you would have n_s_b_c (x, GET_MODE (x)) > 64 - 32.
>>>     
>>
>> This wouldn't work for DI->HI truncation for example.  There too only
>> the upper 33 bits have to match for the TRUNCATE to be unnecessary.
>> See comment around truncsdi in mips.md.
>>   
> If this is so, SImode should be passed to reg_truncated_to_mode as well,
> instead of HImode, shouldn't it?  What about this logic:
>
> int n = num_sign_bit_copies (x, GET_MODE (x));
> int dest_bits;
> enum machine_mode next_mode = mode;
> do
>   {
>     mode = next_mode;
>     dest_bits = GET_MODE_BITSIZE (mode);
>
>     /* If it is a no-op to truncate to MODE from a wider mode (e.g. to 
> HI from SI on MIPS),
>         we can check a weaker condition.  */
>     next_mode = GET_MODE_WIDER_MODE (mode);
>   }
> while (next_mode != VOIDmode
>        && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (next_mode),
>                     dest_bits);
>
> return (REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x))
>            || n > GET_MODE_BITSIZE (GET_MODE (x)) - dest_bits);

It looks like you're introducing a new assumption here: that we can
ignore TRULY_NOOP_TRUNCATE (X, Y) if the upper X-Y bits are all filled
with sign bits.   I realise that's true for both SH and MIPS, but the
current documentation of TRULY_NOOP_TRUNCATE doesn't guarantee it.
For example, I could imagine some future port wanting to preserve zero
extension instead of sign extension.  That still fits TRLULY_NOOP_TRUNCATION
as currently defined, but the code above would then be wrong.  And...

> On MIPS, we would not test HImode but SImode since TRULY_NOOP_TRUNCATION
> (32, 16) == true.  To me, this is a clue that the TRULY_NOOP_TRUNCATION
> macro is insufficient and could be replaced by another one.  For example
> (for MIPS -- SHmedia is the same with s/MIPS64/SHMEDIA/):
>
> /* Return the mode to which we should truncate an INMODE value before 
> operating
>    on it in OUTMODE.  For example, on MIPS we should truncate a 64-bit value
>    to 32-bits when operating on it in SImode or a narrower mode.
>
>    We return INMODE if no such truncation is necessary and we can just 
> pretend
>    that the value is already truncated.  */
> #define WIDEST_NECESSARY_TRUNCATION(outmode, inmode) \
>   (TARGET_MIPS64 \
>    && GET_MODE_BITSIZE (inmode) <= 32 \
>    && GET_MODE_BITSIZE (outmode) > 32 ? SImode : inmode)
>
> Since all uses of TRULY_NOOP_TRUNCATION (except one in convert.c which
> could be changed to use TYPE_MODE) are of the form TRULY_NOOP_TRUNCATION
> (GET_MODE_BITSIZE (x), GET_MODE_BITSIZE (y)), you could change them to
>
>     WIDEST_NECESSARY_TRUNCATION (x, y) != y
>
> We could also take the occasion to remove all the defines of
> TRULY_NOOP_TRUNCATION to 1, and put a default definition in defaults.h!
>
> You can then proceed to implement truncated_to_mode as
>
>    mode = WIDEST_NECESSARY_TRUNCATION (mode, GET_MODE (x));
>    gcc_assert (mode != GET_MODE (x));
>    return (REG_P (x) && rtl_hooks.reg_truncated_to_mode (mode, x))
>           || num_sign_bit_copies (x, GET_MODE (x)) >
> 	     GET_MODE_BITSIZE (GET_MODE (x)) - GET_MODE_BITSIZE (mode);
>
> What do you think?

...I think the same applies to this macro too.  That's one reason why I
prefer the alternative hook that I described: it makes the sign extension
explicit.  The other reason is that it would allow the middle-end to remove
redundant sign extensions.  (Note that WIDEST_NECESSARY_TRUNCATION(X, Y) == Z
does _not_ imply that sign-extension of a Z-bit value to X bits comes for free.
On MIPS, it isn't true for X==128, just X==64.)

Richard


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