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