xref: /llvm-project/llvm/test/Transforms/GVN/tbaa.ll (revision 0bb1b683302e41bb1bdbcec1cbe724f54add0fa3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt -passes=gvn -S < %s | FileCheck %s
3
4define 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]]), !tbaa [[TBAA0:![0-9]+]]
8; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
9; CHECK-NEXT:    ret i32 [[C]]
10;
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
15}
16
17define 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]]
21; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
22; CHECK-NEXT:    ret i32 [[C]]
23;
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
28}
29
30define 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]]
36;
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
41}
42
43define 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]]
49;
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
54}
55
56define 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 [[TBAA0]]
60; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
61; CHECK-NEXT:    ret i32 [[C]]
62;
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
67}
68
69define 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 [[TBAA0]]
73; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
74; CHECK-NEXT:    ret i32 [[C]]
75;
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
80}
81
82define 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]]), !tbaa [[TBAA7:![0-9]+]]
86; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
87; CHECK-NEXT:    ret i32 [[C]]
88;
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
93}
94
95define 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
100;
101; Since we know the location is invariant, we can forward the
102; load across the potentially aliasing store.
103
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
109}
110
111define 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
116;
117; Since we know the location is invariant, we can forward the
118; load across the potentially aliasing store (within the call).
119
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
125}
126
127define 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 [[TBAA10:![0-9]+]]
133; CHECK-NEXT:    [[C:%.*]] = add i32 [[A]], [[A]]
134; CHECK-NEXT:    ret i32 [[C]]
135;
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
140}
141
142declare void @clobber()
143declare i32 @foo(ptr) readonly
144
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}
155
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}
160
161!19 = !{!20, !17, i64 0}            ; TAG_Y_x_i
162!20 = !{!"struct Y", !16, i64 0}    ; struct Y { struct X x; };
163
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}
167;.
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]+]], [[META8]], i64 0}
176; CHECK: [[META8]] = !{!"scalar type", [[META9:![0-9]+]]}
177; CHECK: [[META9]] = !{!"another root"}
178; CHECK: [[TBAA10]] = !{[[META11:![0-9]+]], [[META12:![0-9]+]], i64 0}
179; CHECK: [[META11]] = !{!"struct X", [[META12]], i64 0}
180; CHECK: [[META12]] = !{!"int", [[META13:![0-9]+]], i64 0}
181; CHECK: [[META13]] = !{!"char", [[META3]], i64 0}
182;.
183