<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>I'm trying something cunning/crazy with the stack - implementing it in a type of memory that can only be addressed via immediates.</div><div><br></div><div>I've got this mostly working. However, I came across a problem which I've been unable to work around: lowering the IR (even without any optimisations enabled) often requires the pattern:</div><div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">    </span>i32 = FrameIndex <n></div><div></div></div><div><font class="Apple-style-span" color="#000000"><font class="Apple-style-span" color="#006312"><br></font></font></div></div></blockquote></div></div></blockquote><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>It isn't appropriate to do this with the proposed stack memory - it doesn't make sense to move the address into a register, as it isn't possible to move that back to the domain of an immediate. So I conditionally disabled this instruction. But that leads to most programs failing to select the above pattern.</div></div></blockquote><div><font class="Apple-style-span" color="#006312"><br></font></div>Sounds like your load / store address selection routine isn't working like what you expected. </div><div><br></div></div></blockquote></div><br><div>Thanks for the reply. Unfortunately, this doesn't seem to be the problem.</div><div><br></div><div>I have the following definition for the frameIndex:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">  def frameIndex : Operand<i32>,</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">    ComplexPattern<i32 /*valueType*/, 1 /*numOperands*/,</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">                   "SelectFrameIndex" /*selectFunction*/,</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">                   [frameindex] /*rootNodes*/> {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">    let PrintMethod = "printFrameIndexOperand";</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">    let MIOperandInfo = (ops GPR);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">  }</div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><span class="Apple-style-span" style="font-family: Helvetica; font-size: medium; "><div>And the following selection code:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(200, 0, 162); ">  bool</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(67, 129, 135); ">  MyDAGToDAGISel<span style="color: #000000">::</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">  SelectFrameIndex(SDValue Op, SDValue <span style="color: #438187">N</span>, SDValue& Address) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">    <span style="color: #c800a2">if</span> (FrameIndexSDNode* FIN = dyn_cast<FrameIndexSDNode>(<span style="color: #438187">N</span>)) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(42, 90, 95); "><span class="Apple-style-span" style="color: rgb(0, 0, 0); ">      Address = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(200, 0, 162); "><font class="Apple-style-span" color="#000000">      </font>return<span style="color: #000000"> </span>true<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">    }</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(200, 0, 162); "><font class="Apple-style-span" color="#000000">    </font>return<span style="color: #000000"> </span>false<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; ">  }</div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div></div><div>In light of your comment, I tried extending this method to only allow cases where Op is ISD::LOAD or ISD::STORE. I found this made no difference to the behaviour. That was surprising, so I added code to print out each instruction seen by that method. And it turns out that all the operations were loads or stores anyway. So it must be later on that the conversion happens, which turns the operation into some form of indirect addressing.</div><div><br></div><div>To further explore the example I gave in my original email, I have an instruction matching the pattern:</div><div><br></div><div>  <span class="Apple-style-span" style="font-family: Monaco; font-size: 10px; ">[(set GPR:$dst, (select GPR:$sel, immOrGPR:$a, immOrGPR:$b))]</span></div><div><br></div><div>The target-independent IR (as shown in the original message):</div><div><br></div><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>define i32 @foo(i32 %cond, i32 %a, i32 %b) nounwind {</div><div>entry:</div><div>  %retval = alloca i32                            ; <i32*> [#uses=2]</div><div>  %cond.addr = alloca i32                         ; <i32*> [#uses=2]</div><div>  %a.addr = alloca i32                            ; <i32*> [#uses=2]</div><div>  %b.addr = alloca i32                            ; <i32*> [#uses=2]</div><div>  store i32 %cond, i32* %cond.addr</div><div>  store i32 %a, i32* %a.addr</div><div>  store i32 %b, i32* %b.addr</div><div>  %tmp = load i32* %cond.addr                     ; <i32> [#uses=1]</div><div>  %tobool = icmp ne i32 %tmp, 0                   ; <i1> [#uses=1]</div><div>  %tmp1 = load i32* %a.addr                       ; <i32> [#uses=1]</div><div>  %tmp2 = load i32* %b.addr                       ; <i32> [#uses=1]</div><div>  %cond3 = select i1 %tobool, i32 %tmp1, i32 %tmp2 ; <i32> [#uses=1]</div></div></div></blockquote><div><br></div><div>To me seems to be doing what I want - i.e. storing arguments 'a' and 'b' into local stack slots, then selecting between the values stored in those stack slots. This appears to be what is seen during selection - SelectFrameIndex(), as indicated above.</div><div><br></div><div>The normal debug output from the back-end shows that the target-independent IR gets lowered to a select between the addresses of the two argument stack slots, rather than their values. That's a nice optimisation in general, but isn't allowed here, hence leading to the:</div></div><div><br></div><div><div>  LLVM ERROR: Cannot yet select: 0x1811798: i32 = FrameIndex <3></div><div><br></div></div><div>What transforms are performed during selection? I think this is where I should be looking, but I'm a bit lost.</div><div><br></div><div>Any help would be greatly appreciated.</div><div><br></div><div>- Mark</div><div><br></div></span></span></font></div></div></body></html>