[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Analysis / TypeBasedAliasAnalysis / aggregates.ll
blob1c5efa219134e59abe7ab79470dbb63623f3766d
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 | \
3 ; RUN:     FileCheck %s
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
7 ; correctly.
9 %A = type { i32, i32 }  ; struct A { int i, j; };
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) {
16 entry:
17 ; CHECK-LABEL: f1
18 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
19 ; OPT-LABEL: f1
20 ; OPT: store i32 5,
21 ; OPT: store i32 7,
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
27   ret i32 %0
30 ; int vs. B::a  =>  MayAlias.
31 define i32 @f2(ptr %i, ptr %b) {
32 entry:
33 ; CHECK-LABEL: f2
34 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
35 ; OPT-LABEL: f2
36 ; OPT: store i32 5,
37 ; OPT: store i32 7,
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
43   ret i32 %0
46 ; int vs. C::b  =>  MayAlias.
47 define i32 @f3(ptr %i, ptr %c) {
48 entry:
49 ; CHECK-LABEL: f3
50 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
51 ; OPT-LABEL: f3
52 ; OPT: store i32 5,
53 ; OPT: store i32 7,
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
59   ret i32 %0
62 ; A vs. C::b  =>  MayAlias.
63 define i32 @f4(ptr %a, ptr %c) {
64 entry:
65 ; CHECK-LABEL: f4
66 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
67 ; OPT-LABEL: f4
68 ; OPT: store i32 5,
69 ; OPT: store i32 7,
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
75   ret i32 %0
78 ; short vs. C::b  =>  NoAlias.
79 define i32 @f5(ptr %i, ptr %c) {
80 entry:
81 ; CHECK-LABEL: f5
82 ; CHECK: NoAlias: store i32 7, {{.*}} <-> store i32 5,
83 ; OPT-LABEL: f5
84 ; OPT: store i32 5,
85 ; OPT: store i32 7,
86 ; OPT: ret 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
90   ret i32 %0
93 ; C vs. D  =>  NoAlias.
94 define i32 @f6(ptr %c, ptr %d) {
95 entry:
96 ; CHECK-LABEL: f6
97 ; CHECK: NoAlias: store i16 7, {{.*}} <-> store i32 5,
98 ; OPT-LABEL: f6
99 ; OPT: store i32 5,
100 ; OPT: store i16 7,
101 ; OPT: ret 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
105   ret i32 %0
108 ; A vs. A::j  =>  MayAlias.
109 ; This differs from A vs. A::i case in that the offsets of the final
110 ; accessed objects in A do not match.
111 define i32 @f7(ptr %i, ptr %a) {
112 entry:
113 ; CHECK-LABEL: f7
114 ; CHECK: MayAlias: store i32 7, {{.*}} <-> store i32 5,
115 ; OPT-LABEL: f7
116 ; OPT: store i32 5,
117 ; OPT: store i32 7,
118 ; OPT: %[[RET:.*]] = load i32,
119 ; OPT: ret i32 %[[RET]]
120   store i32 5, ptr %i, align 4, !tbaa !10  ; TAG_A
121   store i32 7, ptr %a, align 4, !tbaa !16  ; TAG_A_j
122   %0 = load i32, ptr %i, align 4, !tbaa !10  ; TAG_A
123   ret i32 %0
126 !0 = !{!"root"}
127 !1 = !{!0, i64 1, !"char"}
128 !2 = !{!1, i64 4, !"int"}
129 !3 = !{!2, !2, i64 0, i64 4}  ; TAG_int
131 !4 = !{!1, i64 4, !"A", !2, i64 0, i64 4, !2, i64 4, i64 4}
132 !5 = !{!4, !2, i64 0, i64 4}  ; TAG_A_i
133 !16 = !{!4, !2, i64 4, i64 4}  ; TAG_A_j
135 !6 = !{!1, i64 4, !"B", !4, i64 0, i64 4}
136 !7 = !{!6, !4, i64 0, i64 4}  ; TAG_B_a
138 !8 = !{!1, i64 4, !"C", !6, i64 0, i64 4}
139 !9 = !{!8, !6, i64 0, i64 4}  ; TAG_C_b
141 !10 = !{!4, !4, i64 0, i64 4}  ; TAG_A
143 !11 = !{!1, i64 2, !"short"}
144 !12 = !{!11, !11, i64 0, i64 2}  ; TAG_short
146 !13 = !{!8, !8, i64 0, i64 4}  ; TAG_C
148 !14 = !{!4, i64 2, !"D", !11, i64 0, i64 2}
149 !15 = !{!14, !14, i64 0, i64 2}  ; TAG_D