<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 11, 2016 at 1:54 AM, Hal Finkel <span dir="ltr"><<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</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">Hi again,<br>
<br>
Thanks to David Majnemer for reviewing many of the patches. David made an important observation: Instead of making the "looking through the intrinsic" logic about the llvm.noalias intrinsic specifically, we could add the 'returned' attribute to the relevant parameter and make the patches about looking through calls with a 'returned' parameter. I like this approach much better, and I'll rework the patches to do this. Also, we don't seem to infer the returned attribute; I'll post a patch for that too.<br>
<br>
Another change I need to make is that I need to add a second metadata parameter to the intrinsic, analogous to the alias.scope metadata we have currently. While the semantics as they stand are fine, they're not completely sufficient for representing local restrict-qualified pointers in C where the pointer variable itself is updated. For example, if we have:<br>
<br>
void foo(int *a) {<br>
  int *restrict r = a;<br>
  *r++ = 1;<br>
  *r++ = 2;<br>
  --r;<br>
  *r = 3;<br>
}<br>
<br>
With the Clang CodeGen patch, the resulting IR looks like this (after optimization):<br>
<br>
define void @foo(i32* nocapture %a) local_unnamed_addr #0 {<br>
entry:<br>
  %0 = tail call i32* @llvm.noalias.p0i32(i32* %a, metadata !1)<br>
  %incdec.ptr = getelementptr inbounds i32, i32* %0, i64 1<br>
  %1 = tail call i32* @llvm.noalias.p0i32(i32* %incdec.ptr, metadata !1)<br>
  store i32 1, i32* %0, align 4, !tbaa !4, !noalias !1<br>
  %incdec.ptr1 = getelementptr inbounds i32, i32* %1, i64 1<br>
  %2 = tail call i32* @llvm.noalias.p0i32(i32* %incdec.ptr1, metadata !1)<br>
  store i32 2, i32* %1, align 4, !tbaa !4, !noalias !1<br>
  %incdec.ptr2 = getelementptr inbounds i32, i32* %2, i64 -1<br>
  %3 = tail call i32* @llvm.noalias.p0i32(i32* %incdec.ptr2, metadata !1)<br>
  store i32 3, i32* %3, align 4, !tbaa !4, !noalias !1<br>
  ret void<br>
}<br>
<br>
which yields this:<br>
<br>
  NoAlias:   store i32 2, i32* %1, align 4, !tbaa !4, !noalias !1 <->   store i32 1, i32* %0, align 4, !tbaa !4, !noalias !1<br>
  NoAlias:   store i32 3, i32* %3, align 4, !tbaa !4, !noalias !1 <->   store i32 1, i32* %0, align 4, !tbaa !4, !noalias !1<br>
  NoAlias:   store i32 3, i32* %3, align 4, !tbaa !4, !noalias !1 <->   store i32 2, i32* %1, align 4, !tbaa !4, !noalias !1<br>
<br>
but that's not correct. The common case is that a restrict-qualified pointer is initialized once and then used as a base pointer for further computations. However, nothing prevents updating the pointer variable to point to an object it pointed to previously. </blockquote><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">The rule, as it stands, is that an access with a noalias scope using a pointer based on the intrinsic's return value (with a compatible scope parameter) does not alias with an access using a pointer with a compatible noalias scope not based on the intrinsics's return value. With a second metadata parameter, this will grow to be: ... not based on the return value from any intrinsic with the same second metadata parameter (the alias.scope parameter).</blockquote><div><br></div><div>Out of curiosity (and we may have talked about this a year ago), is this valid, and if so, what is the noalias status of the phi'd variable?<br><br></div><div>define void @foo(i32* nocapture %a) {</div><div>entry:<br></div><div>  br i1 <something> label %if,  label %else</div><div>if:<br></div><div>  %foo = llvm.noalias(%a, !1)</div><div>  br label %merge</div><div>else:<br>  %bar = llvm.noalias(%a, !2)</div><div>  br label %merge</div><div>merge:<br>  baz = phi(%foo, %bar)<br><use of baz><br></div><div><br></div></div></div></div>