<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. 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">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">scalar.ph</a>.<br><br>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><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? Shouldn't it look at the preceding instructions in the same block as they could contain kill points? I am still unfamiliar with the algorithm used here and would very much appreciate if someone could educate or point me towards right direction.<br><br></div><div>Regards,<br></div><div>Kevin<br></div></div></div>