<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 15, 2016 at 6:45 PM, 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">hfinkel added a comment.<br>
<span class=""><br>
In <a href="https://reviews.llvm.org/D9375#516105" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D9375#516105</a>, @dberlin wrote:<br>
<br>
> > 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.<br>
><br>
><br>
> Sorry, i misunderstood.<br>
>  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.<br>
<br>
<br>
</span>Looks that way.<br>
<span class=""><br>
> But that leads me to the other question:<br>
<br>
>  What control dependence does it have that requires it be marked as argmemonly and not "readnone"?<br>
<br>
>  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 :)<br>
<br>
><br>
<br>
> So what am i missing?<br>
<br>
<br>
</span>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):<br>
<br>
> 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:<br>
<br>
><br>
<br>
>   void foo(float * restrict a, float * restrict b) {<br>
<span class=""><br>
>     for (int i = 0; i < 1600; ++i)<br>
<br>
</span>>       a[i] = b[i] + 1;<br>
<br>
>   }<br>
<br>
><br>
<br>
> and:<br>
<br>
><br>
<br>
>   void inner(float * restrict a, float * restrict b, int i) {<br>
<br>
>     a[i] = b[i] + 1;<br>
<br>
>   }<br>
<br>
>   void foo(float * a, float * b) {<br>
<span class=""><br>
>     for (int i = 0; i < 1600; ++i)<br>
<br>
</span>>       inner(a, b);<br>
<br>
>   }<br>
<br>
><br>
<br>
> 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:<br>
<br>
><br>
<br>
> 1. Does access A alias with access B, both in loop L, within a loop iteration<br>
<br>
> 2. Does access A alias with the memory accessed by B is any loop iteration<br></blockquote><div><br></div><div>These are two very different use cases (one is basically aliasing, and the other is loop dependence analysis).</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
After inlining, the only difference here is that, the two noalias intrinsics:<br>
<br>
%... = @llvm.noalias(%a, !scope)<br>
%... = @llvm.noalias(%b, !scope)<br>
<br>
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. </blockquote><div><br></div><div>IMHO, i would separate these use cases into separate intrinsics.  One which takes loop info as a parameter (and answers one question), the other does not (the current noalias).</div><div><br></div><div>The one without loop info, can be readnone.</div><div>The with loop info, we figure that out :)</div><div><br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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.<br>
<br>
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.<br>
<br>
<br>
<a href="https://reviews.llvm.org/D9375" rel="noreferrer" target="_blank">https://reviews.llvm.org/D9375</a><br>
<br>
<br>
<br>
</blockquote></div><br></div></div>