[llvm-dev] TBAA for struct fields

Oliver Stannard via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 28 03:25:54 PST 2020


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.

Clang reports this as a warning:

*######################################################*
$ /work/llvm/build/bin/clang -fsyntax-only -c test.c
test.c:15:11: warning: incompatible pointer types passing 'float *' to
parameter of type 'struct P *' [-Wincompatible-pointer-types]
  foo(&p, &(p.f2));
          ^~~~~~~
test.c:8:34: note: passing argument to parameter 'p2' here
void foo(struct P *p1, struct P *p2) {
                                 ^
test.c:16:1: warning: non-void function does not return a value
[-Wreturn-type]
}
^
2 warnings generated.
*######################################################*

Oliver

On Fri, 28 Feb 2020 at 06:18, Tiwary, Siddharth via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> [AMD Official Use Only - Internal Distribution Only]
>
> Hi,
>
>
>
> Following issue is observed with Type Based Alias Analysis(TBAA).
>
>
>
> #######################################################
>
> *struct P {*
>
> *  float f1;*
>
> *  float f2;*
>
> *  float f3[3];*
>
> *  float f4;*
>
> *};*
>
>
>
> *void foo(struct P* p1, struct P* p2) {*
>
> *  p1->f2 = 1.2;*
>
> *  p2->f1 = 3.7;*
>
> *}*
>
>
>
> *int callFoo() {*
>
> *  struct P p;*
>
> *  foo(&p, &(p.f2));*
>
> *}*
>
> *######################################################*
>
>
>
> Printing alias-sets using commands:
>
>
>
> *  clang -O1 -S -emit-llvm struct_tbaa.c*
>
> *  opt -basicaa -tbaa -print-alias-sets -disable-output struct_tbaa.ll*
>
>
>
> yields:
>
>
>
> *Alias sets for function 'foo':*
>
> *Alias Set Tracker: 2 alias sets for 2 pointer values.*
>
> *  AliasSet[0x563d8f6a8bd0, 1] must alias, Mod       Pointers: (i32* %f2,
> LocationSize::precise(4))*
>
> *  AliasSet[0x563d8f6bc080, 1] must alias, Mod       Pointers: (float*
> %f1, LocationSize::precise(4))*
>
>
>
> IR of foo:
>
>
>
> *; Function Attrs: nofree norecurse nounwind uwtable writeonly*
>
> *define dso_local void @foo(%struct.P* nocapture %p1, %struct.P* nocapture
> %p2) local_unnamed_addr #0 {*
>
> *entry:*
>
> *  %f2 = getelementptr inbounds %struct.P, %struct.P* %p1, i64 0, i32 1*
>
> *  store float 0x3FF3333340000000, float* %f2, align 4, !tbaa !2*
>
> *  %f1 = getelementptr inbounds %struct.P, %struct.P* %p2, i64 0, i32 0*
>
> *  store float 0x400D9999A0000000, float* %f1, align 4, !tbaa !7*
>
> *  ret void*
>
> *}*
>
> *!2 = !{!3, !4, i64 4}*
>
> *!3 = !{!"P", !4, i64 0, !4, i64 4, !5, i64 8, !4, i64 20}*
>
> *!4 = !{!"float", !5, i64 0}*
>
> *!5 = !{!"omnipotent char", !6, i64 0}*
>
> *!6 = !{!"Simple C/C++ TBAA"}*
>
> *!7 = !{!3, !4, i64 0}*
>
>
>
> TBAA returns p1->f2 and p2->f1 in different alias-sets. But p1->f2 and
> p2->f1 do actually have the same address! Shouldn't the alias result be
> conservative while doing TBAA, especially when it needs interprocedural
> analysis?
>
> 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!
>
>
>
> Could someone please explain the rationale behind above behavior?
>
>
>
> Thanks,
>
> Siddharth
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200228/1ee410c6/attachment-0001.html>


More information about the llvm-dev mailing list