<div dir="auto"><div>Thanks! That looks like a winning approach.</div><div dir="auto"><br></div><div dir="auto">I swear I grepped around for ISD::Constant but for some reason never found this code. I think maybe I was searching for ISD::Constant with setOperationAction, which in hindsight was narrowing down my search to just lowering, which is exactly what I didn't want! (I was looking for other approaches). I also tried looking in depth at PowerPC but it looks like it doesn't use this approach either.<div dir="auto"><br></div><div dir="auto">-- Sean Silva</div><br><div class="gmail_extra" dir="auto"><br><div class="gmail_quote">On Dec 24, 2017 12:16 AM, "Alex Bradbury" <<a href="mailto:asb@asbradbury.org">asb@asbradbury.org</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 24 December 2017 at 04:43, Sean Silva via llvm-dev<br>
<div class="quoted-text"><<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
> Thanks, that sounds like it would work. Was this based on what any other<br>
> target did? Or do any other targets take this approach?<br>
><br>
> I just want to make sure that we don't already have a hook suitable for<br>
> this. Overriding runOnFunction to run what could be described as just a<br>
> "late SelectionDAG pass" sounds pretty intrusive. Do you remember other<br>
> approaches that didn't work?<br>
<br>
</div>An obvious approach that doesn't work: just writing a pattern. This<br>
causes assertions, seemingly as some code paths don't like the<br>
introduction of a physical register.<br>
<br>
At least AArch64, Lanai, and RISC-V handle the zero register in<br>
TgtDAGToDAGISel::Select. Lanai also has a "-1" register and handles<br>
that case in the same place.<br>
<br>
Copying from LanaiDAGToDAGISel::Select:<br>
<br>
  EVT VT = Node->getValueType(0);<br>
  switch (Opcode) {<br>
  case ISD::Constant:<br>
    if (VT == MVT::i32) {<br>
      ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node);<br>
      // Materialize zero constants as copies from R0. This allows the coalescer<br>
      // to propagate these into other instructions.<br>
      if (ConstNode->isNullValue()) {<br>
        SDValue New = CurDAG->getCopyFromReg(CurDAG-<wbr>>getEntryNode(),<br>
                                             SDLoc(Node), Lanai::R0, MVT::i32);<br>
        return ReplaceNode(Node, New.getNode());<br>
      }<br>
      // Materialize all ones constants as copies from R1. This allows the<br>
      // coalescer to propagate these into other instructions.<br>
      if (ConstNode->isAllOnesValue()) {<br>
        SDValue New = CurDAG->getCopyFromReg(CurDAG-<wbr>>getEntryNode(),<br>
                                             SDLoc(Node), Lanai::R1, MVT::i32);<br>
        return ReplaceNode(Node, New.getNode());<br>
      }<br>
    }<br>
    break;<br>
<br>
<br>
<br>
Best,<br>
<br>
Alex<br>
</blockquote></div><br></div></div></div>