Skip to content

Commit 44d527c

Browse files
committed
NFC: precommit test for [ArgPromotion] Perform alias analysis on actual arguments of Calls
1 parent b1b24d7 commit 44d527c

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes
2+
; RUN: opt -S -passes=argpromotion < %s | FileCheck %s
3+
4+
; In the following tests, the call to @callee may invalidate ptr %test_c and so
5+
; prohibit removing loads of %test_c following the call, preventing Argument
6+
; Promotion of %test_c in the general case.
7+
8+
; This is called by @caller_ptr_args, from which we cannot prove anything about
9+
; whether %test_c may alias %p and so we cannot promote %test_c.
10+
;
11+
define internal i32 @test_cannot_promote_1(ptr %p, ptr nocapture readonly %test_c) {
12+
; CHECK-LABEL: define {{[^@]+}}@test_cannot_promote_1
13+
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
14+
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
15+
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
16+
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
17+
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
18+
; CHECK-NEXT: ret i32 [[SUM]]
19+
;
20+
%res = call i32 @callee(ptr %p, ptr %test_c)
21+
22+
%ltest_c = load i32, ptr %test_c
23+
24+
%sum = add i32 %ltest_c, %res
25+
26+
ret i32 %sum
27+
}
28+
29+
; This is called by @caller_aliased_args, from which we can see that %test_c may
30+
; alias %p and so we cannot promote %test_c.
31+
;
32+
define internal i32 @test_cannot_promote_2(ptr %p, ptr nocapture readonly %test_c) {
33+
; CHECK-LABEL: define {{[^@]+}}@test_cannot_promote_2
34+
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
35+
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
36+
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
37+
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
38+
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
39+
; CHECK-NEXT: ret i32 [[SUM]]
40+
;
41+
%res = call i32 @callee(ptr %p, ptr %test_c)
42+
43+
%ltest_c = load i32, ptr %test_c
44+
45+
%sum = add i32 %ltest_c, %res
46+
47+
ret i32 %sum
48+
}
49+
50+
; This is called by @caller_safe_args_1, but also from @caller_aliased_args, so
51+
; we cannot promote %test_c.
52+
;
53+
define internal i32 @test_cannot_promote_3(ptr %p, ptr nocapture readonly %test_c) {
54+
; CHECK-LABEL: define {{[^@]+}}@test_cannot_promote_3
55+
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
56+
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
57+
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
58+
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
59+
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
60+
; CHECK-NEXT: ret i32 [[SUM]]
61+
;
62+
%res = call i32 @callee(ptr %p, ptr %test_c)
63+
64+
%ltest_c = load i32, ptr %test_c
65+
66+
%sum = add i32 %ltest_c, %res
67+
68+
ret i32 %sum
69+
}
70+
71+
; FIXME: We should perform ArgPromotion here!
72+
;
73+
; This is called only by @caller_safe_args_1, from which we can prove that
74+
; %test_c does not alias %p for any Call to the function, so we can promote it.
75+
;
76+
define internal i32 @test_can_promote_1(ptr %p, ptr nocapture readonly %test_c) {
77+
; CHECK-LABEL: define {{[^@]+}}@test_can_promote_1
78+
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
79+
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
80+
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
81+
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
82+
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
83+
; CHECK-NEXT: ret i32 [[SUM]]
84+
;
85+
%res = call i32 @callee(ptr %p, ptr %test_c)
86+
87+
%ltest_c = load i32, ptr %test_c
88+
89+
%sum = add i32 %ltest_c, %res
90+
91+
ret i32 %sum
92+
}
93+
94+
; FIXME: We should perform ArgPromotion here!
95+
;
96+
; This is called by multiple callers (@caller_safe_args_1, @caller_safe_args_2),
97+
; from which we can prove that %test_c does not alias %p for any Call to the
98+
; function, so we can promote it.
99+
;
100+
define internal i32 @test_can_promote_2(ptr %p, ptr nocapture readonly %test_c) {
101+
; CHECK-LABEL: define {{[^@]+}}@test_can_promote_2
102+
; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[TEST_C:%.*]]) {
103+
; CHECK-NEXT: [[TEST_C_VAL:%.*]] = load i32, ptr [[TEST_C]], align 4
104+
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(ptr [[P]], i32 [[TEST_C_VAL]])
105+
; CHECK-NEXT: [[LTEST_C:%.*]] = load i32, ptr [[TEST_C]], align 4
106+
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[LTEST_C]], [[RES]]
107+
; CHECK-NEXT: ret i32 [[SUM]]
108+
;
109+
%res = call i32 @callee(ptr %p, ptr %test_c)
110+
111+
%ltest_c = load i32, ptr %test_c
112+
113+
%sum = add i32 %ltest_c, %res
114+
115+
ret i32 %sum
116+
}
117+
118+
; Called by @test_XXX
119+
define internal i32 @callee(ptr %p, ptr nocapture readonly %callee_c) {
120+
; CHECK-LABEL: define {{[^@]+}}@callee
121+
; CHECK-SAME: (ptr [[P:%.*]], i32 [[CALLEE_C_0_VAL:%.*]]) {
122+
; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4
123+
; CHECK-NEXT: [[SUM:%.*]] = add i32 [[A]], [[CALLEE_C_0_VAL]]
124+
; CHECK-NEXT: store i32 [[SUM]], ptr [[P]], align 4
125+
; CHECK-NEXT: ret i32 [[SUM]]
126+
;
127+
%a = load i32, ptr %p
128+
129+
%lcallee_c = load i32, ptr %callee_c
130+
131+
%sum = add i32 %a, %lcallee_c
132+
133+
store i32 %sum, ptr %p
134+
135+
ret i32 %sum
136+
}
137+
138+
; Calls @test_cannot_promote_1
139+
define i32 @caller_ptr_args(i64 %n, ptr %p1, ptr %p2) {
140+
; CHECK-LABEL: define {{[^@]+}}@caller_ptr_args
141+
; CHECK-SAME: (i64 [[N:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]]) {
142+
; CHECK-NEXT: call void @memset(ptr [[P1]], i64 0, i64 [[N]])
143+
; CHECK-NEXT: store i32 5, ptr [[P2]], align 4
144+
; CHECK-NEXT: [[RES:%.*]] = call i32 @test_cannot_promote_1(ptr [[P1]], ptr [[P2]])
145+
; CHECK-NEXT: ret i32 [[RES]]
146+
;
147+
call void @memset(ptr %p1, i64 0, i64 %n)
148+
149+
store i32 5, ptr %p2
150+
151+
%res = call i32 @test_cannot_promote_1(ptr %p1, ptr %p2)
152+
153+
ret i32 %res
154+
}
155+
156+
; Calls @test_cannot_promote_2
157+
; Calls @test_cannot_promote_3
158+
define i32 @caller_aliased_args() {
159+
; CHECK-LABEL: define {{[^@]+}}@caller_aliased_args() {
160+
; CHECK-NEXT: [[CALLER_C:%.*]] = alloca i32, align 4
161+
; CHECK-NEXT: store i32 5, ptr [[CALLER_C]], align 4
162+
; CHECK-NEXT: [[RES1:%.*]] = call i32 @test_cannot_promote_2(ptr [[CALLER_C]], ptr [[CALLER_C]])
163+
; CHECK-NEXT: [[RES2:%.*]] = call i32 @test_cannot_promote_3(ptr [[CALLER_C]], ptr [[CALLER_C]])
164+
; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES1]], [[RES2]]
165+
; CHECK-NEXT: ret i32 [[RES]]
166+
;
167+
%caller_c = alloca i32
168+
store i32 5, ptr %caller_c
169+
170+
%res1 = call i32 @test_cannot_promote_2(ptr %caller_c, ptr %caller_c)
171+
%res2 = call i32 @test_cannot_promote_3(ptr %caller_c, ptr %caller_c)
172+
173+
%res = add i32 %res1, %res2
174+
175+
ret i32 %res
176+
}
177+
178+
; Calls @test_cannot_promote_3
179+
; Calls @test_can_promote_1
180+
; Calls @test_can_promote_2
181+
define i32 @caller_safe_args_1(i64 %n) {
182+
; CHECK-LABEL: define {{[^@]+}}@caller_safe_args_1
183+
; CHECK-SAME: (i64 [[N:%.*]]) {
184+
; CHECK-NEXT: [[P:%.*]] = alloca [5 x double], i64 [[N]], align 8
185+
; CHECK-NEXT: call void @memset(ptr [[P]], i64 0, i64 [[N]])
186+
; CHECK-NEXT: [[CALLER_C:%.*]] = alloca i32, align 4
187+
; CHECK-NEXT: store i32 5, ptr [[CALLER_C]], align 4
188+
; CHECK-NEXT: [[RES1:%.*]] = call i32 @test_cannot_promote_3(ptr [[P]], ptr [[CALLER_C]])
189+
; CHECK-NEXT: [[RES2:%.*]] = call i32 @test_can_promote_1(ptr [[P]], ptr [[CALLER_C]])
190+
; CHECK-NEXT: [[RES3:%.*]] = call i32 @test_can_promote_2(ptr [[P]], ptr [[CALLER_C]])
191+
; CHECK-NEXT: [[RES12:%.*]] = add i32 [[RES1]], [[RES2]]
192+
; CHECK-NEXT: [[RES:%.*]] = add i32 [[RES12]], [[RES3]]
193+
; CHECK-NEXT: ret i32 [[RES]]
194+
;
195+
%p = alloca [5 x double], i64 %n
196+
call void @memset(ptr %p, i64 0, i64 %n)
197+
198+
%caller_c = alloca i32
199+
store i32 5, ptr %caller_c
200+
201+
%res1 = call i32 @test_cannot_promote_3(ptr %p, ptr %caller_c)
202+
%res2 = call i32 @test_can_promote_1(ptr %p, ptr %caller_c)
203+
%res3 = call i32 @test_can_promote_2(ptr %p, ptr %caller_c)
204+
205+
%res12 = add i32 %res1, %res2
206+
%res = add i32 %res12, %res3
207+
208+
ret i32 %res
209+
}
210+
211+
; Calls @test_can_promote_2
212+
define i32 @caller_safe_args_2(i64 %n, ptr %p) {
213+
; CHECK-LABEL: define {{[^@]+}}@caller_safe_args_2
214+
; CHECK-SAME: (i64 [[N:%.*]], ptr [[P:%.*]]) {
215+
; CHECK-NEXT: call void @memset(ptr [[P]], i64 0, i64 [[N]])
216+
; CHECK-NEXT: [[CALLER_C:%.*]] = alloca i32, align 4
217+
; CHECK-NEXT: store i32 5, ptr [[CALLER_C]], align 4
218+
; CHECK-NEXT: [[RES:%.*]] = call i32 @test_can_promote_2(ptr [[P]], ptr [[CALLER_C]])
219+
; CHECK-NEXT: ret i32 [[RES]]
220+
;
221+
call void @memset(ptr %p, i64 0, i64 %n)
222+
223+
%caller_c = alloca i32
224+
store i32 5, ptr %caller_c
225+
226+
%res = call i32 @test_can_promote_2(ptr %p, ptr %caller_c)
227+
228+
ret i32 %res
229+
}
230+
231+
declare void @memset(ptr, i64, i64)

0 commit comments

Comments
 (0)