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.

Thanks,
Richard

Reply via email to