<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 19, 2014, at 4:43 AM, Nicholas White <<a href="mailto:n.j.white@gmail.com" class="">n.j.white@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">> you just have to formulate your solution in terms of these facts:<br class=""><br class=""></div>Thanks - that helps a lot. I've updated <a href="http://reviews.llvm.org/D6682" class="">http://reviews.llvm.org/D6682</a> to use this, and the patch passes most of the BasicAA regression tests now. I've narrowed down the failures to the test case @based_on_pr18068 in the commit (reproduced below); basically it doesn't know that zext(%var + 1) != zext(%var) for all values of %var when the addition doesn't have the NUW flag set. As %var + 1 may wrap we can't decompose it into zext(%var) + zext(1) - i.e. if we tried to decompose zext(%var + 1) into zext(%var) + C then C could either be +1 or -zext(%var). As the current logic stores the offset in APInt it clearly can't deal with this situation. I'm thinking of allowing the offset to be a dummy unknown-but-non-zero number as well as an APInt, as this would cover the remaining cases. Thanks -<br class=""></div></div></blockquote><div><br class=""></div><div>Sure, you basically want some flag to indicate that the expression doesn't fully wrap back to the original value.</div><div class=""><br class=""></div><div class="">As far as your current patch goes, this looks like the right idea. There are a few things I'm unsure of...</div><div class=""><div class=""><br class=""></div><div class="">I think the vector of Extensions is confusing. If you only handle extension to a pointer-width, then you only need to remeber the last seen extension as you recurse upward.</div><div class=""><br class=""></div><div class="">For example, if all operations are nsw/nuw:</div><div class="">sext64(c1 + zext64(c2 + v)) => sext64(c1) + zext64(c2) + zext64(v)</div><div class=""><br class=""></div><div class="">That's because sext64(zext64(v)) == zext64(v)</div><div class=""><br class=""></div><div class="">If you're only handling extension to a pointer-width, only one extension can possible matter. I think handling extensions and truncations to/from arbitrary width would be way too complicated.</div><div class=""><br class=""></div><div class="">The places where you're zero-extending APInt are confusing to me. Why is this safe? Is it because you don’t actually care whether one index is greater or less than another, just that their difference is nonzero? Can you explain with comments?</div><div class=""><br class=""></div><div class="">+ Offset += Const->getValue().zextOrSelf(Offset.getBitWidth());</div></div><div class=""><br class=""></div><div class="">Andy</div><div class=""><br class=""></div><div class="">PS: I’ll be away for a couple weeks, but I’m fine if someone else signs off on the patch.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class="">Nick<br class=""><br class="">; CHECK-LABEL: based_on_pr18068<br class="">; CHECK: NoAlias: i8* %a, i8* %b<br class="">define void @based_on_pr18068(i32 %loaded, i8* %mem) {<br class="">  %loaded.64 = zext i32 %loaded to i64<br class="">  %add1 = add i32 %loaded, 1 ; unsigned wraps iff %loaded == 0xFFFFFFFF<br class="">  %add1.64 = zext i32 %add1 to i64 ; is zext(%loaded) always != zext(%loaded + 1)? Yes -> NoAlias<br class="">  %a = getelementptr inbounds i8* %mem, i64 %loaded.64<br class="">  %b = getelementptr inbounds i8* %mem, i64 %add1.64<br class="">  ret void<br class="">}<br class=""></div>
</div></blockquote></div><br class=""></body></html>