[libc] support fully OOT build (#101287)
[llvm-project.git] / llvm / test / Transforms / NewGVN / tbaa.ll
blob335e782acc8bcd0d5ee3ae5ef7ee82b6b0ef319e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt -passes=newgvn -S < %s | FileCheck %s
4 define i32 @test1(ptr %p, ptr %q) {
5 ; CHECK-LABEL: define i32 @test1(
6 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
7 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]])
8 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
9 ; CHECK-NEXT:    ret i32 [[C]]
11   %a = call i32 @foo(ptr %p), !tbaa !0
12   %b = call i32 @foo(ptr %p)
13   %c = add i32 %a, %b
14   ret i32 %c
17 define i32 @test2(ptr %p, ptr %q) {
18 ; CHECK-LABEL: define i32 @test2(
19 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
20 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0:![0-9]+]]
21 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
22 ; CHECK-NEXT:    ret i32 [[C]]
24   %a = call i32 @foo(ptr %p), !tbaa !0
25   %b = call i32 @foo(ptr %p), !tbaa !0
26   %c = add i32 %a, %b
27   ret i32 %c
30 define i32 @test3(ptr %p, ptr %q) {
31 ; CHECK-LABEL: define i32 @test3(
32 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
33 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4:![0-9]+]]
34 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
35 ; CHECK-NEXT:    ret i32 [[C]]
37   %a = call i32 @foo(ptr %p), !tbaa !3
38   %b = call i32 @foo(ptr %p), !tbaa !3
39   %c = add i32 %a, %b
40   ret i32 %c
43 define i32 @test4(ptr %p, ptr %q) {
44 ; CHECK-LABEL: define i32 @test4(
45 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
46 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6:![0-9]+]]
47 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
48 ; CHECK-NEXT:    ret i32 [[C]]
50   %a = call i32 @foo(ptr %p), !tbaa !1
51   %b = call i32 @foo(ptr %p), !tbaa !0
52   %c = add i32 %a, %b
53   ret i32 %c
56 define i32 @test5(ptr %p, ptr %q) {
57 ; CHECK-LABEL: define i32 @test5(
58 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
59 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6]]
60 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
61 ; CHECK-NEXT:    ret i32 [[C]]
63   %a = call i32 @foo(ptr %p), !tbaa !0
64   %b = call i32 @foo(ptr %p), !tbaa !1
65   %c = add i32 %a, %b
66   ret i32 %c
69 define i32 @test6(ptr %p, ptr %q) {
70 ; CHECK-LABEL: define i32 @test6(
71 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
72 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6]]
73 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
74 ; CHECK-NEXT:    ret i32 [[C]]
76   %a = call i32 @foo(ptr %p), !tbaa !0
77   %b = call i32 @foo(ptr %p), !tbaa !3
78   %c = add i32 %a, %b
79   ret i32 %c
82 define i32 @test7(ptr %p, ptr %q) {
83 ; CHECK-LABEL: define i32 @test7(
84 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
85 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]])
86 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
87 ; CHECK-NEXT:    ret i32 [[C]]
89   %a = call i32 @foo(ptr %p), !tbaa !4
90   %b = call i32 @foo(ptr %p), !tbaa !3
91   %c = add i32 %a, %b
92   ret i32 %c
95 define i32 @test8(ptr %p, ptr %q) {
96 ; CHECK-LABEL: define i32 @test8(
97 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
98 ; CHECK-NEXT:    store i32 15, ptr [[P]], align 4
99 ; CHECK-NEXT:    ret i32 0
101 ; Since we know the location is invariant, we can forward the
102 ; load across the potentially aliasing store.
104   %a = load i32, ptr %q, !tbaa !10
105   store i32 15, ptr %p
106   %b = load i32, ptr %q, !tbaa !10
107   %c = sub i32 %a, %b
108   ret i32 %c
111 define i32 @test9(ptr %p, ptr %q) {
112 ; CHECK-LABEL: define i32 @test9(
113 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
114 ; CHECK-NEXT:    call void @clobber()
115 ; CHECK-NEXT:    ret i32 0
117 ; Since we know the location is invariant, we can forward the
118 ; load across the potentially aliasing store (within the call).
120   %a = load i32, ptr %q, !tbaa !10
121   call void @clobber()
122   %b = load i32, ptr %q, !tbaa !10
123   %c = sub i32 %a, %b
124   ret i32 %c
127 define i32 @test10(ptr %p, ptr %q) {
128 ; If one access encloses the other, then the merged access is the enclosed one
129 ; and not just the common final access type.
130 ; CHECK-LABEL: define i32 @test10(
131 ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
132 ; CHECK-NEXT:    [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA7:![0-9]+]]
133 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
134 ; CHECK-NEXT:    ret i32 [[C]]
136   %a = call i32 @foo(ptr %p), !tbaa !15  ; TAG_X_i
137   %b = call i32 @foo(ptr %p), !tbaa !19  ; TAG_Y_x_i
138   %c = add i32 %a, %b
139   ret i32 %c
142 declare void @clobber()
143 declare i32 @foo(ptr) readonly
145 !0 = !{!5, !5, i64 0}
146 !1 = !{!6, !6, i64 0}
147 !2 = !{!"tbaa root"}
148 !3 = !{!7, !7, i64 0}
149 !4 = !{!11, !11, i64 0}
150 !5 = !{!"C", !6}
151 !6 = !{!"A", !2}
152 !7 = !{!"B", !6}
153 !8 = !{!"another root"}
154 !11 = !{!"scalar type", !8}
156 !15 = !{!16, !17, i64 0}            ; TAG_X_i
157 !16 = !{!"struct X", !17, i64 0}    ; struct X { int i; };
158 !17 = !{!"int", !18, i64 0}
159 !18 = !{!"char", !2, i64 0}
161 !19 = !{!20, !17, i64 0}            ; TAG_Y_x_i
162 !20 = !{!"struct Y", !16, i64 0}    ; struct Y { struct X x; };
164 ; A TBAA structure who's only point is to have a constant location.
165 !9 = !{!"yet another root"}
166 !10 = !{!"node", !9, i64 1}
168 ; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
169 ; CHECK: [[META1]] = !{!"C", [[META2:![0-9]+]]}
170 ; CHECK: [[META2]] = !{!"A", [[META3:![0-9]+]]}
171 ; CHECK: [[META3]] = !{!"tbaa root"}
172 ; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
173 ; CHECK: [[META5]] = !{!"B", [[META2]]}
174 ; CHECK: [[TBAA6]] = !{[[META2]], [[META2]], i64 0}
175 ; CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], i64 0}
176 ; CHECK: [[META8]] = !{!"struct X", [[META9]], i64 0}
177 ; CHECK: [[META9]] = !{!"int", [[META10:![0-9]+]], i64 0}
178 ; CHECK: [[META10]] = !{!"char", [[META3]], i64 0}