[llvm-dev] llvm-ir: TBAA and struct copies

Ivan Kosarev via llvm-dev llvm-dev at lists.llvm.org
Wed Jun 5 03:25:18 PDT 2019


Hello Jeroen,

AFAIR, with the current TBAA format the access type shall never be an 
aggregate, so the !10 node looks suspicious.

Tried to reproduce this on 362464 with that same input snippet, but got 
something completely different, see below.

Regards,

---
$ clang -cc1 -S -emit-llvm -O1 -disable-llvm-passes x.cpp
$ cat x.ll
...
define i32 @_Z6foobarv() #0 {
entry:
   store i16 42, i16* getelementptr inbounds (%struct.S, %struct.S* @x, 
i32 0, i32 2), align 2, !tbaa !2
   %0 = load %struct.S*, %struct.S** @p, align 8, !tbaa !8
   %1 = bitcast %struct.S* %0 to i8*
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 
bitcast (%struct.S* @y to i8*), i64 8, i1 false), !tbaa.struct !10
   %2 = load i16, i16* getelementptr inbounds (%struct.S, %struct.S* @x, 
i32 0, i32 2), align 2, !tbaa !2
   %conv = sext i16 %2 to i32
   ret i32 %conv
}
...
!2 = !{!3, !7, i64 6}
!3 = !{!"_ZTS1S", !4, i64 0, !7, i64 4, !7, i64 6}
!4 = !{!"int", !5, i64 0}
!5 = !{!"omnipotent char", !6, i64 0}
!6 = !{!"Simple C++ TBAA"}
!7 = !{!"short", !5, i64 0}
!8 = !{!9, !9, i64 0}
!9 = !{!"any pointer", !5, i64 0}
!10 = !{i64 0, i64 4, !11, i64 4, i64 2, !12, i64 6, i64 2, !12}
!11 = !{!4, !4, i64 0}
!12 = !{!7, !7, i64 0}
---



On 04/06/2019 17:34, Jeroen Dobbelaere via llvm-dev wrote:
> Hi,
>
> I have a question about the current definition of TBAA (See [1]).
>
> In the LLVM-IR code that we produce, we generate load/stores of struct types. (See [2] and [3] for a godbolt example showing the issue)
>
> For following c-alike code:
>
>    struct S { int dummy; short e, f; } x,y;
>    struct S* p = &x;
>    int foobar() {
>      x.f=42;
>      *p=y;  //**** struct copy
>      return x.f;
>    }
>
> We produce:
>
>    [...]
>    %struct.S = type { i32, i16, i16 }
>    ; Function Attrs: norecurse nounwind uwtable
>    define dso_local i32 @foobar() local_unnamed_addr #0 {
>      store i16 42, i16* getelementptr inbounds (%struct.S, %struct.S* @x, i64 0, i32 2), align 2, !tbaa !2
>      %1 = load %struct.S*, %struct.S** @p, align 8, !tbaa !8
>      %2 = load %struct.S, %struct.S* @y, align 8, !tbaa  !10  ;*************
>      store %struct.S %2, %struct.S* %1, align 4, !tbaa !10     ; *************
>      %3 = load i16, i16* getelementptr inbounds (%struct.S, %struct.S* @x, i64 0, i32 2), align 2, !tbaa !2
>      %4 = sext i16 %3 to i32
>      ret i32 %4
>    }
>    [...]
>    !0 = !{i32 1, !"wchar_size", i32 4}
>    !1 = !{!"clang version 9.0.0 (trunk 362464)"}
>    !2 = !{!3, !7, i64 6}
>    !3 = !{!"_ZTS1S", !4, i64 0, !7, i64 4, !7, i64 6}
>    !4 = !{!"int", !5, i64 0}
>    !5 = !{!"omnipotent char", !6, i64 0}
>    !6 = !{!"Simple C++ TBAA"}
>    !7 = !{!"short", !5, i64 0}
>    !8 = !{!9, !9, i64 0}
>    !9 = !{!"any pointer", !5, i64 0}
>    !10 = !{!3, !3, i64 0}    ; ***********************
>
>
> In order to allow other optimizations, we have also attached TBAA information to the load/store of the struct (!tbaa !10).
> The logical solution would be to construct '!tbaa !10' as shown:
>    - the base type is '!3 (_ZTS1S)'
>    - the access type is also '!3 (_ZTS1S)'
>    - the offset is 'i64 0'
>
> I observe following issues:
>    - issue 1: the tbaa semantics will not detect aliasing between '!10' and '!2' (See [2] and [3]; the load i16 in bar_wrong should not be optimized away)
>    - issue 2: according to the pure definition of the 'access tags', the base type and the access type can not be the same struct type.
>        As such, the provided example could be found to be 'invalid'. Still, by adding an extra indirection, a similar 'valid' example (with wrong behavior)
>        can be constructed. See [3]
>
>    - For 'issue 2', I think that the definition of 'access tag' should be relaxed, allowing the description of a full copy' of a struct.
>    - For 'issue 1', the lookup algorithm should be enhanced so that aliasing can be detected for these cases.
>
> Is this a correct interpretation ? Any input is welcome !
>
> Thanks,
>
> Jeroen Dobbelaere
> ----
> [1] tbaa metadata: https://llvm.org/docs/LangRef.html#tbaa-metadata
> [2] godbolt example with single struct: https://www.godbolt.org/z/XcQy-U
> [3] godbolt example with nested struct: https://www.godbolt.org/z/mNd-iI
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list