<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Mar 8, 2008, at 1:55 PM, Christopher Lamb wrote:</div><div><br class="webkit-block-placeholder"></div><div>Hey Christopher!</div><div><br class="webkit-block-placeholder"></div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>This was originally part of my changes to use sub/super registers on x86, but got nixed by Evan. See this thread: <a href="http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070730/052377.html">http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070730/052377.html</a></div></div></blockquote><div><br class="webkit-block-placeholder"></div><div>Ok, I didn't remember that.</div><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">The point that Evan made is that implicit zeroing of the upper part of the superregister is target specific to x86-64, thus target independent subreg instructions don't properly capture this behavior.</span></div></div></blockquote><div><br class="webkit-block-placeholder"></div><div>I agree with that.  Subregs (by themselves) really talk about reading/writing to a sub/superset of another register.  The strange thing here is that the operation actually changes all 64 bits, not just the 32 bits being targeted.</div><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">My argument was/is for having a single input form of insert_subreg which is explicitly there to capture target dependent semantics. The target independent machinery is then free to operate on that single input insert_subreg the same way across all platforms (it could be insert into undef, insert into zero, insert into all ones), but the legality of its usage is up to the specific code generator.</span></div></div></blockquote><div><br class="webkit-block-placeholder"></div><div>I'm not sure exactly what you mean, but generally it's good for nodes to have well defined semantics independent of the target.  Of course, this could be done by saying that insert_subreg takes an immediate value to indicate which form it is, and only some forms are valid.  I'm not sure how it simplifies this though.</div><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><span class="Apple-style-span" style="-webkit-text-stroke-width: -1; ">Today this single input form of insert_subreg exists, but is unused. Would it be better if were a separate node, rather than being treated differently based on the number of operands?</span></div></div></blockquote><div><br class="webkit-block-placeholder"></div><div>I'm really not a guru on this sort of stuff.  I am somewhat dissatisfied with both ppc64 and x86-64, which have to duplicate a number of 32-bit register operation forms when operating on the "low part of a 64-bit register".  However, I'm not sure I know a better way to model this.</div><div><br class="webkit-block-placeholder"></div><div>Can you give a concrete example of how this would play out, using 'mov' below as an example?  Basically in svn today we now have 2 copies of 32-bit mov, which codegen to the same instruction, but are matched at isel time in two different ways.  How would your solution change this?</div><div><br></div><div><br class="webkit-block-placeholder"></div><div>Right now we have:</div><div><br class="webkit-block-placeholder"></div><div><div><font class="Apple-style-span" face="Courier">def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),</font></div><div><font class="Apple-style-span" face="Courier">                "mov{l}\t{$src, $dst|$dst, $src}", []>;</font></div><div>and:</div><div><br class="webkit-block-placeholder"></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">def PsAND64rrFFFFFFFF</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">  : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">      "mov{l}\t{${src:subreg32}, ${dst:subreg32}|${dst:subreg32}, ${src:subreg32}}",</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">      [(set GR64:$dst, (and GR64:$src, i64immFFFFFFFF))]>;</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br class="webkit-block-placeholder"></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">One very simple and nice thing we could do is replace the duplicated instruction with a Pat pattern.  This would mean that there is only one instruction and the magic just happens in the isel.  This would give us something like this:</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br class="webkit-block-placeholder"></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">def : Pat<(and GR64:$src, i64immFFFFFFFF),</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">          (x86_64_bit_part_of_32_bit</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">             (MOV32rr (subreg GR64:$src, x86_32bit_part_of_64bit)))>;</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier"><br class="webkit-block-placeholder"></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font class="Apple-style-span" face="Courier">This puts more pressure on the coalescer to coalesce away the copies, but seems like an overall better solution.  Is this the sort of thing you mean?</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><br></div></div></div></div><div>-Chris</div></div><br></body></html>