• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -tbaa -basicaa -gvn -S < %s | FileCheck %s
2
3define i32 @test1(i8* %p, i8* %q) {
4; CHECK: @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: @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: @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: @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: @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: @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: @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
75
76
77define i32 @test8(i32* %p, i32* %q) {
78; CHECK-LABEL: test8
79; CHECK-NEXT: store i32 15, i32* %p
80; CHECK-NEXT: ret i32 0
81; Since we know the location is invariant, we can forward the
82; load across the potentially aliasing store.
83
84  %a = load i32, i32* %q, !tbaa !10
85  store i32 15, i32* %p
86  %b = load i32, i32* %q, !tbaa !10
87  %c = sub i32 %a, %b
88  ret i32 %c
89}
90define i32 @test9(i32* %p, i32* %q) {
91; CHECK-LABEL: test9
92; CHECK-NEXT: call void @clobber()
93; CHECK-NEXT: ret i32 0
94; Since we know the location is invariant, we can forward the
95; load across the potentially aliasing store (within the call).
96
97  %a = load i32, i32* %q, !tbaa !10
98  call void @clobber()
99  %b = load i32, i32* %q, !tbaa !10
100  %c = sub i32 %a, %b
101  ret i32 %c
102}
103
104
105declare void @clobber()
106declare i32 @foo(i8*) readonly
107
108; CHECK: [[TAGC]] = !{[[TYPEC:!.*]], [[TYPEC]], i64 0}
109; CHECK: [[TYPEC]] = !{!"C", [[TYPEA:!.*]]}
110; CHECK: [[TYPEA]] = !{!"A", !{{.*}}}
111; CHECK: [[TAGB]] = !{[[TYPEB:!.*]], [[TYPEB]], i64 0}
112; CHECK: [[TYPEB]] = !{!"B", [[TYPEA]]}
113; CHECK: [[TAGA]] = !{[[TYPEA]], [[TYPEA]], i64 0}
114!0 = !{!5, !5, i64 0}
115!1 = !{!6, !6, i64 0}
116!2 = !{!"tbaa root", null}
117!3 = !{!7, !7, i64 0}
118!4 = !{!8, !8, i64 0}
119!5 = !{!"C", !6}
120!6 = !{!"A", !2}
121!7 = !{!"B", !6}
122!8 = !{!"another root", null}
123
124
125;; A TBAA structure who's only point is to have a constant location
126!9 = !{!"yet another root"}
127!10 = !{!"node", !9, i64 1}
128
129