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]]), !tbaa [[TBAA0:![0-9]+]]
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)
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]]
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
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
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
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 [[TBAA0]]
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
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 [[TBAA0]]
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
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]]), !tbaa [[TBAA7:![0-9]+]]
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
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
106 %b = load i32, ptr %q, !tbaa !10
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
122 %b = load i32, ptr %q, !tbaa !10
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 [[TBAA10:![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
142 declare void @clobber()
143 declare i32 @foo(ptr) readonly
145 !0 = !{!5, !5, i64 0}
146 !1 = !{!6, !6, i64 0}
148 !3 = !{!7, !7, i64 0}
149 !4 = !{!11, !11, i64 0}
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]+]], [[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}