Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SROA / non-capturing-call-readonly.ll
blob3756afadbf884a8ea645fd380f6ac3a48d0ca424
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
3 ; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
5 define i32 @alloca_used_in_call(ptr %data, i64 %n) {
6 ; CHECK-LABEL: @alloca_used_in_call(
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
9 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
10 ; CHECK-NEXT:    br label [[LOOP:%.*]]
11 ; CHECK:       loop:
12 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
13 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
14 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
15 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
16 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
17 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
18 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
19 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
20 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
21 ; CHECK:       exit:
22 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])
23 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
24 ; CHECK-NEXT:    ret i32 [[I1]]
26 entry:
27   %retval = alloca i32, align 4
28   store i32 0, ptr %retval, align 4
29   br label %loop
31 loop:
32   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
33   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
34   %ld = load i32, ptr %arrayidx, align 4
35   %rdx = load i32, ptr %retval, align 4
36   %rdx.inc = add nsw i32 %rdx, %ld
37   store i32 %rdx.inc, ptr %retval, align 4
38   %indvars.iv.next = add nsw i64 %indvars.iv, 1
39   %exitcond = icmp ne i64 %indvars.iv.next, %n
40   br i1 %exitcond, label %loop, label %exit
42 exit:
43   %i0 = call i32 @user_of_alloca(ptr %retval)
44   %i1 = load i32, ptr %retval, align 4
45   ret i32 %i1
48 define i32 @alloca_captured_in_call(ptr %data, i64 %n) {
49 ; CHECK-LABEL: @alloca_captured_in_call(
50 ; CHECK-NEXT:  entry:
51 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
52 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
53 ; CHECK-NEXT:    br label [[LOOP:%.*]]
54 ; CHECK:       loop:
55 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
56 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
57 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
58 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
59 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
60 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
61 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
62 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
63 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
64 ; CHECK:       exit:
65 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(ptr [[RETVAL]])
66 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
67 ; CHECK-NEXT:    ret i32 [[I1]]
69 entry:
70   %retval = alloca i32, align 4
71   store i32 0, ptr %retval, align 4
72   br label %loop
74 loop:
75   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
76   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
77   %ld = load i32, ptr %arrayidx, align 4
78   %rdx = load i32, ptr %retval, align 4
79   %rdx.inc = add nsw i32 %rdx, %ld
80   store i32 %rdx.inc, ptr %retval, align 4
81   %indvars.iv.next = add nsw i64 %indvars.iv, 1
82   %exitcond = icmp ne i64 %indvars.iv.next, %n
83   br i1 %exitcond, label %loop, label %exit
85 exit:
86   %i0 = call i32 @capture_of_alloca(ptr %retval)
87   %i1 = load i32, ptr %retval, align 4
88   ret i32 %i1
91 define i32 @alloca_not_captured_as_per_operand_attr(ptr %data, i64 %n) {
92 ; CHECK-LABEL: @alloca_not_captured_as_per_operand_attr(
93 ; CHECK-NEXT:  entry:
94 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
95 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
96 ; CHECK-NEXT:    br label [[LOOP:%.*]]
97 ; CHECK:       loop:
98 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
99 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
100 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
101 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
102 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
103 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
104 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
105 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
106 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
107 ; CHECK:       exit:
108 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(ptr nocapture [[RETVAL]])
109 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
110 ; CHECK-NEXT:    ret i32 [[I1]]
112 entry:
113   %retval = alloca i32, align 4
114   store i32 0, ptr %retval, align 4
115   br label %loop
117 loop:
118   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
119   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
120   %ld = load i32, ptr %arrayidx, align 4
121   %rdx = load i32, ptr %retval, align 4
122   %rdx.inc = add nsw i32 %rdx, %ld
123   store i32 %rdx.inc, ptr %retval, align 4
124   %indvars.iv.next = add nsw i64 %indvars.iv, 1
125   %exitcond = icmp ne i64 %indvars.iv.next, %n
126   br i1 %exitcond, label %loop, label %exit
128 exit:
129   %i0 = call i32 @capture_of_alloca(ptr nocapture %retval)
130   %i1 = load i32, ptr %retval, align 4
131   ret i32 %i1
134 define i32 @alloca_not_captured_and_readonly_as_per_operand_attr(ptr %data, i64 %n) {
135 ; CHECK-LABEL: @alloca_not_captured_and_readonly_as_per_operand_attr(
136 ; CHECK-NEXT:  entry:
137 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
138 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
139 ; CHECK-NEXT:    br label [[LOOP:%.*]]
140 ; CHECK:       loop:
141 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
142 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
143 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
144 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
145 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
146 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
147 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
148 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
149 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
150 ; CHECK:       exit:
151 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(ptr nocapture readonly [[RETVAL]])
152 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
153 ; CHECK-NEXT:    ret i32 [[I1]]
155 entry:
156   %retval = alloca i32, align 4
157   store i32 0, ptr %retval, align 4
158   br label %loop
160 loop:
161   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
162   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
163   %ld = load i32, ptr %arrayidx, align 4
164   %rdx = load i32, ptr %retval, align 4
165   %rdx.inc = add nsw i32 %rdx, %ld
166   store i32 %rdx.inc, ptr %retval, align 4
167   %indvars.iv.next = add nsw i64 %indvars.iv, 1
168   %exitcond = icmp ne i64 %indvars.iv.next, %n
169   br i1 %exitcond, label %loop, label %exit
171 exit:
172   %i0 = call i32 @capture_of_alloca(ptr nocapture readonly %retval)
173   %i1 = load i32, ptr %retval, align 4
174   ret i32 %i1
177 define i32 @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase_attr(ptr %data, i64 %n) {
178 ; CHECK-LABEL: @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase_attr(
179 ; CHECK-NEXT:  entry:
180 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
181 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
182 ; CHECK-NEXT:    br label [[LOOP:%.*]]
183 ; CHECK:       loop:
184 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
185 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
186 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
187 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
188 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
189 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
190 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
191 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
192 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
193 ; CHECK:       exit:
194 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(ptr nocapture [[RETVAL]]) #[[ATTR2:[0-9]+]]
195 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
196 ; CHECK-NEXT:    ret i32 [[I1]]
198 entry:
199   %retval = alloca i32, align 4
200   store i32 0, ptr %retval, align 4
201   br label %loop
203 loop:
204   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
205   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
206   %ld = load i32, ptr %arrayidx, align 4
207   %rdx = load i32, ptr %retval, align 4
208   %rdx.inc = add nsw i32 %rdx, %ld
209   store i32 %rdx.inc, ptr %retval, align 4
210   %indvars.iv.next = add nsw i64 %indvars.iv, 1
211   %exitcond = icmp ne i64 %indvars.iv.next, %n
212   br i1 %exitcond, label %loop, label %exit
214 exit:
215   %i0 = call i32 @capture_of_alloca(ptr nocapture %retval) readonly
216   %i1 = load i32, ptr %retval, align 4
217   ret i32 %i1
220 define i32 @alloca_not_readonly_as_per_operand_attr(ptr %data, i64 %n) {
221 ; CHECK-LABEL: @alloca_not_readonly_as_per_operand_attr(
222 ; CHECK-NEXT:  entry:
223 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
224 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
225 ; CHECK-NEXT:    br label [[LOOP:%.*]]
226 ; CHECK:       loop:
227 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
228 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
229 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
230 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
231 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
232 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
233 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
234 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
235 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
236 ; CHECK:       exit:
237 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_of_alloca(ptr readonly [[RETVAL]])
238 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
239 ; CHECK-NEXT:    ret i32 [[I1]]
241 entry:
242   %retval = alloca i32, align 4
243   store i32 0, ptr %retval, align 4
244   br label %loop
246 loop:
247   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
248   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
249   %ld = load i32, ptr %arrayidx, align 4
250   %rdx = load i32, ptr %retval, align 4
251   %rdx.inc = add nsw i32 %rdx, %ld
252   store i32 %rdx.inc, ptr %retval, align 4
253   %indvars.iv.next = add nsw i64 %indvars.iv, 1
254   %exitcond = icmp ne i64 %indvars.iv.next, %n
255   br i1 %exitcond, label %loop, label %exit
257 exit:
258   %i0 = call i32 @capture_of_alloca(ptr readonly %retval)
259   %i1 = load i32, ptr %retval, align 4
260   ret i32 %i1
263 define i32 @alloca_with_gep_used_in_call(ptr %data, i64 %n) {
264 ; CHECK-LABEL: @alloca_with_gep_used_in_call(
265 ; CHECK-NEXT:  entry:
266 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
267 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
268 ; CHECK-NEXT:    br label [[LOOP:%.*]]
269 ; CHECK:       loop:
270 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
271 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
272 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
273 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
274 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
275 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
276 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
277 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
278 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
279 ; CHECK:       exit:
280 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])
281 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
282 ; CHECK-NEXT:    ret i32 [[I1]]
284 entry:
285   %retval = alloca i32, align 4
286   store i32 0, ptr %retval, align 4
287   br label %loop
289 loop:
290   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
291   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
292   %ld = load i32, ptr %arrayidx, align 4
293   %rdx = load i32, ptr %retval, align 4
294   %rdx.inc = add nsw i32 %rdx, %ld
295   store i32 %rdx.inc, ptr %retval, align 4
296   %indvars.iv.next = add nsw i64 %indvars.iv, 1
297   %exitcond = icmp ne i64 %indvars.iv.next, %n
298   br i1 %exitcond, label %loop, label %exit
300 exit:
301   %i0 = call i32 @user_of_alloca(ptr %retval)
302   %i1 = load i32, ptr %retval, align 4
303   ret i32 %i1
306 define i32 @alloca_captured_second_arg(ptr %data, i64 %n) {
307 ; CHECK-LABEL: @alloca_captured_second_arg(
308 ; CHECK-NEXT:  entry:
309 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
310 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
311 ; CHECK-NEXT:    br label [[LOOP:%.*]]
312 ; CHECK:       loop:
313 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
314 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
315 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
316 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
317 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
318 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
319 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
320 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
321 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
322 ; CHECK:       exit:
323 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @capture_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL]])
324 ; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4
325 ; CHECK-NEXT:    ret i32 [[I1]]
327 entry:
328   %retval = alloca i32, align 4
329   store i32 0, ptr %retval, align 4
330   br label %loop
332 loop:
333   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
334   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
335   %ld = load i32, ptr %arrayidx, align 4
336   %rdx = load i32, ptr %retval, align 4
337   %rdx.inc = add nsw i32 %rdx, %ld
338   store i32 %rdx.inc, ptr %retval, align 4
339   %indvars.iv.next = add nsw i64 %indvars.iv, 1
340   %exitcond = icmp ne i64 %indvars.iv.next, %n
341   br i1 %exitcond, label %loop, label %exit
343 exit:
344   %i0 = call i32 @capture_with_multiple_args(ptr %retval, ptr %retval)
345   %i1 = load i32, ptr %retval, align 4
346   ret i32 %i1
349 define i32 @alloca_used_in_maybe_throwing_call(ptr %data, i64 %n) personality ptr @__gxx_personality_v0  {
350 ; CHECK-LABEL: @alloca_used_in_maybe_throwing_call(
351 ; CHECK-NEXT:  entry:
352 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
353 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
354 ; CHECK-NEXT:    br label [[LOOP:%.*]]
355 ; CHECK:       loop:
356 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
357 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
358 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
359 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
360 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
361 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
362 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
363 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
364 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
365 ; CHECK:       exit:
366 ; CHECK-NEXT:    [[I0:%.*]] = invoke i32 @user_of_alloca(ptr [[RETVAL]])
367 ; CHECK-NEXT:    to label [[CONT:%.*]] unwind label [[UW:%.*]]
368 ; CHECK:       cont:
369 ; CHECK-NEXT:    br label [[END:%.*]]
370 ; CHECK:       uw:
371 ; CHECK-NEXT:    [[I1:%.*]] = landingpad { ptr, i32 }
372 ; CHECK-NEXT:    catch ptr null
373 ; CHECK-NEXT:    br label [[END]]
374 ; CHECK:       end:
375 ; CHECK-NEXT:    [[I2:%.*]] = load i32, ptr [[RETVAL]], align 4
376 ; CHECK-NEXT:    ret i32 [[I2]]
378 entry:
379   %retval = alloca i32, align 4
380   store i32 0, ptr %retval, align 4
381   br label %loop
383 loop:
384   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
385   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
386   %ld = load i32, ptr %arrayidx, align 4
387   %rdx = load i32, ptr %retval, align 4
388   %rdx.inc = add nsw i32 %rdx, %ld
389   store i32 %rdx.inc, ptr %retval, align 4
390   %indvars.iv.next = add nsw i64 %indvars.iv, 1
391   %exitcond = icmp ne i64 %indvars.iv.next, %n
392   br i1 %exitcond, label %loop, label %exit
394 exit:
395   %i0 = invoke i32 @user_of_alloca(ptr %retval) to label %cont unwind label %uw
397 cont:
398   br label %end
401   %i1 = landingpad { ptr, i32 } catch ptr null
402   br label %end
404 end:
405   %i2 = load i32, ptr %retval, align 4
406   ret i32 %i2
409 define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(ptr %data, i64 %n) personality ptr @__gxx_personality_v0  {
410 ; CHECK-LABEL: @alloca_used_in_maybe_throwing_call_with_same_dests(
411 ; CHECK-NEXT:  entry:
412 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
413 ; CHECK-NEXT:    store i32 0, ptr [[RETVAL]], align 4
414 ; CHECK-NEXT:    br label [[LOOP:%.*]]
415 ; CHECK:       loop:
416 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
417 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
418 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
419 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
420 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
421 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
422 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
423 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
424 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
425 ; CHECK:       exit:
426 ; CHECK-NEXT:    [[I0:%.*]] = invoke i32 @user_of_alloca(ptr [[RETVAL]])
427 ; CHECK-NEXT:    to label [[END:%.*]] unwind label [[UW:%.*]]
428 ; CHECK:       uw:
429 ; CHECK-NEXT:    [[I1:%.*]] = landingpad { ptr, i32 }
430 ; CHECK-NEXT:    catch ptr null
431 ; CHECK-NEXT:    br label [[END]]
432 ; CHECK:       end:
433 ; CHECK-NEXT:    [[I2:%.*]] = load i32, ptr [[RETVAL]], align 4
434 ; CHECK-NEXT:    ret i32 [[I2]]
436 entry:
437   %retval = alloca i32, align 4
438   store i32 0, ptr %retval, align 4
439   br label %loop
441 loop:
442   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
443   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
444   %ld = load i32, ptr %arrayidx, align 4
445   %rdx = load i32, ptr %retval, align 4
446   %rdx.inc = add nsw i32 %rdx, %ld
447   store i32 %rdx.inc, ptr %retval, align 4
448   %indvars.iv.next = add nsw i64 %indvars.iv, 1
449   %exitcond = icmp ne i64 %indvars.iv.next, %n
450   br i1 %exitcond, label %loop, label %exit
452 exit:
453   %i0 = invoke i32 @user_of_alloca(ptr %retval) to label %end unwind label %uw
456   %i1 = landingpad { ptr, i32 } catch ptr null
457   br label %end
459 end:
460   %i2 = load i32, ptr %retval, align 4
461   ret i32 %i2
464 define [2 x i32] @part_of_alloca_used_in_call(ptr %data, i64 %n) {
465 ; CHECK-LABEL: @part_of_alloca_used_in_call(
466 ; CHECK-NEXT:  entry:
467 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
468 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
469 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
470 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
471 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
472 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
473 ; CHECK-NEXT:    br label [[LOOP:%.*]]
474 ; CHECK:       loop:
475 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
476 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
477 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
478 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
479 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
480 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
481 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
482 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
483 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
484 ; CHECK:       exit:
485 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])
486 ; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
487 ; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
488 ; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0
489 ; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
490 ; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
491 ; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
492 ; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
494 entry:
495   %retval.full = alloca [2 x i32], align 4
496   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
497   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
498   br label %loop
500 loop:
501   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
502   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
503   %ld = load i32, ptr %arrayidx, align 4
504   %rdx = load i32, ptr %retval, align 4
505   %rdx.inc = add nsw i32 %rdx, %ld
506   store i32 %rdx.inc, ptr %retval, align 4
507   %indvars.iv.next = add nsw i64 %indvars.iv, 1
508   %exitcond = icmp ne i64 %indvars.iv.next, %n
509   br i1 %exitcond, label %loop, label %exit
511 exit:
512   %i0 = call i32 @user_of_alloca(ptr %retval)
513   %i1 = load [2 x i32], ptr %retval.full, align 4
514   ret [2 x i32] %i1
517 define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args(ptr %data, i64 %n) {
518 ; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args(
519 ; CHECK-NEXT:  entry:
520 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
521 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
522 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
523 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
524 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
525 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
526 ; CHECK-NEXT:    br label [[LOOP:%.*]]
527 ; CHECK:       loop:
528 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
529 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
530 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
531 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
532 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
533 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
534 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
535 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
536 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
537 ; CHECK:       exit:
538 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])
539 ; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
540 ; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
541 ; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0
542 ; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
543 ; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
544 ; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
545 ; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
547 entry:
548   %retval.full = alloca [2 x i32], align 4
549   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
550   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
551   br label %loop
553 loop:
554   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
555   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
556   %ld = load i32, ptr %arrayidx, align 4
557   %rdx = load i32, ptr %retval, align 4
558   %rdx.inc = add nsw i32 %rdx, %ld
559   store i32 %rdx.inc, ptr %retval, align 4
560   %indvars.iv.next = add nsw i64 %indvars.iv, 1
561   %exitcond = icmp ne i64 %indvars.iv.next, %n
562   br i1 %exitcond, label %loop, label %exit
564 exit:
565   %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)
566   %i1 = load [2 x i32], ptr %retval.full, align 4
567   ret [2 x i32] %i1
570 define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_before_call(ptr %data, i64 %n) {
571 ; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_before_call(
572 ; CHECK-NEXT:  entry:
573 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
574 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
575 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
576 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
577 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
578 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
579 ; CHECK-NEXT:    br label [[LOOP:%.*]]
580 ; CHECK:       loop:
581 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
582 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
583 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
584 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
585 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
586 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
587 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
588 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
589 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
590 ; CHECK:       exit:
591 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[RETVAL_FULL]], ptr [[RETVAL]], i32 4, i1 false)
592 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])
593 ; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
594 ; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
595 ; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0
596 ; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
597 ; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
598 ; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
599 ; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
601 entry:
602   %retval.full = alloca [2 x i32], align 4
603   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
604   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
605   br label %loop
607 loop:
608   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
609   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
610   %ld = load i32, ptr %arrayidx, align 4
611   %rdx = load i32, ptr %retval, align 4
612   %rdx.inc = add nsw i32 %rdx, %ld
613   store i32 %rdx.inc, ptr %retval, align 4
614   %indvars.iv.next = add nsw i64 %indvars.iv, 1
615   %exitcond = icmp ne i64 %indvars.iv.next, %n
616   br i1 %exitcond, label %loop, label %exit
618 exit:
619   call void @llvm.memcpy.p0.p0.i32(ptr %retval.full, ptr %retval, i32 4, i1 false)
620   %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)
621   %i1 = load [2 x i32], ptr %retval.full, align 4
622   ret [2 x i32] %i1
625 define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_after_call(ptr %data, i64 %n) {
626 ; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_after_call(
627 ; CHECK-NEXT:  entry:
628 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
629 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
630 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
631 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
632 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
633 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
634 ; CHECK-NEXT:    br label [[LOOP:%.*]]
635 ; CHECK:       loop:
636 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
637 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
638 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
639 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
640 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
641 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
642 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
643 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
644 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
645 ; CHECK:       exit:
646 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])
647 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr [[RETVAL_FULL]], ptr [[RETVAL]], i32 4, i1 false)
648 ; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
649 ; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
650 ; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0
651 ; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
652 ; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
653 ; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
654 ; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
656 entry:
657   %retval.full = alloca [2 x i32], align 4
658   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
659   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
660   br label %loop
662 loop:
663   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
664   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
665   %ld = load i32, ptr %arrayidx, align 4
666   %rdx = load i32, ptr %retval, align 4
667   %rdx.inc = add nsw i32 %rdx, %ld
668   store i32 %rdx.inc, ptr %retval, align 4
669   %indvars.iv.next = add nsw i64 %indvars.iv, 1
670   %exitcond = icmp ne i64 %indvars.iv.next, %n
671   br i1 %exitcond, label %loop, label %exit
673 exit:
674   %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)
675   call void @llvm.memcpy.p0.p0.i32(ptr %retval.full, ptr %retval, i32 4, i1 false)
676   %i1 = load [2 x i32], ptr %retval.full, align 4
677   ret [2 x i32] %i1
680 define [2 x i32] @part_of_alloca_used_in_call_with_multiple_args(ptr %data, i64 %n) {
681 ; CHECK-LABEL: @part_of_alloca_used_in_call_with_multiple_args(
682 ; CHECK-NEXT:  entry:
683 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
684 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
685 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
686 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
687 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
688 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
689 ; CHECK-NEXT:    br label [[LOOP:%.*]]
690 ; CHECK:       loop:
691 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
692 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
693 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
694 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
695 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
696 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
697 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
698 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
699 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
700 ; CHECK:       exit:
701 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL]])
702 ; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
703 ; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
704 ; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0
705 ; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
706 ; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
707 ; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
708 ; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
710 entry:
711   %retval.full = alloca [2 x i32], align 4
712   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
713   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
714   br label %loop
716 loop:
717   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
718   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
719   %ld = load i32, ptr %arrayidx, align 4
720   %rdx = load i32, ptr %retval, align 4
721   %rdx.inc = add nsw i32 %rdx, %ld
722   store i32 %rdx.inc, ptr %retval, align 4
723   %indvars.iv.next = add nsw i64 %indvars.iv, 1
724   %exitcond = icmp ne i64 %indvars.iv.next, %n
725   br i1 %exitcond, label %loop, label %exit
727 exit:
728   %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval)
729   %i1 = load [2 x i32], ptr %retval.full, align 4
730   ret [2 x i32] %i1
733 define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(ptr %data, i64 %n) {
734 ; CHECK-LABEL: @all_parts_of_alloca_used_in_calls_with_multiple_args(
735 ; CHECK-NEXT:  entry:
736 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
737 ; CHECK-NEXT:    [[SOME_ANOTHER_ALLOCA_FULL:%.*]] = alloca [42 x i32], align 4
738 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
739 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
740 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
741 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
742 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
743 ; CHECK-NEXT:    br label [[LOOP:%.*]]
744 ; CHECK:       loop:
745 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]
746 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]
747 ; CHECK-NEXT:    [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
748 ; CHECK-NEXT:    [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4
749 ; CHECK-NEXT:    [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]
750 ; CHECK-NEXT:    store i32 [[RDX_INC]], ptr [[RETVAL]], align 4
751 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
752 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]
753 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]
754 ; CHECK:       exit:
755 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])
756 ; CHECK-NEXT:    [[I1:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL_FULL]], ptr [[RETVAL]])
757 ; CHECK-NEXT:    [[I2:%.*]] = call i32 @capture_of_alloca(ptr [[SOME_ANOTHER_ALLOCA_FULL]])
758 ; CHECK-NEXT:    [[I3_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
759 ; CHECK-NEXT:    [[I3_FCA_0_LOAD:%.*]] = load i32, ptr [[I3_FCA_0_GEP]], align 4
760 ; CHECK-NEXT:    [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I3_FCA_0_LOAD]], 0
761 ; CHECK-NEXT:    [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
762 ; CHECK-NEXT:    [[I3_FCA_1_LOAD:%.*]] = load i32, ptr [[I3_FCA_1_GEP]], align 4
763 ; CHECK-NEXT:    [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[I3_FCA_1_LOAD]], 1
764 ; CHECK-NEXT:    ret [2 x i32] [[I3_FCA_1_INSERT]]
766 entry:
767   %retval.full = alloca [2 x i32], align 4
768   %some.another.alloca.full = alloca [42 x i32], align 4
769   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
770   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
771   br label %loop
773 loop:
774   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]
775   %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv
776   %ld = load i32, ptr %arrayidx, align 4
777   %rdx = load i32, ptr %retval, align 4
778   %rdx.inc = add nsw i32 %rdx, %ld
779   store i32 %rdx.inc, ptr %retval, align 4
780   %indvars.iv.next = add nsw i64 %indvars.iv, 1
781   %exitcond = icmp ne i64 %indvars.iv.next, %n
782   br i1 %exitcond, label %loop, label %exit
784 exit:
785   %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)
786   %i1 = call i32 @user_of_alloca_with_multiple_args(ptr %retval.full, ptr %retval)
787   %i2 = call i32 @capture_of_alloca(ptr %some.another.alloca.full)
788   %i3 = load [2 x i32], ptr %retval.full, align 4
789   ret [2 x i32] %i3
792 define i32 @all_uses_of_alloca_are_calls(ptr %data, i64 %n) {
793 ; CHECK-LABEL: @all_uses_of_alloca_are_calls(
794 ; CHECK-NEXT:  entry:
795 ; CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
796 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])
797 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])
798 ; CHECK-NEXT:    ret i32 0
800 entry:
801   %retval = alloca i32, align 4
802   call i32 @user_of_alloca(ptr %retval)
803   call i32 @user_of_alloca(ptr %retval)
804   ret i32 0
807 declare void @llvm.lifetime.start.p0(i64 immarg, ptr)
809 define i64 @do_schedule_instrs_for_dce_after_fixups() {
810 ; CHECK-LABEL: @do_schedule_instrs_for_dce_after_fixups(
811 ; CHECK-NEXT:  entry:
812 ; CHECK-NEXT:    [[C:%.*]] = alloca i64, align 2
813 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 1, ptr [[C]])
814 ; CHECK-NEXT:    store i64 0, ptr [[C]], align 4
815 ; CHECK-NEXT:    br label [[IF_END:%.*]]
816 ; CHECK:       if.end:
817 ; CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 1
818 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @user_of_alloca(ptr [[ADD_PTR]])
819 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[C]], align 4
820 ; CHECK-NEXT:    ret i64 [[LD]]
822 entry:
823   %c = alloca i64, align 2
824   call void @llvm.lifetime.start.p0(i64 1, ptr %c)
825   store i64 0, ptr %c
826   br label %if.end
828 if.end:                                           ; preds = %entry
829   %add.ptr = getelementptr inbounds i32, ptr %c, i64 1
830   call i32 @user_of_alloca(ptr %add.ptr)
831   %ld = load i64, ptr %c
832   ret i64 %ld
835 define void @dont_transform_store_only() {
836 ; CHECK-LABEL: @dont_transform_store_only(
837 ; CHECK-NEXT:  entry:
838 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
839 ; CHECK-NEXT:    store i8 0, ptr [[A]], align 1
840 ; CHECK-NEXT:    call void @byte_user_of_alloca(ptr [[A]])
841 ; CHECK-NEXT:    ret void
843 entry:
844   %a = alloca i8
845   store i8 0, ptr %a
846   call void @byte_user_of_alloca(ptr %a)
847   ret void
849 define i8 @dont_transform_load_only() {
850 ; CHECK-LABEL: @dont_transform_load_only(
851 ; CHECK-NEXT:  entry:
852 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
853 ; CHECK-NEXT:    call void @byte_user_of_alloca(ptr [[A]])
854 ; CHECK-NEXT:    [[R:%.*]] = load i8, ptr [[A]], align 1
855 ; CHECK-NEXT:    ret i8 [[R]]
857 entry:
858   %a = alloca i8
859   call void @byte_user_of_alloca(ptr %a)
860   %r = load i8, ptr %a
861   ret i8 %r
863 define i8 @transform_load_and_store() {
864 ; CHECK-LABEL: @transform_load_and_store(
865 ; CHECK-NEXT:  entry:
866 ; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 1
867 ; CHECK-NEXT:    store i8 0, ptr [[A]], align 1
868 ; CHECK-NEXT:    call void @byte_user_of_alloca(ptr [[A]])
869 ; CHECK-NEXT:    [[R:%.*]] = load i8, ptr [[A]], align 1
870 ; CHECK-NEXT:    ret i8 [[R]]
872 entry:
873   %a = alloca i8
874   store i8 0, ptr %a
875   call void @byte_user_of_alloca(ptr %a)
876   %r = load i8, ptr %a
877   ret i8 %r
880 define [2 x i32] @select_of_ptrs(ptr %data, i1 %c, i32 %v) {
881 ; CHECK-LABEL: @select_of_ptrs(
882 ; CHECK-NEXT:  entry:
883 ; CHECK-NEXT:    [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4
884 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
885 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_0_GEP]], align 4
886 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
887 ; CHECK-NEXT:    store i32 0, ptr [[DOTFCA_1_GEP]], align 4
888 ; CHECK-NEXT:    [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1
889 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], ptr [[RETVAL_FULL]], ptr [[RETVAL]]
890 ; CHECK-NEXT:    store i32 [[V:%.*]], ptr [[PTR]], align 4
891 ; CHECK-NEXT:    [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL_FULL]])
892 ; CHECK-NEXT:    [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0
893 ; CHECK-NEXT:    [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4
894 ; CHECK-NEXT:    [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0
895 ; CHECK-NEXT:    [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1
896 ; CHECK-NEXT:    [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4
897 ; CHECK-NEXT:    [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1
898 ; CHECK-NEXT:    ret [2 x i32] [[I1_FCA_1_INSERT]]
900 entry:
901   %retval.full = alloca [2 x i32], align 4
902   store [2 x i32] zeroinitializer, ptr %retval.full, align 4
903   %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1
904   %ptr = select i1 %c, ptr %retval.full, ptr %retval
905   store i32 %v, ptr %ptr
906   %i0 = call i32 @user_of_alloca(ptr %retval.full)
907   %i1 = load [2 x i32], ptr %retval.full, align 4
908   ret [2 x i32] %i1
911 declare dso_local i32 @user_of_alloca(ptr nocapture readonly)
912 declare dso_local i32 @user_of_alloca_with_multiple_args(ptr nocapture readonly, ptr nocapture readonly)
913 declare dso_local i32 @capture_of_alloca(ptr)
914 declare dso_local i32 @capture_with_multiple_args(ptr nocapture readonly, ptr)
916 declare dso_local void @byte_user_of_alloca(ptr nocapture readonly)
918 declare dso_local i32 @__gxx_personality_v0(...)
920 declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1)
921 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
922 ; CHECK-MODIFY-CFG: {{.*}}
923 ; CHECK-PRESERVE-CFG: {{.*}}