Reason is that I want this case to be supported by default, without specific flags (should we change the default AA for PPC if we do a separate one?).<div><br></div><div>Fixing at the Clang level might be the right thing to do... But if there are other cases like this, the traversal would definitely help in general to get a proper handling of restrict.</div><div><br></div><div>Olivier<span></span><br><br>On Sunday, March 15, 2015, Daniel Berlin <<a href="mailto:dberlin@dberlin.org">dberlin@dberlin.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote">On Sun, Mar 15, 2015 at 4:34 PM Olivier Sallenave <<a href="javascript:_e(%7B%7D,'cvml','ol.sall@gmail.com');" target="_blank">ol.sall@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Daniel,<div><br></div><div>Thanks for your feedback. I would prefer not to write a new AA. Can't we directly implement that traversal in BasicAA?</div></div></blockquote><div>Can I ask why?<br>Outside of the "well, it's another pass", i mean?<br><br></div><div>BasicAA is stateless, so you can't cache, and you really don't want to redo these walks repeatedly (especially when the answer doesn't change unless AA is invalidated).  It would be really expensive.</div><div>Doing this in a separate analysis pass, caching the answer, and producing AA results, seems to me exactly the right thing.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Otherwise, I'll investigate why this i64 was generated in the first place (but like you, I don't really want to know why :-)</div></div></blockquote><div><br></div><div>Reid walked over to my desk and told me all the gory details - the clang ABI lowering of  structs like these for anything but x86 basically says "oh, this  really should be 2 8 byte GPR's, and the way it makes this happen is by using i64's :)</div><div><br></div><div>If you want to do it at a clang level, the right thing to do is to fixup the ABI lowerings for pointers to keep them pointers in this case.</div><div><br></div><div>For something simpler, if you wanted, you could do the *exact* opposite of happens now and you'd get better results.</div><div><br></div><div>This is, pass everything that needs to be 2 8 byte regs as 8 byte pointers, and cast it back to something if it's not really a pointer, using ptrtoint.</div><div><br></div><div>if it's not really a pointer, we don't care what AA says about it.</div><div>If it is a pointer, now we don't get bad AA answers, because there is no inttoptr being used like there is now.<br></div><div><br></div><div>Of course, i have no idea if this strategy is going to produce correct ABI results on all platforms, it depends on whether they treat pointers as special.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div></div><div>Olivier</div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-03-13 18:51 GMT-04:00 Daniel Berlin <span dir="ltr"><<a href="javascript:_e(%7B%7D,'cvml','dberlin@dberlin.org');" target="_blank">dberlin@dberlin.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"></blockquote></div></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote"><div><div>On Fri, Mar 13, 2015 at 2:54 PM Daniel Berlin <<a href="javascript:_e(%7B%7D,'cvml','dberlin@dberlin.org');" target="_blank">dberlin@dberlin.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote">On Fri, Mar 13, 2015 at 2:39 PM Olivier H Sallenave <<a href="javascript:_e(%7B%7D,'cvml','ohsallen@us.ibm.com');" target="_blank">ohsallen@us.ibm.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<p><font face="sans-serif">Hi,</font><br>
<br>
<font face="sans-serif">I have the following C loop to vectorize:</font><br>
<br>
<font face="sans-serif">struct box {</font><br>
<font face="sans-serif">    double* source;</font><br>
<font face="sans-serif">};</font><br>
<br>
<font face="sans-serif">void test(double* restrict result, struct box my_struct, int len)</font><br>
<font face="sans-serif">{</font><br>
<font face="sans-serif">    for (int i=0 ; i<len; i++) {</font><br>
<font face="sans-serif">        result[i] = my_struct.source[i] * my_struct.source[i];</font><br>
<font face="sans-serif">    }</font><br>
<font face="sans-serif">}</font><br>
<br>
<font face="sans-serif">There are two references in the loop, result[i] (restrict) and my_struct.source[i] (readonly). The compiler should easily figure out that they do not alias.</font><br>
<br>
<font face="sans-serif">Compiling for x86, the loop alias analysis works just fine:</font><br>
<font face="sans-serif">  AST: Alias Set Tracker: 2 alias sets for 2 pointer values.</font><br>
<font face="sans-serif">  AliasSet[0x7fd8e2f32290, 1] must alias, No access Pointers: (double* %arrayidx5, 18446744073709551615)</font><br>
<font face="sans-serif">  AliasSet[0x7fd8e2f322e0, 1] must alias, No access Pointers: (double* %arrayidx, 18446744073709551615)</font><br>
<br>
<font face="sans-serif">Compilin</font><font face="sans-serif">g for PPC with -target powerpc64le-ibm-linux-gnu, the two addresses now alias:</font><br>
<font face="sans-serif">  AST: Alias Set Tracker: 1 alias sets for 2 pointer values.</font><br>
<font face="sans-serif">  AliasSet[0x7f931bd5bdc0, 2] may alias, No access Pointers: (double* %arrayidx5, 18446744073709551615), (double* %arrayidx, 18446744073709551615)</font><br>
<br>
<font face="sans-serif">BasicAA is used for both targets by default. The difference is that in PPC, the IR obtained from Clang takes an i64 as parameter instead of a double* for my_struct.</font></p></div></blockquote><div><br></div></div></div><div dir="ltr"><div class="gmail_quote"><div>I don't even want to know why this would be the case :)</div></div></div><div dir="ltr"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p><font face="sans-serif"> This parameter is then coerced into double* using an inttoptr instruction. The code in BasicAliasAnalysis.cpp which is triggered for x86 is the following:</font><br>
<br>
<font face="sans-serif">    </font><font face="sans-serif">// Function arguments can't alias with things that are known to be</font><br>
<font face="sans-serif">    </font><font face="sans-serif">// </font><font face="sans-serif">unambigously</font><font face="sans-serif"> identified at the function level.</font><br>
<font face="sans-serif">    </font><font face="sans-serif">if</font><font face="sans-serif"> </font><font face="sans-serif">((</font><font face="sans-serif">isa<Argument></font><font face="sans-serif">(</font><font face="sans-serif">O1</font><font face="sans-serif">)</font><font face="sans-serif"> </font><font face="sans-serif">&&</font><font face="sans-serif"> </font><font face="sans-serif">isId<u></u>entifiedFunctionLocal</font><font face="sans-serif">(</font><font face="sans-serif">O2</font><font face="sans-serif">))</font><font face="sans-serif"> </font><font face="sans-serif">||</font><br>
<font face="sans-serif">        </font><font face="sans-serif">(</font><font face="sans-serif">isa<Argument></font><font face="sans-serif">(</font><font face="sans-serif">O2</font><font face="sans-serif">)</font><font face="sans-serif"> </font><font face="sans-serif">&&</font><font face="sans-serif"> </font><font face="sans-serif">isIdenti<u></u>fiedFunctionLocal</font><font face="sans-serif">(</font><font face="sans-serif">O1</font><font face="sans-serif">)))</font><br>
<font face="sans-serif">      </font><font face="sans-serif">return</font><font face="sans-serif"> </font><font face="sans-serif">NoAlias</font><font face="sans-serif">;</font><br>
<br>
<font face="sans-serif">isIdentifiedFunctionLocal(V) returns true for a noalias argument (such as result), but the other address (my_struct) must be a function argument in order to return NoAlias, which is not the case anymore for PPC (since my_struct is now the result from an inttoptr instruction). If I understand, the problem is that we cannot trust the fact that locals do not alias with restrict parameters (because the compiler could generate some locals which alias)?</font></p></div></blockquote></div></div><div dir="ltr"><div class="gmail_quote"><div>Yes, because pointers *based on* the noalias'd argument are legal aliases.</div><div> <br></div><div>So if you don't know it's an argument or an identified local, it could be based on the restricted pointer, and thus, alias it.</div></div></div><div dir="ltr"><div class="gmail_quote"><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p><font face="sans-serif"> If someone has suggestions about this, that would help a lot.</font></p></div></blockquote></div></div><div dir="ltr"><div class="gmail_quote"><div><br>The only way you could prove something in this case would be to walk the chain and prove the value comes directly from an argument with no modification.</div></div></div></blockquote><div><br></div></div></div><div>Actually, you could do the opposite, too, pretty cheaply.</div><div><br></div><div>You could write a new pass or AA.</div><div>It traverses chains in the reverse direction (IE it goes from the arguments, and walks down the immediate use chain, marking things as based on arguments or not), and makes a lookup table of things it can prove are also  unmolested identified objects.</div><div>(which would be the result of inttoptr in your case).</div><div><br></div><div>You can then use this simple lookup table to answer the isIdentifiedObject question better.</div><div>(You'd have to make isIdentifiedObject part of the AA interface, or take an optional table, blah blah blah)</div><div><br></div></div></div>
<br></blockquote></div></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="javascript:_e(%7B%7D,'cvml','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>
<br></blockquote></div></div></blockquote></div></div>
</blockquote></div>