<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 20, 2016 at 9:56 AM, Kevin Choi via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div>Hello to whom this may concern,<br><br></div>Versioned this as I saw identical title before. I'm compiling a clang project where I'm seeing GVN mess up and replace a load with a wrong def value.</div></div></div></div></div></div></div></div></blockquote><div><br></div><div><br>Do you have a c testcase or a .ll file i can actually compile?<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div> I am using LLVM-3.5, but the problem has been observed upto 3.8.<br>To illustrate the problem,<br><br></div><div>define i32 @main<br></div><a href="http://scalar.ph" target="_blank">scalar.ph</a>:<br></div>    <initialize [80 x i16] %dest><br>...<br></div><div>preheader:<br></div><div>%index=0<br></div><div>br test, loop1, bb2<br></div>loop1:<br></div>  ... write to %dest in increasing index // ptr-based while loop<br></div><div>  %ptr++;<br></div>  br test, loop1, bb2<br></div><div>bb2:<br></div><div>  %lcssa = phi [%ptr, loop1], [%ptr, preheader]<br>  store i16 0, i16* %lcssa !dbg !20094 !tbaa 20030  // write null byte at end<br></div><div>  %76 = getelementptr inbounds [80 x i16]* %dest, i64 0, i64 7, !dbg !20095 // load addr of null byte (7th index)<br>  %77 = load i16* %76, align 2, !dbg !20095, !tbaa !20010<br>  %78 = icmp eq i16 %77, 0, !dbg !20095<br>  br i1 %78, label %80, label %79, !dbg !20095<br><br></div><div>GVN calls processNonLocalLoad() on "%77 = load..." and replaces it with init value from <a href="http://scalar.ph" target="_blank">scalar.ph</a>.<br><br></div></div></div></blockquote><div><br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>bb2:<br>%lcssa = phi [%ptr, loop1], [%ptr, preheader]<br>store i16 0, i16* %lcssa, !dbg !20094, !tbaa !20030<br>%76 = getelementptr inbounds [80 x i16]* %dest, i64 0, i64 7, !dbg !20095<br>br i1 icmp eq (i16 trunc (i128 lshr (i128 bitcast (<8 x i16> <i16 120, i16 120, i16 120, i16 120, i16 120, i16 120, i16 120, i16 120> to i128), i128 96) to i16), i16 0), label %78, label %77, !dbg !20095  // simplifies to "icmp eq (i16 120, i16 0) --> false"<br><br></div><div>I first suspected problem might be TBAA; invoking clang with -fno-strict-aliasing makes the test pass (similarly, opt with -basicaa does not make GVN transform the load). When I look at the C/C++ source code, I cannot find any type-based aliasing violations from eyeballing.<br></div></div></div></blockquote><div><br></div><div>Can you excerpt the actual source code? </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><br></div><div>I started looking at the aliasing and landed at getNonLocalPointerDepFromBB(), in which the worklist algorithm to find MemDep reported the result from the init block, ignoring all the kills after it. I did see one of the parm was SkipFirstBlock and this appears to ignore the store %ptr above the load. Is there a reason why it skips first block?</div></div></div></blockquote><div><br></div><div><br></div><div>Yes. It is looking for *non-local* dependences.  The block it should skip is bb2, not loop1.</div><div>There is another call for local dependences.  If you ask for local dependences, then non-local ones, as GVN does, there is no point in having it go and look at the local ones again :)</div><div><br></div><div>Look at how GVN calls this:</div><div><div><div>MemDepResult Dep = MD->getDependency(L);</div><div><br></div><div>   // If it is defined in another block, try harder.</div><div>   if (Dep.isNonLocal())</div><div>     return processNonLocalLoad(L);</div></div></div><div><br></div><div>(IE get local dependence, if there is none, go looking at non-local dependences).</div><div><br></div><div><br></div><div>The list of non-local dependences it includes should definitely include the one from block "loop1", and if it is ignoring it, it is most likely thinks it does not alias for some reason.</div><div><br></div></div></div></div>