<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 24, 2015 at 5:31 PM, Daniel Berlin <span dir="ltr"><<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">So, this is an awfully specific redundancy to detect in GVN.<div><br>The more general case doesn't use select's but phi's, and is tested in gcc with GVNPRE with testcases like:</div><div><br><br></div><div><div> int</div><div> foo (int i)</div><div> {</div><div>     int a, b;</div><div>     if (i)</div><div>         a = 3, b = 2;</div><div>     else</div><div>         a = 2, b = 3;</div><div>     return a + b;</div><div> }</div></div><div><br></div><div>and more complex testcase that involve expressions.</div><div>But the basic idea is the same - if both values are computed already, the end is redundant.</div><div>(here, the result is constant along both edges)<br></div><div><br></div>GVN doesn't touch this (and wouldn't with your patch):<br><br><div> ; Function Attrs: nounwind readnone ssp uwtable</div><div> define i32 @foo(i32 %i) #0 {</div><div>   %1 = icmp eq i32 %i, 0</div><div>   %. = select i1 %1, i32 2, i32 3</div><div>   %.1 = select i1 %1, i32 3, i32 2</div><div>   %2 = add nsw i32 %., %.1</div><div>   ret i32 %2</div><div> }</div><div><br></div><div><br></div><div>GCC treats this as a GVNPRE problem rather than a GVN one, because it involves computing available values along edges.</div><div><br></div><div>Putting these as selects, sadly, makes it harder for things like PRE to see this (though you could treat the selects are false blocks with incoming edges) </div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>It would compute the values are available along each edge already, and insert a no-cost phi to merge them.</div><div><br></div></div></blockquote><div>In particular, if PRE saw this as</div><div><br></div><div>a = load gep_ptr_a</div><div>b = load gep_ptr_b</div><div><br></div><div>br cond, A, B</div><div><br></div><div>block  A</div><div>c = gep_ptr a</div><div>goto C</div><div><br></div><div>block B</div><div>d = gep_ptr b</div><div>goto C</div><div><br></div><div>block C</div><div>e = phi(c, d)</div><div>load e</div><div><br></div><div><br></div><div>It should *already* insert a phi that merges (a, b) and uses it to replace load e, without you doing anything.</div><div><br></div><div>(or at least, GVN-PRE definitely will).</div><div><br></div></div></div></div>