1; RUN: opt -tbaa -basic-aa -newgvn -S < %s | FileCheck %s
2
3define i32 @test1(i8* %p, i8* %q) {
4; CHECK-LABEL: @test1(i8* %p, i8* %q)
5; CHECK: call i32 @foo(i8* %p)
6; CHECK-NOT: tbaa
7; CHECK: %c = add i32 %a, %a
8  %a = call i32 @foo(i8* %p), !tbaa !0
9  %b = call i32 @foo(i8* %p)
10  %c = add i32 %a, %b
11  ret i32 %c
12}
13
14define i32 @test2(i8* %p, i8* %q) {
15; CHECK-LABEL: @test2(i8* %p, i8* %q)
16; CHECK: call i32 @foo(i8* %p), !tbaa [[TAGC:!.*]]
17; CHECK: %c = add i32 %a, %a
18  %a = call i32 @foo(i8* %p), !tbaa !0
19  %b = call i32 @foo(i8* %p), !tbaa !0
20  %c = add i32 %a, %b
21  ret i32 %c
22}
23
24define i32 @test3(i8* %p, i8* %q) {
25; CHECK-LABEL: @test3(i8* %p, i8* %q)
26; CHECK: call i32 @foo(i8* %p), !tbaa [[TAGB:!.*]]
27; CHECK: %c = add i32 %a, %a
28  %a = call i32 @foo(i8* %p), !tbaa !3
29  %b = call i32 @foo(i8* %p), !tbaa !3
30  %c = add i32 %a, %b
31  ret i32 %c
32}
33
34define i32 @test4(i8* %p, i8* %q) {
35; CHECK-LABEL: @test4(i8* %p, i8* %q)
36; CHECK: call i32 @foo(i8* %p), !tbaa [[TAGA:!.*]]
37; CHECK: %c = add i32 %a, %a
38  %a = call i32 @foo(i8* %p), !tbaa !1
39  %b = call i32 @foo(i8* %p), !tbaa !0
40  %c = add i32 %a, %b
41  ret i32 %c
42}
43
44define i32 @test5(i8* %p, i8* %q) {
45; CHECK-LABEL: @test5(i8* %p, i8* %q)
46; CHECK: call i32 @foo(i8* %p), !tbaa [[TAGA]]
47; CHECK: %c = add i32 %a, %a
48  %a = call i32 @foo(i8* %p), !tbaa !0
49  %b = call i32 @foo(i8* %p), !tbaa !1
50  %c = add i32 %a, %b
51  ret i32 %c
52}
53
54define i32 @test6(i8* %p, i8* %q) {
55; CHECK-LABEL: @test6(i8* %p, i8* %q)
56; CHECK: call i32 @foo(i8* %p), !tbaa [[TAGA]]
57; CHECK: %c = add i32 %a, %a
58  %a = call i32 @foo(i8* %p), !tbaa !0
59  %b = call i32 @foo(i8* %p), !tbaa !3
60  %c = add i32 %a, %b
61  ret i32 %c
62}
63
64define i32 @test7(i8* %p, i8* %q) {
65; CHECK-LABEL: @test7(i8* %p, i8* %q)
66; CHECK: call i32 @foo(i8* %p)
67; CHECK-NOT: tbaa
68; CHECK: %c = add i32 %a, %a
69  %a = call i32 @foo(i8* %p), !tbaa !4
70  %b = call i32 @foo(i8* %p), !tbaa !3
71  %c = add i32 %a, %b
72  ret i32 %c
73}
74
75define i32 @test8(i32* %p, i32* %q) {
76; CHECK-LABEL: @test8
77; CHECK-NEXT: store i32 15, i32* %p
78; CHECK-NEXT: ret i32 0
79; Since we know the location is invariant, we can forward the
80; load across the potentially aliasing store.
81
82  %a = load i32, i32* %q, !tbaa !10
83  store i32 15, i32* %p
84  %b = load i32, i32* %q, !tbaa !10
85  %c = sub i32 %a, %b
86  ret i32 %c
87}
88
89define i32 @test9(i32* %p, i32* %q) {
90; CHECK-LABEL: @test9
91; CHECK-NEXT: call void @clobber()
92; CHECK-NEXT: ret i32 0
93; Since we know the location is invariant, we can forward the
94; load across the potentially aliasing store (within the call).
95
96  %a = load i32, i32* %q, !tbaa !10
97  call void @clobber()
98  %b = load i32, i32* %q, !tbaa !10
99  %c = sub i32 %a, %b
100  ret i32 %c
101}
102
103define i32 @test10(i8* %p, i8* %q) {
104; If one access encloses the other, then the merged access is the enclosed one
105; and not just the common final access type.
106; CHECK-LABEL: @test10
107; CHECK: call i32 @foo(i8* %p), !tbaa [[TAG_X_i:!.*]]
108; CHECK: %c = add i32 %a, %a
109  %a = call i32 @foo(i8* %p), !tbaa !15  ; TAG_X_i
110  %b = call i32 @foo(i8* %p), !tbaa !19  ; TAG_Y_x_i
111  %c = add i32 %a, %b
112  ret i32 %c
113}
114
115declare void @clobber()
116declare i32 @foo(i8*) readonly
117
118; CHECK-DAG: [[TAGC]] = !{[[TYPEC:!.*]], [[TYPEC]], i64 0}
119; CHECK-DAG: [[TYPEC]] = !{!"C", [[TYPEA:!.*]]}
120; CHECK-DAG: [[TYPEA]] = !{!"A", !{{.*}}}
121; CHECK-DAG: [[TAGB]] = !{[[TYPEB:!.*]], [[TYPEB]], i64 0}
122; CHECK-DAG: [[TYPEB]] = !{!"B", [[TYPEA]]}
123; CHECK-DAG: [[TAGA]] = !{[[TYPEA]], [[TYPEA]], i64 0}
124!0 = !{!5, !5, i64 0}
125!1 = !{!6, !6, i64 0}
126!2 = !{!"tbaa root"}
127!3 = !{!7, !7, i64 0}
128!4 = !{!11, !11, i64 0}
129!5 = !{!"C", !6}
130!6 = !{!"A", !2}
131!7 = !{!"B", !6}
132!8 = !{!"another root"}
133!11 = !{!"scalar type", !8}
134
135; CHECK-DAG: [[TAG_X_i]] = !{[[TYPE_X:!.*]], [[TYPE_int:!.*]], i64 0}
136; CHECK-DAG: [[TYPE_X:!.*]] = !{!"struct X", [[TYPE_int]], i64 0}
137; CHECK-DAG: [[TYPE_int]] = !{!"int", {{!.*}}, i64 0}
138!15 = !{!16, !17, i64 0}            ; TAG_X_i
139!16 = !{!"struct X", !17, i64 0}    ; struct X { int i; };
140!17 = !{!"int", !18, i64 0}
141!18 = !{!"char", !2, i64 0}
142
143!19 = !{!20, !17, i64 0}            ; TAG_Y_x_i
144!20 = !{!"struct Y", !16, i64 0}    ; struct Y { struct X x; };
145
146; A TBAA structure who's only point is to have a constant location.
147!9 = !{!"yet another root"}
148!10 = !{!"node", !9, i64 1}
149