<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><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><br></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="mailto: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"><div dir="ltr"><br><br><div class="gmail_quote"><div><div class="h5">On Fri, Mar 13, 2015 at 2:54 PM Daniel Berlin <<a href="mailto: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="mailto: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>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">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><br></div>