1 ; RUN: opt < %s -aa-pipeline=tbaa,basic-aa -passes=aa-eval -evaluate-aa-metadata \
2 ; RUN: -print-no-aliases -print-may-aliases -disable-output 2>&1 | \
4 ; RUN: opt < %s -aa-pipeline=tbaa,basic-aa -passes=gvn -S | FileCheck %s --check-prefix=OPT
6 ; Check that TBAA handles access tags with aggregate final access types
9 %A = type { i32 } ; struct A { int i; };
10 %B = type { %A } ; struct B { A a; };
11 %C = type { %B } ; struct C { B b; };
12 %D = type { i16 } ; struct D { short s; };
14 ; int vs. A::i => MayAlias.
15 define i32 @f1(ptr %i, ptr %a) {
18 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
22 ; OPT: %[[RET:.*]] = load i32,
23 ; OPT: ret i32 %[[RET]]
24 store i32 5, ptr %i, align 4, !tbaa !3 ; TAG_int
25 store i32 7, ptr %a, align 4, !tbaa !5 ; TAG_A_i
26 %0 = load i32, ptr %i, align 4, !tbaa !3 ; TAG_int
30 ; int vs. B::a => MayAlias.
31 define i32 @f2(ptr %i, ptr %b) {
34 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
38 ; OPT: %[[RET:.*]] = load i32,
39 ; OPT: ret i32 %[[RET]]
40 store i32 5, ptr %i, align 4, !tbaa !3 ; TAG_int
41 store i32 7, ptr %b, align 4, !tbaa !7 ; TAG_B_a
42 %0 = load i32, ptr %i, align 4, !tbaa !3 ; TAG_int
46 ; int vs. C::b => MayAlias.
47 define i32 @f3(ptr %i, ptr %c) {
50 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
54 ; OPT: %[[RET:.*]] = load i32,
55 ; OPT: ret i32 %[[RET]]
56 store i32 5, ptr %i, align 4, !tbaa !3 ; TAG_int
57 store i32 7, ptr %c, align 4, !tbaa !9 ; TAG_C_b
58 %0 = load i32, ptr %i, align 4, !tbaa !3 ; TAG_int
62 ; A vs. C::b => MayAlias.
63 define i32 @f4(ptr %a, ptr %c) {
66 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
70 ; OPT: %[[RET:.*]] = load i32,
71 ; OPT: ret i32 %[[RET]]
72 store i32 5, ptr %a, align 4, !tbaa !10 ; TAG_A
73 store i32 7, ptr %c, align 4, !tbaa !9 ; TAG_C_b
74 %0 = load i32, ptr %a, align 4, !tbaa !10 ; TAG_A
78 ; short vs. C::b => NoAlias.
79 define i32 @f5(ptr %i, ptr %c) {
82 ; CHECK: NoAlias: store i32 7, {{.*}} <-> store i32 5,
87 store i32 5, ptr %i, align 4, !tbaa !12 ; TAG_short
88 store i32 7, ptr %c, align 4, !tbaa !9 ; TAG_C_b
89 %0 = load i32, ptr %i, align 4, !tbaa !12 ; TAG_short
94 define i32 @f6(ptr %c, ptr %d) {
97 ; CHECK: NoAlias: store i16 7, {{.*}} <-> store i32 5,
102 store i32 5, ptr %c, align 4, !tbaa !13 ; TAG_C
103 store i16 7, ptr %d, align 4, !tbaa !15 ; TAG_D
104 %0 = load i32, ptr %c, align 4, !tbaa !13 ; TAG_C
109 !1 = !{!0, i64 1, !"char"}
110 !2 = !{!1, i64 4, !"int"}
111 !3 = !{!2, !2, i64 0, i64 4} ; TAG_int
113 !4 = !{!1, i64 4, !"A", !2, i64 0, i64 4}
114 !5 = !{!4, !2, i64 0, i64 4} ; TAG_A_i
116 !6 = !{!1, i64 4, !"B", !4, i64 0, i64 4}
117 !7 = !{!6, !4, i64 0, i64 4} ; TAG_B_a
119 !8 = !{!1, i64 4, !"C", !6, i64 0, i64 4}
120 !9 = !{!8, !6, i64 0, i64 4} ; TAG_C_b
122 !10 = !{!4, !4, i64 0, i64 4} ; TAG_A
124 !11 = !{!1, i64 2, !"short"}
125 !12 = !{!11, !11, i64 0, i64 2} ; TAG_short
127 !13 = !{!8, !8, i64 0, i64 4} ; TAG_C
129 !14 = !{!4, i64 2, !"D", !11, i64 0, i64 2}
130 !15 = !{!14, !14, i64 0, i64 2} ; TAG_D