<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hi Mikael,<div><br><div><div>On Aug 15, 2014, at 3:42 AM, Mikael Holmén <<a href="mailto:mikael.holmen@ericsson.com">mikael.holmen@ericsson.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Hi,<br><br>I have a problem regarding sub-register definitions and LiveIntervals on<br>our target. When a subregister is defined, other parts of the register<br>are always left untouched - they are neither read or def:ed.<br><br>It however seems that Codegen treats subregister definitions as somehow<br>clobbering the whole register.<br><br>The SSA-code looks like this after isel:<br><br>(Reg0 and Reg1 are 16bit registers. Reg2, Reg3 and Reg4 are 32 bit<br>registers with 16bit subregs, hi16 and lo16.)<br><br>Reg0 = #imm0<br>Reg1 = #imm1<br><br>Reg2 = IMPLICIT_DEF<br>Reg3 = INSERT_SUBREG Reg2, Reg0, hi16<br>Reg4 = INSERT_SUBREG Reg3, Reg1, lo16<br><br>After TwoAddressInstructionPass it becomes:<br><br>Reg5:hi16<def,read-undef> = Reg0<br>Reg5:lo16<def>            = Reg1<br><br>So, in my world this means a setting of the high 16 bits in Reg5 (not<br>affecting the low part) followed by a setting of the low 16 bits (not<br>affecting the high part). Is this how LLVM looks at it too?<br></blockquote><div><br></div>Yes, it is.</div><div><br><blockquote type="cite"><br>(What does the "read-undef" part really mean, since in my<br>world, the setting of lo16 or hi16 does not in any way affect or<br>access the other part of the register.)<br></blockquote><div><br></div>read-undef means that we care only about the part we are defining.</div><div>Reg5:hi16<def,read-undef> means that whatever is set in Reg5, but hi16, we do not care.</div><div>Reg5:lo16<def>  means that we do care about the value of Reg5:hi16.</div><div><br></div><div>Here is the exact definition:</div><div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">  /// IsUndef - True if this register operand reads an "undef" value, i.e. the</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">  /// read value doesn't matter.  This flag can be set on both use and def</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">  /// operands.  On a sub-register def operand, it refers to the part of the</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">  /// register that isn't written.  On a full-register def operand, it is a</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">  /// noop.  See readsReg().</div></div><div><br></div><div><blockquote type="cite"><br>The question is: How should true subregister definitions be<br>expressed so that they do not interfere with each other? See the<br>detailed problem description below.<br></blockquote><div><br></div><div>We do have a limitation in our current liveness tracking for sub-register. Therefore, I am not sure that is possible.</div><div><br></div><div>Conceptually, what you want is:</div><div><div>Reg5:hi16<def,read-undef></div><div>Reg5:lo16<def,read-undef></div><div><br></div><div>However, I guess this wouldn’t be supported, because it would mean that we do not care about the value of hi16 at the definition of Reg5:lo16. This is true, but after this definition we do care about hi16 and I am afraid read-undef does not convey the right information for the subsequent uses of Reg5.</div><div><br></div><div>You can give it a try and see how it goes.</div></div><br><blockquote type="cite"><br>---<br><br>During RA it's decided Reg5 should be spilled and it's also decided Reg5<br>can be rematerialized:<br><br>"Value Reg5:0@5000r may remat from Reg5:hi16<def,read-undef> = mv_any16<br>32766"<br><br>So it says Reg5 can be rematerialized by setting it's high part...<br><br>We also get:<br><br>     reload:   5052r    Reg5<def> = Load40FI <fi#2><br>     rewrite: 5056r    Reg5:lo16<def> = mv_nimm6_ar16 0<br><br>So it inserts a reload of the full Reg5 prior to the setting of<br>Reg5:lo16, because it thinks there is an implicit use of Reg5 when<br>writing the low part??? This seems very weird to me.<br><br>The decision is based on the fact that MachineOperand::readsReg()<br>returns true:<br><br>   /// readsReg - Returns true if this operand reads the previous value<br>of its<br>   /// register.  A use operand with the <undef> flag set doesn't read its<br>   /// register.  A sub-register def implicitly reads the other parts of the<br>   /// register being redefined unless the <undef> flag is set.<br>   ///<br>   /// This refers to reading the register value from before the current<br>   /// instruction or bundle. Internal bundle reads are not included.<br>   bool readsReg() const {<br>     assert(isReg() && "Wrong MachineOperand accessor");<br>     return !isUndef() && !isInternalRead() && (isUse() || getSubReg());<br>   }<br><br>I don't get why we automatically should get an implicit use just<br>because we are writing a subreg.<br><br>Since Reg5:lo16 is defined with<br><br>Reg5:lo16<def>            = Reg1<br><br>isUndef() will return false and getSubReg() true, and thus readsReg()<br>true and the reload is inserted.<br><br>Then we get<br><br>*** Bad machine code: Instruction loads from dead spill slot ***<br><br>because the spill slot has not been written.<br></blockquote><div><br></div><div>This is weird. Any chance you could share a test case?</div><div><br></div><div>Thanks,</div><div>-Quentin</div><br><blockquote type="cite"><br>Most grateful for any help,<br>Mikael Holmén<br>_______________________________________________<br>LLVM Developers mailing list<br><a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu">http://llvm.cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br></blockquote></div><br></div></body></html>