on 2024/8/13 18:02, Richard Sandiford wrote:
> "Kewen.Lin" <li...@linux.ibm.com> writes:
>> on 2024/8/12 21:02, Richard Sandiford wrote:
>>> "Kewen.Lin" <li...@linux.ibm.com> writes:
>>>> Hi Richard,
>>>>
>>>> Thanks for the comments!
>>>>
>>>> on 2024/8/12 16:55, Richard Sandiford wrote:
>>>>> "Kewen.Lin" <li...@linux.ibm.com> writes:
>>>>>> Hi,
>>>>>>
>>>>>> Commit r15-2084 exposes one ICE in LRA.  Firstly, before
>>>>>> r15-2084 KFmode has 126 bit precision while V1TImode has 128
>>>>>> bit precision, so the subreg (subreg:V1TI (reg:KF 131) 0) is
>>>>>> paradoxical_subreg_p, which stops some passes from doing
>>>>>> some optimization.  After r15-2084, KFmode has the same mode
>>>>>> precision as V1TImode, passes are able to optimize more, but
>>>>>> it causes this ICE in LRA as described below:
>>>>>>
>>>>>> For insn 106 (set (mem:V1TI ...) (subreg:V1TI (reg:KF 133) 0)),
>>>>>> which matches pattern
>>>>>>
>>>>>> (define_insn "*vsx_le_perm_store_<mode>"
>>>>>>   [(set (match_operand:VSX_LE_128 0 "memory_operand" "=Z,Q")
>>>>>>         (match_operand:VSX_LE_128 1 "vsx_register_operand" "+wa,r"))]
>>>>>
>>>>> Is it well-formed to have "+" on an operand that is only semantically
>>>>> an input?  df and most passes would consider it to be a pure input
>>>>> and so would disregard any write that is intended to take place.
>>>>>
>>>>> E.g. if we have:
>>>>>
>>>>>   (set (reg:M R2) (reg:M R1)) ;; R1 dead
>>>>>   (set (reg:M R3) (reg:M R2))
>>>>>
>>>>> then it would be valid to change that to:
>>>>>
>>>>>   (set (reg:M R2) (reg:M R1))
>>>>>   (set (reg:M R3) (reg:M R1))
>>>>>
>>>>> without considering the "+" on the input to the first instruction.
>>>>
>>>> Good question, I guess the "+" is to match the fact that operand[1]
>>>> can be both read and written by this insn, operand[1] has to be
>>>> re-used as the dest register of vector rotate 64bit (doubleword swap).
>>>> but it'll get swapped back so it's safe if the register is still live
>>>> (like the above example).  For this case that writing to but later
>>>> restoring, I'm not sure if we can take it as "no write" (strip "+").
>>>
>>> Yeah.  AIUI, there is no way of satisfying the constraints in a way
>>> that makes operand 0 overlap operand 1, and:
>>>
>>>>
>>>> ;; The post-reload split requires that we re-permute the source
>>>> ;; register in case it is still live.
>>>> (define_split
>>>>   [(set (match_operand:VSX_LE_128 0 "memory_operand")
>>>>         (match_operand:VSX_LE_128 1 "vsx_register_operand"))]
>>>>   "!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed && !TARGET_P9_VECTOR
>>>>    && !altivec_indexed_or_indirect_operand (operands[0], <MODE>mode)"
>>>>   [(const_int 0)]
>>>> {
>>>>   rs6000_emit_le_vsx_permute (operands[1], operands[1], <MODE>mode);
>>>>   rs6000_emit_le_vsx_permute (operands[0], operands[1], <MODE>mode);
>>>>   rs6000_emit_le_vsx_permute (operands[1], operands[1], <MODE>mode);
>>>
>>> would not work correctly for that kind of overlap in any case.
>>
>> Guessing you meant the case that both operands are REGs?  I may miss
>> something, but the case here op0 is MEM and op1 is REG, is it still
>> possible to overlap?
> 
> Not unless the source register can be used in addresses, which I assume
> can't happen for vector registers.
> 
> That's why I said "AIUI, there is no way of satisfying the constraints
> in a way that makes operand 0 overlap operand 1".

Got it, thanks for clarifying!

BR,
Kewen

Reply via email to