<div dir="ltr"><br><br><div class="gmail_quote">On Fri, Mar 13, 2015 at 2:39 PM Olivier H Sallenave <<a href="mailto:ohsallen@us.ibm.com">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>I don't even want to know why this would be the case :)</div><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">isIdentifiedFunctionLocal</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">isIdentifiedFunctionLocal</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>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><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><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><br></div><div>That is expensive to do in the general case, and inttoptr is generally not going to be wonderful for performance (for example, outside of BasicAA, more advanced AA's like CFL-AA will give up on anything that comes from or goes through ptrtoint/inttoptr). So what's the issue that makes you pass this as i64 in the first place?<br><br></div></div></div>