<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"Segoe UI";
        panose-1:2 11 5 2 4 2 4 2 2 3;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
p.msipheader251902e5, li.msipheader251902e5, div.msipheader251902e5
        {mso-style-name:msipheader251902e5;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="msipheader251902e5" style="margin:0in;margin-bottom:.0001pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:#317100">[AMD Public Use]</span><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi Oliver,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks for the clarification, but please consider the following:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></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<o:p></o:p></p>
<p class="MsoNormal">is aggressive in ignoring alias between different field types of a struct. Now, consider below:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">#######################################################<o:p></o:p></p>
<p class="MsoNormal">struct P {<o:p></o:p></p>
<p class="MsoNormal">  float f1;<o:p></o:p></p>
<p class="MsoNormal">  float f2;<o:p></o:p></p>
<p class="MsoNormal">  float f3[3];<o:p></o:p></p>
<p class="MsoNormal">  float f4;<o:p></o:p></p>
<p class="MsoNormal">};<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><i>void foo(struct P* p1, struct P* p2) {<o:p></o:p></i></p>
<p class="MsoNormal"><i>  p1->f1 = 1.2;<o:p></o:p></i></p>
<p class="MsoNormal"><i>  p2->f3[0] = 3.7;<o:p></o:p></i></p>
<p class="MsoNormal"><i>}<o:p></o:p></i></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">int callFoo() {<o:p></o:p></p>
<p class="MsoNormal">  struct P p;<o:p></o:p></p>
<p class="MsoNormal">  foo(&p, &p);<o:p></o:p></p>
<p class="MsoNormal">  return 0;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">#######################################################<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Using the TBAA for the above program yields the alias-set for
<i>foo</i>:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><i>AliasSet[0x559a412391f0, 2] may alias, Mod       Pointers: (float* %f1, LocationSize::precise(4)), (float* %arrayidx, LocationSize::precise(4))<o:p></o:p></i></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">that is, there exists a may-alias between f1 and f3[] fields between two pointers to same structure type.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></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<o:p></o:p></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<o:p></o:p></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).<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></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?<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal">Siddharth<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Oliver Stannard <oliver.stannard@linaro.org> <br>
<b>Sent:</b> Tuesday, March 3, 2020 7:06 PM<br>
<b>To:</b> Tiwary, Siddharth <Siddharth.Tiwary@amd.com><br>
<b>Cc:</b> llvm-dev@lists.llvm.org<br>
<b>Subject:</b> Re: [llvm-dev] TBAA for struct fields<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">[CAUTION: External Email] <o:p></o:p></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><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></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.
<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></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><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">TBAA doesn't have to consider overlap between different fields, because different fields are not allowed to overlap.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> <b><span style="color:black">For Clang, O1 onwards results are wrong!</span></b><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Oliver<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<p style="margin:15.0pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:#317100">[AMD Public Use]<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">Hi Oliver,<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"><o:p> </o:p></span></p>
<p style="margin:0in;margin-bottom:.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.<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">#######################################################<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">struct P {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f1;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f2;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f3[3];<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f4;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">};<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">void foo(struct P* p1, struct P* p2) {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  p1->f2 = 1.2;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  p2->f1 = 3.7;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">}<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">int callFoo() {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  struct P p;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  foo(&p, (struct P*)(&(p.f2)));<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  return 0;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">}<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">#######################################################<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.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?
<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.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.<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">So, in second case, it is indeed conservative. This too is in interprocedural context!<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">I ask this because as a result of the above, following happens:<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">##########################################<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">struct P {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f1;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f2;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f3[3];<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float f4;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">};<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">float foo(struct P* p1, struct P* p2) {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  float sum = 0;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  for( int i = 0; i < 1000; i++) {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">    sum += p1->f2;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">    p2->f1 += i*7;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  }<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  return sum;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">}<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">int callFoo() {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  struct P p;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  p.f1 = 3.0;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  p.f2 = 7.0;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  printf("foo = %f\n", foo(&p, (struct P*)&(p.f2)));<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  return 0;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">}<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">int main() {<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  callFoo();<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">  return 0;<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">}<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">###########################################<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">Clang O0 and gcc O0/O1/O2 give the same expected result.<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black"> <o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.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<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">hoisted and sinked in the loop in foo, respectively. That happens even though<o:p></o:p></span></p>
<p style="margin:0in;margin-bottom:.0001pt;background:white"><span style="color:black">load(p1->f2) and store(p2->f1) are same address, but LLVM doesn’t find it.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt;color:black">Thanks,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="font-size:12.0pt;color:black">Siddharth<o:p></o:p></span></p>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="98%" align="center">
</div>
<div id="gmail-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> <o:p></o:p></p>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal">[CAUTION: External Email] <o:p></o:p></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. <o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Clang reports this as a warning:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><i>######################################################</i><o:p></o:p></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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><i>######################################################</i><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Oliver<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></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:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt">
<div>
<p style="margin:0in;margin-bottom:.0001pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:#0078D7">[AMD Official Use Only - Internal Distribution Only]</span><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p>Hi,<o:p></o:p></p>
<p> <o:p></o:p></p>
<p>Following issue is observed with Type Based Alias Analysis(TBAA).<o:p></o:p></p>
<p> <o:p></o:p></p>
<p>#######################################################<o:p></o:p></p>
<p><i>struct P {</i><o:p></o:p></p>
<p><i>  float f1;</i><o:p></o:p></p>
<p><i>  float f2;</i><o:p></o:p></p>
<p><i>  float f3[3];</i><o:p></o:p></p>
<p><i>  float f4;</i><o:p></o:p></p>
<p><i>};</i><o:p></o:p></p>
<p><i> </i><o:p></o:p></p>
<p><i>void foo(struct P* p1, struct P* p2) {</i><o:p></o:p></p>
<p><i>  p1->f2 = 1.2;</i><o:p></o:p></p>
<p><i>  p2->f1 = 3.7;</i><o:p></o:p></p>
<p><i>}</i><o:p></o:p></p>
<p><i> </i><o:p></o:p></p>
<p><i>int callFoo() {</i><o:p></o:p></p>
<p><i>  struct P p;</i><o:p></o:p></p>
<p><i>  foo(&p, &(p.f2));</i><o:p></o:p></p>
<p><i>}</i><o:p></o:p></p>
<p><i>######################################################</i><o:p></o:p></p>
<p> <o:p></o:p></p>
<p>Printing alias-sets using commands:<o:p></o:p></p>
<p> <o:p></o:p></p>
<p><i>  clang -O1 -S -emit-llvm struct_tbaa.c</i><o:p></o:p></p>
<p><i>  opt -basicaa -tbaa -print-alias-sets -disable-output struct_tbaa.ll</i><o:p></o:p></p>
<p> <o:p></o:p></p>
<p>yields:<o:p></o:p></p>
<p> <o:p></o:p></p>
<p><i>Alias sets for function 'foo':</i><o:p></o:p></p>
<p><i>Alias Set Tracker: 2 alias sets for 2 pointer values.</i><o:p></o:p></p>
<p><i>  AliasSet[0x563d8f6a8bd0, 1] must alias, Mod       Pointers: (i32* %f2, LocationSize::precise(4))</i><o:p></o:p></p>
<p><i>  AliasSet[0x563d8f6bc080, 1] must alias, Mod       Pointers: (float* %f1, LocationSize::precise(4))</i><o:p></o:p></p>
<p><i> </i><o:p></o:p></p>
<p>IR of foo:<o:p></o:p></p>
<p> <o:p></o:p></p>
<p><i>; Function Attrs: nofree norecurse nounwind uwtable writeonly</i><o:p></o:p></p>
<p><i>define dso_local void @foo(%struct.P* nocapture %p1, %struct.P* nocapture %p2) local_unnamed_addr #0 {</i><o:p></o:p></p>
<p><i>entry:</i><o:p></o:p></p>
<p><i>  %f2 = getelementptr inbounds %struct.P, %struct.P* %p1, i64 0, i32 1</i><o:p></o:p></p>
<p><i>  store float 0x3FF3333340000000, float* %f2, align 4, !tbaa !2</i><o:p></o:p></p>
<p><i>  %f1 = getelementptr inbounds %struct.P, %struct.P* %p2, i64 0, i32 0</i><o:p></o:p></p>
<p><i>  store float 0x400D9999A0000000, float* %f1, align 4, !tbaa !7</i><o:p></o:p></p>
<p><i>  ret void</i><o:p></o:p></p>
<p><i>}</i><o:p></o:p></p>
<p><i>!2 = !{!3, !4, i64 4}</i><o:p></o:p></p>
<p><i>!3 = !{!"P", !4, i64 0, !4, i64 4, !5, i64 8, !4, i64 20}</i><o:p></o:p></p>
<p><i>!4 = !{!"float", !5, i64 0}</i><o:p></o:p></p>
<p><i>!5 = !{!"omnipotent char", !6, i64 0}</i><o:p></o:p></p>
<p><i>!6 = !{!"Simple C/C++ TBAA"}</i><o:p></o:p></p>
<p><i>!7 = !{!3, !4, i64 0}</i><o:p></o:p></p>
<p><i> </i><o:p></o:p></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><o:p></o:p></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!
<o:p></o:p></p>
<p> <o:p></o:p></p>
<p>Could someone please explain the rationale behind above behavior?<o:p></o:p></p>
<p> <o:p></o:p></p>
<p>Thanks,<o:p></o:p></p>
<p>Siddharth<o:p></o:p></p>
<p> <o:p></o:p></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><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</body>
</html>