llvm.noalias patches

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 10 13:40:30 PDT 2016


On Mon, Jul 11, 2016 at 1:54 AM, Hal Finkel <hfinkel at anl.gov> wrote:

> Hi again,
>
> 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.
>
> 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:
>
> void foo(int *a) {
>   int *restrict r = a;
>   *r++ = 1;
>   *r++ = 2;
>   --r;
>   *r = 3;
> }
>
> With the Clang CodeGen patch, the resulting IR looks like this (after
> optimization):
>
> define void @foo(i32* nocapture %a) local_unnamed_addr #0 {
> entry:
>   %0 = tail call i32* @llvm.noalias.p0i32(i32* %a, metadata !1)
>   %incdec.ptr = getelementptr inbounds i32, i32* %0, i64 1
>   %1 = tail call i32* @llvm.noalias.p0i32(i32* %incdec.ptr, metadata !1)
>   store i32 1, i32* %0, align 4, !tbaa !4, !noalias !1
>   %incdec.ptr1 = getelementptr inbounds i32, i32* %1, i64 1
>   %2 = tail call i32* @llvm.noalias.p0i32(i32* %incdec.ptr1, metadata !1)
>   store i32 2, i32* %1, align 4, !tbaa !4, !noalias !1
>   %incdec.ptr2 = getelementptr inbounds i32, i32* %2, i64 -1
>   %3 = tail call i32* @llvm.noalias.p0i32(i32* %incdec.ptr2, metadata !1)
>   store i32 3, i32* %3, align 4, !tbaa !4, !noalias !1
>   ret void
> }
>
> which yields this:
>
>   NoAlias:   store i32 2, i32* %1, align 4, !tbaa !4, !noalias !1 <->
>  store i32 1, i32* %0, align 4, !tbaa !4, !noalias !1
>   NoAlias:   store i32 3, i32* %3, align 4, !tbaa !4, !noalias !1 <->
>  store i32 1, i32* %0, align 4, !tbaa !4, !noalias !1
>   NoAlias:   store i32 3, i32* %3, align 4, !tbaa !4, !noalias !1 <->
>  store i32 2, i32* %1, align 4, !tbaa !4, !noalias !1
>
> 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.



> 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).


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?

define void @foo(i32* nocapture %a) {
entry:
  br i1 <something> label %if,  label %else
if:
  %foo = llvm.noalias(%a, !1)
  br label %merge
else:
  %bar = llvm.noalias(%a, !2)
  br label %merge
merge:
  baz = phi(%foo, %bar)
<use of baz>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160711/cdf5ddf4/attachment.html>


More information about the llvm-commits mailing list