<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, May 3, 2015 at 9:57 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</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"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Sun, May 3, 2015 at 6:26 PM, Nicholas White <span dir="ltr"><<a href="mailto:n.j.white@gmail.com" target="_blank">n.j.white@gmail.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">Hi - I've got a question about what optimizations the "inbounds"<br>
keyword of "getelementptr" allows you to use. In the code below, %five<br>
is loaded from and inbounds offset of either a null pointer or %mem:<br>
<br>
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"<br>
<br>
define i8 @func(i8* %mem) {<br>
%test = icmp eq i8* %mem, null<br>
br i1 %test, label %done, label %mem.is.valid<br>
mem.is.valid:<br>
%1 = getelementptr inbounds i8, i8* %mem, i64 4<br>
store i8 5, i8* %1, align 4<br>
br label %done<br>
done:<br>
%after.phi = phi i8* [ %mem, %mem.is.valid ], [ null, %0 ]<br>
%2 = getelementptr inbounds i8, i8* %after.phi, i64 4<br>
%five = load i8, i8* %2, align 4<br>
ret i8 %five<br>
}<br>
<br>
According to the documentation, "the result value of the getelementptr<br>
is a poison value if the base pointer is not an in bounds address of<br>
an allocated object", so does this mean it's valid to optimise the<br>
function to:<br>
<br>
define i8 @func(i8* %mem) {<br>
%test = icmp eq i8* %mem, null<br>
br i1 %test, label %done, label %mem.is.valid<br>
mem.is.valid:<br>
ret i8 5<br>
done:<br>
ret i8 undef<br>
}<br>
<br>
Or even this:<br>
<br>
define i8 @func(i8* %mem) {<br>
ret i8 5<br>
}<br></blockquote><div><br></div></div></div><div>No, neither are semantics preserving because there exists no store to '%mem'.</div><div><br></div><div>Let's start by hoisting both sides of the branch into the entry block. This will leave you with:</div><div><span class=""><div>define i8 @func(i8* %mem) {</div><div> %test = icmp eq i8* %mem, null</div></span><div> %after.phi = select i1 %test, i8* null, %mem</div><span class=""><div> %1 = getelementptr inbounds i8, i8* %mem, i64 4<br></div><div> store i8 5, i8* %1, align 4</div>
</span><span class=""><div> %2 = getelementptr inbounds i8, i8* %after.phi, i64 4<br></div><div> %five = load i8, i8* %2, align 4</div><div> ret i8 %five</div><div>}</div></span></div><div><br></div><div>The SSA value '%after.phi' can be trivially simplified to '%mem', this leaves us with:</div><div><div>define i8 @func(i8* %mem) {</div><span class=""><div> %1 = getelementptr inbounds i8, i8* %mem, i64 4</div><div> store i8 5, i8* %1, align 4</div></span><div> %2 = getelementptr inbounds i8, i8* %mem, i64 4</div><span class=""><div> %five = load i8, i8* %2, align 4</div><div> ret i8 %five</div><div>}</div></span></div><div><br></div><div>The SSA values '%1' and '%2' are equivalent, this leaves us with:</div><div><div>define i8 @func(i8* %mem) {</div><span class=""><div> %1 = getelementptr inbounds i8, i8* %mem, i64 4</div><div> store i8 5, i8* %1, align 4</div></span><div> ret i8 5</div><div>}</div></div><div><br></div><div>I do not believe further simplification is possible.</div></div></div></div></blockquote><div><br></div><div>One final point that I forgot to mention: the transformations that I performed did not rely on the presence of 'inbounds'.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><div><br></div><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">
<br>
...? This is a reduced example of something I saw while running "opt"<br>
on a test case that missed a null check. Thanks -<br>
<br>
Nick<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></span></div><br></div></div>
</blockquote></div><br></div></div>