On 10/13/2017 10:08 AM, Richard Sandiford wrote:
> Jeff Law <l...@redhat.com> writes:
>> On 08/24/2017 12:25 PM, Richard Sandiford wrote:
>>> Segher Boessenkool <seg...@kernel.crashing.org> writes:
>>>> On Wed, Aug 23, 2017 at 11:49:03AM +0100, Richard Sandiford wrote:
>>>>> This patch uses df_read_modify_subreg_p to check whether writing
>>>>> to a subreg would preserve some of the existing contents.
>>>>
>>>> combine does not keep the DF info up-to-date -- but that is no
>>>> problem here, df_read_modify_subreg_p uses no DF info at all.  Maybe
>>>> it should not have "df_" in the name?
>>>
>>> Yeah, I guess that's a bit confusing.  I've just posted a patch
>>> to rename it.
>>>
>>> Here's a version of the patch that applies on top of that one.
>>> Tested as before.  OK to install?
>>>
>>> Thanks,
>>> Richard
>>>
>>>
>>> 2017-08-24  Richard Sandiford  <richard.sandif...@linaro.org>
>>>         Alan Hayward  <alan.hayw...@arm.com>
>>>         David Sherwood  <david.sherw...@arm.com>
>>>
>>> gcc/
>>>     * caller-save.c (mark_referenced_regs):  Use read_modify_subreg_p.
>>>     * combine.c (find_single_use_1): Likewise.
>>>     (expand_field_assignment): Likewise.
>>>     (move_deaths): Likewise.
>>>     * lra-constraints.c (simplify_operand_subreg): Likewise.
>>>     (curr_insn_transform): Likewise.
>>>     * lra.c (collect_non_operand_hard_regs): Likewise.
>>>     (add_regs_to_insn_regno_info): Likewise.
>>>     * rtlanal.c (reg_referenced_p): Likewise.
>>>     (covers_regno_no_parallel_p): Likewise.
>>>
>>
>>
>>> Index: gcc/combine.c
>>> ===================================================================
>>> --- gcc/combine.c   2017-08-24 19:22:26.163269637 +0100
>>> +++ gcc/combine.c   2017-08-24 19:22:45.218100970 +0100
>>> @@ -579,10 +579,7 @@ find_single_use_1 (rtx dest, rtx *loc)
>>>       && !REG_P (SET_DEST (x))
>>>       && ! (GET_CODE (SET_DEST (x)) == SUBREG
>>>             && REG_P (SUBREG_REG (SET_DEST (x)))
>>> -           && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
>>> -                 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
>>> -               == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
>>> -                    + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
>>> +           && !read_modify_subreg_p (SET_DEST (x))))
>>>     break;
>> Is this correct for a paradoxical subreg?  ISTM the original code was
>> checking for a subreg that just changes the mode, but not the size
>> (subreg:SI (reg:SF)) or (subreg:DF (reg:DI)) kinds of things.  It would
>> reject a paradoxical AFAICT.
>>
>> As written now I think the condition would be true for a paradoxical.
>>
>> Similarly for the other two instances in combine.c and the changes in
>> rtlanal.c.
>>
>> In some of those cases you might be able to argue that it's the right
>> way to handle a paradoxical.  I haven't thought a whole lot about that
>> angle, but mention it as a possible way your change might still be correct.
> 
> Yeah, I agree this'll change the handling of paradoxical subregs that
> occupy more words than the SUBREG_REG, but I think the new version is
> correct.  The comment says:
> 
>       /* If the destination is anything other than CC0, PC, a REG or a SUBREG
>        of a REG that occupies all of the REG, the insn uses DEST if
>        it is mentioned in the destination or the source.  Otherwise, we
>        need just check the source.  */
> 
> and a paradoxical subreg does occupy all of the SUBREG_REG.
> 
> The code is trying to work out whether the instruction "reads" the
> destination if you view partial stores as a read of the old value
> followed by a write of a partially-updated value, whereas writing to a
> paradoxical subreg preserves none of the original value.  And that's
> also the semantics that the current code uses for "normal" word-sized
> paradoxical subregs.
OK.    Thanks for clarifying.

Jeff

Reply via email to