<div dir="ltr"><div>I think it would make sense for (1) and (2). I am not sure if (3) is feasible in <span style="font-size:12.8000001907349px">instcombine</span>. (I am not too familiar with LoopInfo)<br></div><div><br></div><div>For the Octasic's Opus platform, I modified shouldMergeGEPs in our fork to:</div><div><br></div><div><div>  if (GEP.hasAllZeroIndices() && !Src.hasAllZeroIndices() &&</div><div>      !Src.hasOneUse())</div><div>    return false;</div><div><br></div><div>  return Src.hasAllConstantIndices(); // was return false;<br></div></div><div><br></div><div>Following that change, I noticed some performance gain for a few specific tests and no regression at all in our (admittedly limited) benchmarks suite.</div><div><br></div><div><span style="font-size:12.8000001907349px">Regards,</span></div><div>Francois Pichet, Octasic.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 12, 2015 at 4:14 PM, Mark Heffernan <span dir="ltr"><<a href="mailto:meheff@google.com" target="_blank">meheff@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Coincidentally, I just ran into this same issue on some of our benchmarks for the NVPTX backend.  You have something like this before instcombine:<div><br></div><div>  %tmp = getelementptr inbounds i32, i32* %input, i64 %offset<br></div><div>loop:<br></div><div>  %loop_variant = ...</div><div>  %ptr = getelementptr inbounds i32, i32* %tmp, i64 %loop_variant</div><div><br></div><div>Which gets transformed to:</div><div><br></div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">loop:<br></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">  %loop_variant = ...</div><div style="text-align:start;text-indent:0px">  %sum = add nsw i64 %loop_variant, %offset<br></div><div style="text-align:start;text-indent:0px">  %ptr = getelementptr inbounds i32, i32* %input, i64 %sum<br></div><div style="text-align:start;text-indent:0px"><br></div><div style="text-align:start;text-indent:0px">The merge essentially reassociates the loop-variant term (%loop_variant) and loop-invariant terms (%input and %offset) in such a way that LICM can't remove it.<br></div></div><div><div><br></div><div>One idea is to only perform this style of gep merge if at least one of the following conditions is true:</div><div>(1) both index terms in the GEP  are constant.  In this case no new add instruction is created, instead the constants are folded.</div><div>(2) the GEPs are in the same BB.</div><div>(3) LoopInfo is available, and we know we're not creating a new instruction in a (deeper) loop.<br></div><div><br></div><div>What do you think?</div><span class=""><font color="#888888"><div><br></div><div>Mark</div><div><br></div></font></span></div></div>
</blockquote></div><br></div></div>