<div dir="ltr">I think that's a limitation of LLVM's current implementation of TBAA - it does not handle arrays inside structs, so must be conservative and return may-alias.<div><br></div><div>Oliver</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 4 Mar 2020 at 09:52, Tiwary, Siddharth <<a href="mailto:Siddharth.Tiwary@amd.com">Siddharth.Tiwary@amd.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">





<div lang="EN-US">
<div class="gmail-m_7130865506401423867WordSection1">
<p class="gmail-m_7130865506401423867msipheader251902e5" style="margin:0in 0in 0.0001pt"><span style="font-size:10pt;font-family:Arial,sans-serif;color:rgb(49,113,0)">[AMD Public Use]</span><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Hi Oliver,<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Thanks for the clarification, but please consider the following:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">For your point “TBAA doesn't have to consider overlap between different fields, because different fields are not allowed to overlap”. Basically, TBBA<u></u><u></u></p>
<p class="MsoNormal">is aggressive in ignoring alias between different field types of a struct. Now, consider below:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">#######################################################<u></u><u></u></p>
<p class="MsoNormal">struct P {<u></u><u></u></p>
<p class="MsoNormal">  float f1;<u></u><u></u></p>
<p class="MsoNormal">  float f2;<u></u><u></u></p>
<p class="MsoNormal">  float f3[3];<u></u><u></u></p>
<p class="MsoNormal">  float f4;<u></u><u></u></p>
<p class="MsoNormal">};<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><i>void foo(struct P* p1, struct P* p2) {<u></u><u></u></i></p>
<p class="MsoNormal"><i>  p1->f1 = 1.2;<u></u><u></u></i></p>
<p class="MsoNormal"><i>  p2->f3[0] = 3.7;<u></u><u></u></i></p>
<p class="MsoNormal"><i>}<u></u><u></u></i></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">int callFoo() {<u></u><u></u></p>
<p class="MsoNormal">  struct P p;<u></u><u></u></p>
<p class="MsoNormal">  foo(&p, &p);<u></u><u></u></p>
<p class="MsoNormal">  return 0;<u></u><u></u></p>
<p class="MsoNormal">}<u></u><u></u></p>
<p class="MsoNormal">#######################################################<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Using the TBAA for the above program yields the alias-set for
<i>foo</i>:<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><i>AliasSet[0x559a412391f0, 2] may alias, Mod       Pointers: (float* %f1, LocationSize::precise(4)), (float* %arrayidx, LocationSize::precise(4))<u></u><u></u></i></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">that is, there exists a may-alias between f1 and f3[] fields between two pointers to same structure type.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">It is observed that when a struct-field(scalar-field) of type T and another struct-field(array) of type T[] are accessed, LLVM’s Type based Alias Analysis<u></u><u></u></p>
<p class="MsoNormal">returns a may-alias. The field in the above context are f1 and f3[someIndx]. However, it does resolve aliasing between accesses to two scalar<u></u><u></u></p>
<p class="MsoNormal">struct-fields (scalars of type T, say f1 and f4), provided there is no access to the same struct’s field which is an array of same type(of type T[] here, say f3).<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Note that f3 is a static array in struct P and hence non-re-assignable, so p1->f3[anyIndex] can never alias with p1->f1. But TBAA becomes conservative here.<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Upon inferring that the two stores are to two different field types(static-array and scalar), shouldn’t TBAA rule out the aliasing?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
<p class="MsoNormal">Siddharth<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0in 0in">
<p class="MsoNormal"><b>From:</b> Oliver Stannard <<a href="mailto:oliver.stannard@linaro.org" target="_blank">oliver.stannard@linaro.org</a>> <br>
<b>Sent:</b> Tuesday, March 3, 2020 7:06 PM<br>
<b>To:</b> Tiwary, Siddharth <<a href="mailto:Siddharth.Tiwary@amd.com" target="_blank">Siddharth.Tiwary@amd.com</a>><br>
<b>Cc:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<b>Subject:</b> Re: [llvm-dev] TBAA for struct fields<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">[CAUTION: External Email] <u></u><u></u></p>
<div>
<div>
<div>
<p class="MsoNormal">> <span style="color:black">I get rid of the warnings by explicitly type-casting it to struct*, and still get similar results.</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">Adding the explicit cast suppresses the warning, but the behaviour of the code is still undefined according to the C (and C++) standard.
<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">> <span style="color:black">Shouldn’t any alias analysis(including TBAA) be conservative in interprocedural context, and consider all aliasing possibilities between different fields?</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">TBAA doesn't have to consider overlap between different fields, because different fields are not allowed to overlap.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">> <b><span style="color:black">For Clang, O1 onwards results are wrong!</span></b><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Since the behaviour of the source code is undefined, a compiler can generate any code it wants to, and be correct.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">If you really want to write code like this (though I'd strongly advise you not to, since it's not correct portable C), you can disable type-based alias analysis with the -fno-strict-aliasing clang option.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Oliver<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Tue, 3 Mar 2020 at 05:30, Tiwary, Siddharth <<a href="mailto:Siddharth.Tiwary@amd.com" target="_blank">Siddharth.Tiwary@amd.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt">
<div>
<p style="margin:15pt"><span style="font-size:10pt;font-family:Arial,sans-serif;color:rgb(49,113,0)">[AMD Public Use]<u></u><u></u></span></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">Hi Oliver,<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"><u></u> <u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">I get rid of the warnings by explicitly type-casting it to struct*, and still get similar results.<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">#######################################################<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">struct P {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f1;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f2;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f3[3];<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f4;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">};<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">void foo(struct P* p1, struct P* p2) {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  p1->f2 = 1.2;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  p2->f1 = 3.7;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">}<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">int callFoo() {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  struct P p;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  foo(&p, (struct P*)(&(p.f2)));<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  return 0;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">}<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">#######################################################<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">Shouldn’t any alias analysis(including TBAA) be conservative in interprocedural context, and consider all aliasing possibilities between different fields?
<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">As mentioned before, if instead of the above, p1->f2 and p2->f2 are the ones being accessed, then p1->f2 and p2->f2 are returned in same alias-sets.<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">So, in second case, it is indeed conservative. This too is in interprocedural context!<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">I ask this because as a result of the above, following happens:<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">##########################################<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">struct P {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f1;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f2;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f3[3];<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float f4;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">};<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">float foo(struct P* p1, struct P* p2) {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  float sum = 0;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  for( int i = 0; i < 1000; i++) {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">    sum += p1->f2;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">    p2->f1 += i*7;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  }<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  return sum;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">}<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">int callFoo() {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  struct P p;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  p.f1 = 3.0;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  p.f2 = 7.0;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  printf("foo = %f\n", foo(&p, (struct P*)&(p.f2)));<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  return 0;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">}<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">int main() {<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  callFoo();<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">  return 0;<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">}<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">###########################################<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">Clang O0 and gcc O0/O1/O2 give the same expected result.<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black"> <u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><b><span style="color:black">For Clang, O1 onwards results are wrong!</span></b><span style="color:black"> This is because the load and store get<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">hoisted and sinked in the loop in foo, respectively. That happens even though<u></u><u></u></span></p>
<p style="margin:0in 0in 0.0001pt;background:white"><span style="color:black">load(p1->f2) and store(p2->f1) are same address, but LLVM doesn’t find it.<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12pt;color:black"><u></u> <u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12pt;color:black">Thanks,<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12pt;color:black">Siddharth<u></u><u></u></span></p>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:12pt;color:black"><u></u> <u></u></span></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="98%" align="center">
</div>
<div id="gmail-m_7130865506401423867gmail-m_-5516881373014970105gmail-m_-6928860084797707650divRplyFwdMsg">
<p class="MsoNormal"><b><span style="color:black">From:</span></b><span style="color:black"> Oliver Stannard <<a href="mailto:oliver.stannard@linaro.org" target="_blank">oliver.stannard@linaro.org</a>><br>
<b>Sent:</b> Friday, February 28, 2020 4:55 PM<br>
<b>To:</b> Tiwary, Siddharth <<a href="mailto:Siddharth.Tiwary@amd.com" target="_blank">Siddharth.Tiwary@amd.com</a>><br>
<b>Cc:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a> <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] TBAA for struct fields</span> <u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal">[CAUTION: External Email] <u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">This is happening because there is undefined behaviour in your example. In C, a `struct P*` must point to the start of a `struct P`, so the compiler can assume references to two different members do not alias. In your example, you've constructed
 `p2` to point to the second member of the struct, which is not correct. <u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Clang reports this as a warning:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><i>######################################################</i><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">$ /work/llvm/build/bin/clang -fsyntax-only -c test.c<br>
test.c:15:11: warning: incompatible pointer types passing 'float *' to parameter of type 'struct P *' [-Wincompatible-pointer-types]<br>
  foo(&p, &(p.f2));<br>
          ^~~~~~~<br>
test.c:8:34: note: passing argument to parameter 'p2' here<br>
void foo(struct P *p1, struct P *p2) {<br>
                                 ^<br>
test.c:16:1: warning: non-void function does not return a value [-Wreturn-type]<br>
}<br>
^<br>
2 warnings generated.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><i>######################################################</i><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Oliver<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Fri, 28 Feb 2020 at 06:18, Tiwary, Siddharth via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt">
<div>
<p style="margin:0in 0in 0.0001pt"><span style="font-size:10pt;font-family:Arial,sans-serif;color:rgb(0,120,215)">[AMD Official Use Only - Internal Distribution Only]</span><u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p>Hi,<u></u><u></u></p>
<p> <u></u><u></u></p>
<p>Following issue is observed with Type Based Alias Analysis(TBAA).<u></u><u></u></p>
<p> <u></u><u></u></p>
<p>#######################################################<u></u><u></u></p>
<p><i>struct P {</i><u></u><u></u></p>
<p><i>  float f1;</i><u></u><u></u></p>
<p><i>  float f2;</i><u></u><u></u></p>
<p><i>  float f3[3];</i><u></u><u></u></p>
<p><i>  float f4;</i><u></u><u></u></p>
<p><i>};</i><u></u><u></u></p>
<p><i> </i><u></u><u></u></p>
<p><i>void foo(struct P* p1, struct P* p2) {</i><u></u><u></u></p>
<p><i>  p1->f2 = 1.2;</i><u></u><u></u></p>
<p><i>  p2->f1 = 3.7;</i><u></u><u></u></p>
<p><i>}</i><u></u><u></u></p>
<p><i> </i><u></u><u></u></p>
<p><i>int callFoo() {</i><u></u><u></u></p>
<p><i>  struct P p;</i><u></u><u></u></p>
<p><i>  foo(&p, &(p.f2));</i><u></u><u></u></p>
<p><i>}</i><u></u><u></u></p>
<p><i>######################################################</i><u></u><u></u></p>
<p> <u></u><u></u></p>
<p>Printing alias-sets using commands:<u></u><u></u></p>
<p> <u></u><u></u></p>
<p><i>  clang -O1 -S -emit-llvm struct_tbaa.c</i><u></u><u></u></p>
<p><i>  opt -basicaa -tbaa -print-alias-sets -disable-output struct_tbaa.ll</i><u></u><u></u></p>
<p> <u></u><u></u></p>
<p>yields:<u></u><u></u></p>
<p> <u></u><u></u></p>
<p><i>Alias sets for function 'foo':</i><u></u><u></u></p>
<p><i>Alias Set Tracker: 2 alias sets for 2 pointer values.</i><u></u><u></u></p>
<p><i>  AliasSet[0x563d8f6a8bd0, 1] must alias, Mod       Pointers: (i32* %f2, LocationSize::precise(4))</i><u></u><u></u></p>
<p><i>  AliasSet[0x563d8f6bc080, 1] must alias, Mod       Pointers: (float* %f1, LocationSize::precise(4))</i><u></u><u></u></p>
<p><i> </i><u></u><u></u></p>
<p>IR of foo:<u></u><u></u></p>
<p> <u></u><u></u></p>
<p><i>; Function Attrs: nofree norecurse nounwind uwtable writeonly</i><u></u><u></u></p>
<p><i>define dso_local void @foo(%struct.P* nocapture %p1, %struct.P* nocapture %p2) local_unnamed_addr #0 {</i><u></u><u></u></p>
<p><i>entry:</i><u></u><u></u></p>
<p><i>  %f2 = getelementptr inbounds %struct.P, %struct.P* %p1, i64 0, i32 1</i><u></u><u></u></p>
<p><i>  store float 0x3FF3333340000000, float* %f2, align 4, !tbaa !2</i><u></u><u></u></p>
<p><i>  %f1 = getelementptr inbounds %struct.P, %struct.P* %p2, i64 0, i32 0</i><u></u><u></u></p>
<p><i>  store float 0x400D9999A0000000, float* %f1, align 4, !tbaa !7</i><u></u><u></u></p>
<p><i>  ret void</i><u></u><u></u></p>
<p><i>}</i><u></u><u></u></p>
<p><i>!2 = !{!3, !4, i64 4}</i><u></u><u></u></p>
<p><i>!3 = !{!"P", !4, i64 0, !4, i64 4, !5, i64 8, !4, i64 20}</i><u></u><u></u></p>
<p><i>!4 = !{!"float", !5, i64 0}</i><u></u><u></u></p>
<p><i>!5 = !{!"omnipotent char", !6, i64 0}</i><u></u><u></u></p>
<p><i>!6 = !{!"Simple C/C++ TBAA"}</i><u></u><u></u></p>
<p><i>!7 = !{!3, !4, i64 0}</i><u></u><u></u></p>
<p><i> </i><u></u><u></u></p>
<p>TBAA returns p1->f2 and p2->f1 in different alias-sets. But p1->f2 and p2->f1 do actually have the same address!
<span style="font-size:10.5pt;font-family:"Segoe UI",sans-serif">Shouldn't the alias result be conservative while doing TBAA, especially when it needs interprocedural analysis?</span><u></u><u></u></p>
<p>If instead of the above, p1->f2 and p2->f2 are the ones being accessed, then p1->f2 and p2->f2 are returned in same alias-sets. So, in second case, it is indeed conservative!
<u></u><u></u></p>
<p> <u></u><u></u></p>
<p>Could someone please explain the rationale behind above behavior?<u></u><u></u></p>
<p> <u></u><u></u></p>
<p>Thanks,<u></u><u></u></p>
<p>Siddharth<u></u><u></u></p>
<p> <u></u><u></u></p>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.llvm.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fllvm-dev&data=02%7C01%7CSiddharth.Tiwary%40amd.com%7Ccfa64e3992be42b6641508d7bf77e497%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637188393972992227&sdata=RULMER98bPM2w73vOtMGRl415KmyqE9oyfb6gnnEQkQ%3D&reserved=0" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><u></u><u></u></p>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>

</blockquote></div>