<div dir="ltr"><div>> <span style="color:rgb(0,0,0);font-family:Calibri,sans-serif;font-size:14.6667px">I get rid of the warnings by explicitly type-casting it to struct*, and still get similar results.</span></div><div><br></div>Adding the explicit cast suppresses the warning, but the behaviour of the code is still undefined according to the C (and C++) standard.<div><br></div><div>> <span style="color:rgb(0,0,0);font-family:Calibri,sans-serif;font-size:14.6667px">Shouldn’t any alias analysis(including TBAA) be conservative in interprocedural context, and consider all aliasing possibilities between different fields?</span></div><div><br></div><div>TBAA doesn't have to consider overlap between different fields, because different fields are not allowed to overlap.</div><div><br></div><div>> <b style="color:rgb(0,0,0);font-family:Calibri,sans-serif;font-size:14.6667px">For Clang, O1 onwards results are wrong!</b></div><div><b style="color:rgb(0,0,0);font-family:Calibri,sans-serif;font-size:14.6667px"><br></b></div><div>Since the behaviour of the source code is undefined, a compiler can generate any code it wants to, and be correct.<br></div><div><br></div><div>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.</div><div><br></div><div>Oliver</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">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:<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 dir="ltr">
<p style="font-family:Arial;font-size:10pt;color:rgb(49,113,0);margin:15pt" align="Left">
[AMD Public Use]<br>
</p>
<br>
<div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
Hi Oliver,</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<br>
</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
I get rid of the warnings by explicitly type-casting it to struct*, and still get similar results.</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
#######################################################</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
struct P {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f1;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f2;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f3[3];</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f4;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
};</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
void foo(struct P* p1, struct P* p2) {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  p1->f2 = 1.2;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  p2->f1 = 3.7;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
}</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
int callFoo() {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  struct P p;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  foo(&p, (struct P*)(&(p.f2)));</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  return 0;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
}</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
#######################################################</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
Shouldn’t any alias analysis(including TBAA) be conservative in interprocedural context, and consider all aliasing possibilities between different fields?
<span style="font-size:10.5pt;font-family:"Segoe UI",sans-serif"></span></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
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.</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
So, in second case, it is indeed conservative. This too is in interprocedural context!</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
I ask this because as a result of the above, following happens:</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
##########################################</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
struct P {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f1;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f2;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f3[3];</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float f4;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
};</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
float foo(struct P* p1, struct P* p2) {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  float sum = 0;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  for( int i = 0; i < 1000; i++) {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
    sum += p1->f2;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
    p2->f1 += i*7;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  }</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  return sum;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
}</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
int callFoo() {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  struct P p;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  p.f1 = 3.0;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  p.f2 = 7.0;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  printf("foo = %f\n", foo(&p, (struct P*)&(p.f2)));</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  return 0;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
}</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
int main() {</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  callFoo();</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
  return 0;</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
}</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
###########################################</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
Clang O0 and gcc O0/O1/O2 give the same expected result.</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<u></u> <u></u></p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
<b>For Clang, O1 onwards results are wrong!</b> This is because the load and store get</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
hoisted and sinked in the loop in foo, respectively. That happens even though</p>
<p style="margin:0in 0in 0.0001pt;font-size:11pt;font-family:Calibri,sans-serif">
load(p1->f2) and store(p2->f1) are same address, but LLVM doesn’t find it.</p>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">
<br>
</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">
Thanks,</div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">
Siddharth</div>
<div>
<div id="gmail-m_-5516881373014970105gmail-m_-6928860084797707650appendonsend"></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
<br>
</div>
<hr style="display:inline-block;width:98%">
<div id="gmail-m_-5516881373014970105gmail-m_-6928860084797707650divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> 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</font>
<div> </div>
</div>
<div>[CAUTION: External Email]
<div>
<div dir="ltr">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.
<div><br>
</div>
<div>Clang reports this as a warning:</div>
<div><br>
</div>
<div><i>######################################################</i><br>
</div>
<div>$ /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.<br>
</div>
<div><i>######################################################</i><br>
</div>
<div><br>
</div>
<div>Oliver</div>
</div>
<br>
<div>
<div dir="ltr">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:<br>
</div>
<blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US">
<p align="Left" style="margin:0px"><span style="font-size:10pt;font-family:Arial;color:rgb(0,120,215)">[AMD Official Use Only - Internal Distribution Only]</span></p>
<br>
<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 {<u></u><u></u></i></p>
<p><i>  float f1;<u></u><u></u></i></p>
<p><i>  float f2;<u></u><u></u></i></p>
<p><i>  float f3[3];<u></u><u></u></i></p>
<p><i>  float f4;<u></u><u></u></i></p>
<p><i>};<u></u><u></u></i></p>
<p><i><u></u> <u></u></i></p>
<p><i>void foo(struct P* p1, struct P* p2) {<u></u><u></u></i></p>
<p><i>  p1->f2 = 1.2;<u></u><u></u></i></p>
<p><i>  p2->f1 = 3.7;<u></u><u></u></i></p>
<p><i>}<u></u><u></u></i></p>
<p><i><u></u> <u></u></i></p>
<p><i>int callFoo() {<u></u><u></u></i></p>
<p><i>  struct P p;<u></u><u></u></i></p>
<p><i>  foo(&p, &(p.f2));<u></u><u></u></i></p>
<p><i>}<u></u><u></u></i></p>
<p><i>######################################################<u></u><u></u></i></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<u></u><u></u></i></p>
<p><i>  opt -basicaa -tbaa -print-alias-sets -disable-output struct_tbaa.ll<u></u><u></u></i></p>
<p><u></u> <u></u></p>
<p>yields:<i><u></u><u></u></i></p>
<p><u></u> <u></u></p>
<p><i>Alias sets for function 'foo':<u></u><u></u></i></p>
<p><i>Alias Set Tracker: 2 alias sets for 2 pointer values.<u></u><u></u></i></p>
<p><i>  AliasSet[0x563d8f6a8bd0, 1] must alias, Mod       Pointers: (i32* %f2, LocationSize::precise(4))<u></u><u></u></i></p>
<p><i>  AliasSet[0x563d8f6bc080, 1] must alias, Mod       Pointers: (float* %f1, LocationSize::precise(4))<u></u><u></u></i></p>
<p><i><u></u> <u></u></i></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<u></u><u></u></i></p>
<p><i>define dso_local void @foo(%struct.P* nocapture %p1, %struct.P* nocapture %p2) local_unnamed_addr #0 {<u></u><u></u></i></p>
<p><i>entry:<u></u><u></u></i></p>
<p><i>  %f2 = getelementptr inbounds %struct.P, %struct.P* %p1, i64 0, i32 1<u></u><u></u></i></p>
<p><i>  store float 0x3FF3333340000000, float* %f2, align 4, !tbaa !2<u></u><u></u></i></p>
<p><i>  %f1 = getelementptr inbounds %struct.P, %struct.P* %p2, i64 0, i32 0<u></u><u></u></i></p>
<p><i>  store float 0x400D9999A0000000, float* %f1, align 4, !tbaa !7<u></u><u></u></i></p>
<p><i>  ret void<u></u><u></u></i></p>
<p><i>}<u></u><u></u></i></p>
<p><i>!2 = !{!3, !4, i64 4}<u></u><u></u></i></p>
<p><i>!3 = !{!"P", !4, i64 0, !4, i64 4, !5, i64 8, !4, i64 20}<u></u><u></u></i></p>
<p><i>!4 = !{!"float", !5, i64 0}<u></u><u></u></i></p>
<p><i>!5 = !{!"omnipotent char", !6, i64 0}<u></u><u></u></i></p>
<p><i>!6 = !{!"Simple C/C++ TBAA"}<u></u><u></u></i></p>
<p><i>!7 = !{!3, !4, i64 0}<u></u><u></u></i></p>
<p><i><u></u> <u></u></i></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?<u></u><u></u></span></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>
_______________________________________________<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%7C55cbbbb7e1a94c96e95a08d7bc410071%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637184859677188070&sdata=FWe7e9hyGnK0Sfg01akjq9oYWzN2cJi%2BvorGSyvlx4A%3D&reserved=0" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>

</blockquote></div>