[PATCH] D9375: An llvm.noalias intrinsic

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 15 18:45:28 PDT 2016


hfinkel added a comment.

In https://reviews.llvm.org/D9375#516105, @dberlin wrote:

> > In this example the indexing is simple and we'd get the (lack of) aliasing anyway, but in the general case the problem is that we lose which pointer values are derived from one restrict pointer and which are derived from the other once we inline. That's why I have @llvm.noalias return a value.
>
>
> Sorry, i misunderstood.
>  I thought you were saying that llvm.noalias *still* has this problem, in the current implementation, and, as i think i pointed out, it should not, *because* it returns a value.  It seems like we are in violent agreement.


Looks that way.

> But that leads me to the other question:

>  What control dependence does it have that requires it be marked as argmemonly and not "readnone"?

>  I don't see any tests attached where it would change the semantics if they were hoisted to wherever, and i don't see how they could be DSE'd/DCE'd if the pointers themselves are not dead :)

> 

> So what am i missing?


There are no tests because I can't write them yet ;) -- But this certainly a good point, and definitely a good thing to discuss. This goes back to an earlier part of the description (which I've edited a bit to make the point more explicit):

> To summarize from the llvmdev e-mail, the problem underlying (1) is that, when using the existing metadata scheme, we cannot differentiate between these two after inlining:

> 

>   void foo(float * restrict a, float * restrict b) {

>     for (int i = 0; i < 1600; ++i)

>       a[i] = b[i] + 1;

>   }

> 

> and:

> 

>   void inner(float * restrict a, float * restrict b, int i) {

>     a[i] = b[i] + 1;

>   }

>   void foo(float * a, float * b) {

>     for (int i = 0; i < 1600; ++i)

>       inner(a, b);

>   }

> 

> and we currently cheat and assume the former to enable vectorization. This is not correct, however, and the underlying issue is that the current scheme cannot differentiate directly between:

> 

> 1. Does access A alias with access B, both in loop L, within a loop iteration

> 2. Does access A alias with the memory accessed by B is any loop iteration


After inlining, the only difference here is that, the two noalias intrinsics:

%... = @llvm.noalias(%a, !scope)
%... = @llvm.noalias(%b, !scope)

will, in the first case, be outside the loop and, in the second case, be inside the loop. There's no other difference, but I need to be able to distinguish them in order to correctly answer the queries the vectorizer wants to make. The vectorizer needs to be able to do alias(a[i], b[i], L), where L is the loop, and the associated MemLocs have sizes that are infinite (or corresponding somehow to the entire range of indices), instead of just referring to the individual accesses. If the intrinsics can be hosted out of loops, then this won't work.

I can't write a test for this yet because we have no such interface yet. Proposing that is what I plan for the next step. Maybe we'll think of a better way, and we can make the intrinsics readnone.


https://reviews.llvm.org/D9375





More information about the llvm-commits mailing list