xref: /llvm-project/llvm/test/CodeGen/X86/StackColoring.ll (revision 2b63077cfa13095b3e64f79fe825cc85ca9da7be)
1; RUN: llc -mcpu=corei7 -no-stack-coloring=false < %s | FileCheck %s --check-prefix=YESCOLOR --check-prefix=CHECK
2; RUN: llc -mcpu=corei7 -no-stack-coloring=false -stackcoloring-lifetime-start-on-first-use=false < %s | FileCheck %s --check-prefix=NOFIRSTUSE --check-prefix=CHECK
3; RUN: llc -mcpu=corei7 -no-stack-coloring=true  < %s | FileCheck %s --check-prefix=NOCOLOR --check-prefix=CHECK
4
5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6target triple = "x86_64-apple-macosx10.8.0"
7
8;CHECK-LABEL: myCall_w2:
9;YESCOLOR: subq  $144, %rsp
10;NOCOLOR: subq  $272, %rsp
11
12define i32 @myCall_w2(i32 %in) {
13entry:
14  %a = alloca [17 x ptr], align 8
15  %a2 = alloca [16 x ptr], align 8
16  call void @llvm.lifetime.start.p0(i64 -1, ptr %a)
17  %t1 = call i32 @foo(i32 %in, ptr %a)
18  %t2 = call i32 @foo(i32 %in, ptr %a)
19  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
20  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
21  %t3 = call i32 @foo(i32 %in, ptr %a2)
22  %t4 = call i32 @foo(i32 %in, ptr %a2)
23  call void @llvm.lifetime.end.p0(i64 -1, ptr %a2)
24  %t5 = add i32 %t1, %t2
25  %t6 = add i32 %t3, %t4
26  %t7 = add i32 %t5, %t6
27  ret i32 %t7
28}
29
30
31;CHECK-LABEL: myCall2_no_merge
32;YESCOLOR: subq  $272, %rsp
33;NOCOLOR: subq  $272, %rsp
34
35define i32 @myCall2_no_merge(i32 %in, i1 %d) {
36entry:
37  %a = alloca [17 x ptr], align 8
38  %a2 = alloca [16 x ptr], align 8
39  call void @llvm.lifetime.start.p0(i64 -1, ptr %a)
40  %t1 = call i32 @foo(i32 %in, ptr %a)
41  %t2 = call i32 @foo(i32 %in, ptr %a)
42  br i1 %d, label %bb2, label %bb3
43bb2:
44  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
45  %t3 = call i32 @foo(i32 %in, ptr %a2)
46  %t4 = call i32 @foo(i32 %in, ptr %a2)
47  call void @llvm.lifetime.end.p0(i64 -1, ptr %a2)
48  %t5 = add i32 %t1, %t2
49  %t6 = add i32 %t3, %t4
50  %t7 = add i32 %t5, %t6
51  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
52  ret i32 %t7
53bb3:
54  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
55  ret i32 0
56}
57
58;CHECK-LABEL: myCall2_w2
59;YESCOLOR: subq  $144, %rsp
60;NOCOLOR: subq  $272, %rsp
61
62define i32 @myCall2_w2(i32 %in, i1 %d) {
63entry:
64  %a = alloca [17 x ptr], align 8
65  %a2 = alloca [16 x ptr], align 8
66  call void @llvm.lifetime.start.p0(i64 -1, ptr %a)
67  %t1 = call i32 @foo(i32 %in, ptr %a)
68  %t2 = call i32 @foo(i32 %in, ptr %a)
69  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
70  br i1 %d, label %bb2, label %bb3
71bb2:
72  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
73  %t3 = call i32 @foo(i32 %in, ptr %a2)
74  %t4 = call i32 @foo(i32 %in, ptr %a2)
75  call void @llvm.lifetime.end.p0(i64 -1, ptr %a2)
76  %t5 = add i32 %t1, %t2
77  %t6 = add i32 %t3, %t4
78  %t7 = add i32 %t5, %t6
79  ret i32 %t7
80bb3:
81  ret i32 0
82}
83
84;CHECK-LABEL: myCall_w4:
85;YESCOLOR: subq  $112, %rsp
86;NOFIRSTUSE: subq  $208, %rsp
87;NOCOLOR: subq  $400, %rsp
88
89define i32 @myCall_w4(i32 %in) {
90entry:
91  %a1 = alloca [14 x ptr], align 8
92  %a2 = alloca [13 x ptr], align 8
93  %a3 = alloca [12 x ptr], align 8
94  %a4 = alloca [11 x ptr], align 8
95  call void @llvm.lifetime.start.p0(i64 -1, ptr %a4)
96  call void @llvm.lifetime.start.p0(i64 -1, ptr %a1)
97  %t1 = call i32 @foo(i32 %in, ptr %a1)
98  %t2 = call i32 @foo(i32 %in, ptr %a1)
99  call void @llvm.lifetime.end.p0(i64 -1, ptr %a1)
100  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
101  %t9 = call i32 @foo(i32 %in, ptr %a2)
102  %t8 = call i32 @foo(i32 %in, ptr %a2)
103  call void @llvm.lifetime.end.p0(i64 -1, ptr %a2)
104  call void @llvm.lifetime.start.p0(i64 -1, ptr %a3)
105  %t3 = call i32 @foo(i32 %in, ptr %a3)
106  %t4 = call i32 @foo(i32 %in, ptr %a3)
107  call void @llvm.lifetime.end.p0(i64 -1, ptr %a3)
108  %t11 = call i32 @foo(i32 %in, ptr %a4)
109  call void @llvm.lifetime.end.p0(i64 -1, ptr %a4)
110  %t5 = add i32 %t1, %t2
111  %t6 = add i32 %t3, %t4
112  %t7 = add i32 %t5, %t6
113  ret i32 %t7
114}
115
116;CHECK-LABEL: myCall2_w4:
117;YESCOLOR: subq  $112, %rsp
118;NOCOLOR: subq  $400, %rsp
119
120define i32 @myCall2_w4(i32 %in) {
121entry:
122  %a1 = alloca [14 x ptr], align 8
123  %a2 = alloca [13 x ptr], align 8
124  %a3 = alloca [12 x ptr], align 8
125  %a4 = alloca [11 x ptr], align 8
126  call void @llvm.lifetime.start.p0(i64 -1, ptr %a1)
127  %t1 = call i32 @foo(i32 %in, ptr %a1)
128  %t2 = call i32 @foo(i32 %in, ptr %a1)
129  call void @llvm.lifetime.end.p0(i64 -1, ptr %a1)
130  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
131  %t9 = call i32 @foo(i32 %in, ptr %a2)
132  %t8 = call i32 @foo(i32 %in, ptr %a2)
133  call void @llvm.lifetime.end.p0(i64 -1, ptr %a2)
134  call void @llvm.lifetime.start.p0(i64 -1, ptr %a3)
135  %t3 = call i32 @foo(i32 %in, ptr %a3)
136  %t4 = call i32 @foo(i32 %in, ptr %a3)
137  call void @llvm.lifetime.end.p0(i64 -1, ptr %a3)
138  br i1 poison, label %bb2, label %bb3
139bb2:
140  call void @llvm.lifetime.start.p0(i64 -1, ptr %a4)
141  %t11 = call i32 @foo(i32 %in, ptr %a4)
142  call void @llvm.lifetime.end.p0(i64 -1, ptr %a4)
143  %t5 = add i32 %t1, %t2
144  %t6 = add i32 %t3, %t4
145  %t7 = add i32 %t5, %t6
146  ret i32 %t7
147bb3:
148  ret i32 0
149}
150
151
152;CHECK-LABEL: myCall2_noend:
153;YESCOLOR: subq  $144, %rsp
154;NOCOLOR: subq  $272, %rsp
155
156
157define i32 @myCall2_noend(i32 %in, i1 %d) {
158entry:
159  %a = alloca [17 x ptr], align 8
160  %a2 = alloca [16 x ptr], align 8
161  call void @llvm.lifetime.start.p0(i64 -1, ptr %a)
162  %t1 = call i32 @foo(i32 %in, ptr %a)
163  %t2 = call i32 @foo(i32 %in, ptr %a)
164  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
165  br i1 %d, label %bb2, label %bb3
166bb2:
167  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
168  %t3 = call i32 @foo(i32 %in, ptr %a2)
169  %t4 = call i32 @foo(i32 %in, ptr %a2)
170  %t5 = add i32 %t1, %t2
171  %t6 = add i32 %t3, %t4
172  %t7 = add i32 %t5, %t6
173  ret i32 %t7
174bb3:
175  ret i32 0
176}
177
178;CHECK-LABEL: myCall2_noend2:
179;YESCOLOR: subq  $144, %rsp
180;NOCOLOR: subq  $272, %rsp
181define i32 @myCall2_noend2(i32 %in, i1 %d) {
182entry:
183  %a = alloca [17 x ptr], align 8
184  %a2 = alloca [16 x ptr], align 8
185  call void @llvm.lifetime.start.p0(i64 -1, ptr %a)
186  %t1 = call i32 @foo(i32 %in, ptr %a)
187  %t2 = call i32 @foo(i32 %in, ptr %a)
188  br i1 %d, label %bb2, label %bb3
189bb2:
190  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
191  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
192  %t3 = call i32 @foo(i32 %in, ptr %a2)
193  %t4 = call i32 @foo(i32 %in, ptr %a2)
194  %t5 = add i32 %t1, %t2
195  %t6 = add i32 %t3, %t4
196  %t7 = add i32 %t5, %t6
197  ret i32 %t7
198bb3:
199  ret i32 0
200}
201
202
203;CHECK-LABEL: myCall2_nostart:
204;YESCOLOR: subq  $272, %rsp
205;NOCOLOR: subq  $272, %rsp
206define i32 @myCall2_nostart(i32 %in, i1 %d) {
207entry:
208  %a = alloca [17 x ptr], align 8
209  %a2 = alloca [16 x ptr], align 8
210  %t1 = call i32 @foo(i32 %in, ptr %a)
211  %t2 = call i32 @foo(i32 %in, ptr %a)
212  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
213  br i1 %d, label %bb2, label %bb3
214bb2:
215  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
216  %t3 = call i32 @foo(i32 %in, ptr %a2)
217  %t4 = call i32 @foo(i32 %in, ptr %a2)
218  %t5 = add i32 %t1, %t2
219  %t6 = add i32 %t3, %t4
220  %t7 = add i32 %t5, %t6
221  ret i32 %t7
222bb3:
223  ret i32 0
224}
225
226; Adopt the test from Transforms/Inline/array_merge.ll'
227;CHECK-LABEL: array_merge:
228;YESCOLOR: subq  $808, %rsp
229;NOCOLOR: subq  $1608, %rsp
230define void @array_merge() nounwind ssp {
231entry:
232  %A.i1 = alloca [100 x i32], align 4
233  %B.i2 = alloca [100 x i32], align 4
234  %A.i = alloca [100 x i32], align 4
235  %B.i = alloca [100 x i32], align 4
236  call void @llvm.lifetime.start.p0(i64 -1, ptr %A.i) nounwind
237  call void @llvm.lifetime.start.p0(i64 -1, ptr %B.i) nounwind
238  call void @bar(ptr %A.i, ptr %B.i) nounwind
239  call void @llvm.lifetime.end.p0(i64 -1, ptr %A.i) nounwind
240  call void @llvm.lifetime.end.p0(i64 -1, ptr %B.i) nounwind
241  call void @llvm.lifetime.start.p0(i64 -1, ptr %A.i1) nounwind
242  call void @llvm.lifetime.start.p0(i64 -1, ptr %B.i2) nounwind
243  call void @bar(ptr %A.i1, ptr %B.i2) nounwind
244  call void @llvm.lifetime.end.p0(i64 -1, ptr %A.i1) nounwind
245  call void @llvm.lifetime.end.p0(i64 -1, ptr %B.i2) nounwind
246  ret void
247}
248
249;CHECK-LABEL: func_phi_lifetime:
250;YESCOLOR: subq  $272, %rsp
251;NOCOLOR: subq  $272, %rsp
252define i32 @func_phi_lifetime(i32 %in, i1 %d) {
253entry:
254  %a = alloca [17 x ptr], align 8
255  %a2 = alloca [16 x ptr], align 8
256  %t1 = call i32 @foo(i32 %in, ptr %a)
257  %t2 = call i32 @foo(i32 %in, ptr %a)
258  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
259  br i1 %d, label %bb0, label %bb1
260
261bb0:
262  br label %bb2
263
264bb1:
265  br label %bb2
266
267bb2:
268  %split = phi ptr [ %a, %bb0 ], [ %a2, %bb1 ]
269  call void @llvm.lifetime.start.p0(i64 -1, ptr %split)
270  %t3 = call i32 @foo(i32 %in, ptr %a2)
271  %t4 = call i32 @foo(i32 %in, ptr %a2)
272  %t5 = add i32 %t1, %t2
273  %t6 = add i32 %t3, %t4
274  %t7 = add i32 %t5, %t6
275  call void @llvm.lifetime.end.p0(i64 -1, ptr %split)
276  ret i32 %t7
277bb3:
278  ret i32 0
279}
280
281
282;CHECK-LABEL: multi_region_bb:
283;YESCOLOR: subq  $272, %rsp
284;NOCOLOR: subq  $272, %rsp
285
286define void @multi_region_bb() nounwind ssp {
287entry:
288  %A.i1 = alloca [100 x i32], align 4
289  %B.i2 = alloca [100 x i32], align 4
290  %A.i = alloca [100 x i32], align 4
291  %B.i = alloca [100 x i32], align 4
292  call void @llvm.lifetime.start.p0(i64 -1, ptr %A.i) nounwind ; <---- start #1
293  call void @llvm.lifetime.start.p0(i64 -1, ptr %B.i) nounwind
294  call void @bar(ptr %A.i, ptr %B.i) nounwind
295  call void @llvm.lifetime.end.p0(i64 -1, ptr %A.i) nounwind
296  call void @llvm.lifetime.end.p0(i64 -1, ptr %B.i) nounwind
297  call void @llvm.lifetime.start.p0(i64 -1, ptr %A.i1) nounwind
298  call void @llvm.lifetime.start.p0(i64 -1, ptr %B.i2) nounwind
299  call void @llvm.lifetime.start.p0(i64 -1, ptr %A.i) nounwind  ; <---- start #2
300  call void @bar(ptr %A.i1, ptr %B.i2) nounwind
301  call void @llvm.lifetime.end.p0(i64 -1, ptr %A.i1) nounwind
302  call void @llvm.lifetime.end.p0(i64 -1, ptr %A.i) nounwind
303  call void @llvm.lifetime.end.p0(i64 -1, ptr %B.i2) nounwind
304  ret void
305}
306
307define i32 @myCall_end_before_begin(i32 %in, i1 %d) {
308entry:
309  %a = alloca [17 x ptr], align 8
310  %a2 = alloca [16 x ptr], align 8
311  %t1 = call i32 @foo(i32 %in, ptr %a)
312  %t2 = call i32 @foo(i32 %in, ptr %a)
313  call void @llvm.lifetime.end.p0(i64 -1, ptr %a)
314  call void @llvm.lifetime.start.p0(i64 -1, ptr %a)
315  br i1 %d, label %bb2, label %bb3
316bb2:
317  call void @llvm.lifetime.start.p0(i64 -1, ptr %a2)
318  %t3 = call i32 @foo(i32 %in, ptr %a2)
319  %t4 = call i32 @foo(i32 %in, ptr %a2)
320  %t5 = add i32 %t1, %t2
321  %t6 = add i32 %t3, %t4
322  %t7 = add i32 %t5, %t6
323  ret i32 %t7
324bb3:
325  ret i32 0
326}
327
328
329; Regression test for PR15707.  %buf1 and %buf2 should not be merged
330; in this test case.
331;CHECK-LABEL: myCall_pr15707:
332;NOFIRSTUSE: subq $200008, %rsp
333;NOCOLOR: subq $200008, %rsp
334define void @myCall_pr15707() {
335  %buf1 = alloca i8, i32 100000, align 16
336  %buf2 = alloca i8, i32 100000, align 16
337
338  call void @llvm.lifetime.start.p0(i64 -1, ptr %buf1)
339  call void @llvm.lifetime.end.p0(i64 -1, ptr %buf1)
340
341  call void @llvm.lifetime.start.p0(i64 -1, ptr %buf1)
342  call void @llvm.lifetime.start.p0(i64 -1, ptr %buf2)
343  %result1 = call i32 @foo(i32 0, ptr %buf1)
344  %result2 = call i32 @foo(i32 0, ptr %buf2)
345  ret void
346}
347
348
349; Check that we don't assert and crash even when there are allocas
350; outside the declared lifetime regions.
351;CHECK-LABEL: bad_range:
352define void @bad_range() nounwind ssp {
353entry:
354  %A.i1 = alloca [100 x i32], align 4
355  %B.i2 = alloca [100 x i32], align 4
356  %A.i = alloca [100 x i32], align 4
357  %B.i = alloca [100 x i32], align 4
358  call void @llvm.lifetime.start.p0(i64 -1, ptr %A.i) nounwind
359  call void @llvm.lifetime.start.p0(i64 -1, ptr %B.i) nounwind
360  call void @bar(ptr %A.i, ptr %B.i) nounwind
361  call void @llvm.lifetime.end.p0(i64 -1, ptr %A.i) nounwind
362  call void @llvm.lifetime.end.p0(i64 -1, ptr %B.i) nounwind
363  br label %block2
364
365block2:
366  ; I am used outside the marked lifetime.
367  call void @bar(ptr %A.i, ptr %B.i) nounwind
368  ret void
369}
370
371
372; Check that we don't assert and crash even when there are usages
373; of allocas which do not read or write outside the declared lifetime regions.
374;CHECK-LABEL: shady_range:
375
376%struct.Klass = type { i32, i32 }
377
378define i32 @shady_range(i32 %argc, ptr nocapture %argv) uwtable {
379  %a.i = alloca [4 x %struct.Klass], align 16
380  %b.i = alloca [4 x %struct.Klass], align 16
381  ; I am used outside the lifetime zone below:
382  call void @llvm.lifetime.start.p0(i64 -1, ptr %a.i)
383  call void @llvm.lifetime.start.p0(i64 -1, ptr %b.i)
384  %z3 = load i32, ptr %a.i, align 16
385  %r = call i32 @foo(i32 %z3, ptr %a.i)
386  %r2 = call i32 @foo(i32 %z3, ptr %b.i)
387  call void @llvm.lifetime.end.p0(i64 -1, ptr %a.i)
388  call void @llvm.lifetime.end.p0(i64 -1, ptr %b.i)
389  ret i32 9
390}
391
392; In this case 'itar1' and 'itar2' can't be overlapped if we treat
393; lifetime.start as the beginning of the lifetime, but we can
394; overlap if we consider first use of the slot as lifetime
395; start. See llvm bug 25776.
396
397;CHECK-LABEL: ifthen_twoslots:
398;YESCOLOR: subq  $1544, %rsp
399;NOFIRSTUSE: subq $2056, %rsp
400;NOCOLOR: subq  $2568, %rsp
401
402define i32 @ifthen_twoslots(i32 %x) #0 {
403entry:
404  %b1 = alloca [128 x i32], align 16
405  %b2 = alloca [128 x i32], align 16
406  %b3 = alloca [128 x i32], align 16
407  %b4 = alloca [128 x i32], align 16
408  %b5 = alloca [128 x i32], align 16
409  call void @llvm.lifetime.start.p0(i64 512, ptr %b1)
410  call void @llvm.lifetime.start.p0(i64 512, ptr %b2)
411  %and = and i32 %x, 1
412  %tobool = icmp eq i32 %and, 0
413  br i1 %tobool, label %if.else, label %if.then
414
415if.then:                                          ; preds = %entry
416  call void @llvm.lifetime.start.p0(i64 512, ptr %b3)
417  call void @initb(ptr %b1, ptr %b3, ptr null)
418  call void @llvm.lifetime.end.p0(i64 512, ptr %b3)
419  br label %if.end
420
421if.else:                                          ; preds = %entry
422  call void @llvm.lifetime.start.p0(i64 512, ptr %b4)
423  call void @llvm.lifetime.start.p0(i64 512, ptr %b5)
424  call void @initb(ptr %b2, ptr %b4, ptr %b5) #3
425  call void @llvm.lifetime.end.p0(i64 512, ptr %b5)
426  call void @llvm.lifetime.end.p0(i64 512, ptr %b4)
427  br label %if.end
428
429if.end:                                           ; preds = %if.else, %if.then
430  call void @llvm.lifetime.end.p0(i64 512, ptr %b2)
431  call void @llvm.lifetime.end.p0(i64 512, ptr %b1)
432  ret i32 0
433
434}
435
436; This function is intended to test the case where you
437; have a reference to a stack slot that lies outside of
438; the START/END lifetime markers-- the flow analysis
439; should catch this and build the lifetime based on the
440; markers only.
441
442;CHECK-LABEL: while_loop:
443;YESCOLOR: subq  $1032, %rsp
444;NOFIRSTUSE: subq  $1544, %rsp
445;NOCOLOR: subq  $1544, %rsp
446
447define i32 @while_loop(i32 %x) #0 {
448entry:
449  %b1 = alloca [128 x i32], align 16
450  %b2 = alloca [128 x i32], align 16
451  %b3 = alloca [128 x i32], align 16
452  call void @llvm.lifetime.start.p0(i64 512, ptr %b1) #3
453  call void @llvm.lifetime.start.p0(i64 512, ptr %b2) #3
454  %and = and i32 %x, 1
455  %tobool = icmp eq i32 %and, 0
456  br i1 %tobool, label %if.else, label %if.then
457
458if.then:                                          ; preds = %entry
459  call void @inita(ptr %b2) #3
460  br label %if.end
461
462if.else:                                          ; preds = %entry
463  call void @inita(ptr %b1) #3
464  call void @inita(ptr %b3) #3
465  %tobool25 = icmp eq i32 %x, 0
466  br i1 %tobool25, label %if.end, label %while.body.lr.ph
467
468while.body.lr.ph:                                 ; preds = %if.else
469  br label %while.body
470
471while.body:                                       ; preds = %while.body.lr.ph, %while.body
472  %x.addr.06 = phi i32 [ %x, %while.body.lr.ph ], [ %dec, %while.body ]
473  %dec = add nsw i32 %x.addr.06, -1
474  call void @llvm.lifetime.start.p0(i64 512, ptr %b3) #3
475  call void @inita(ptr %b3) #3
476  call void @llvm.lifetime.end.p0(i64 512, ptr %b3) #3
477  %tobool2 = icmp eq i32 %dec, 0
478  br i1 %tobool2, label %if.end.loopexit, label %while.body
479
480if.end.loopexit:                                  ; preds = %while.body
481  br label %if.end
482
483if.end:                                           ; preds = %if.end.loopexit, %if.else, %if.then
484  call void @llvm.lifetime.end.p0(i64 512, ptr %b2) #3
485  call void @llvm.lifetime.end.p0(i64 512, ptr %b1) #3
486  ret i32 0
487}
488
489; Test case motivated by PR27903. Same routine inlined multiple times
490; into a caller results in a multi-segment lifetime, but the second
491; lifetime has no explicit references to the stack slot. Such slots
492; have to be treated conservatively.
493
494;CHECK-LABEL: twobod_b27903:
495;YESCOLOR: subq  $96, %rsp
496;NOFIRSTUSE: subq  $96, %rsp
497;NOCOLOR: subq  $96, %rsp
498
499define i32 @twobod_b27903(i32 %y, i32 %x) {
500entry:
501  %buffer.i = alloca [12 x i32], align 16
502  %abc = alloca [12 x i32], align 16
503  call void @llvm.lifetime.start.p0(i64 48, ptr %buffer.i)
504  %idxprom.i = sext i32 %y to i64
505  %arrayidx.i = getelementptr inbounds [12 x i32], ptr %buffer.i, i64 0, i64 %idxprom.i
506  call void @inita(ptr %arrayidx.i)
507  %add.i = add nsw i32 %x, %y
508  call void @llvm.lifetime.end.p0(i64 48, ptr %buffer.i)
509  %tobool = icmp eq i32 %y, 0
510  br i1 %tobool, label %if.end, label %if.then
511
512if.then:                                          ; preds = %entry
513  call void @llvm.lifetime.start.p0(i64 48, ptr %abc)
514  %arrayidx = getelementptr inbounds [12 x i32], ptr %abc, i64 0, i64 %idxprom.i
515  call void @inita(ptr %arrayidx)
516  call void @llvm.lifetime.start.p0(i64 48, ptr %buffer.i)
517  call void @inita(ptr %arrayidx.i)
518  %add.i9 = add nsw i32 %add.i, %y
519  call void @llvm.lifetime.end.p0(i64 48, ptr %buffer.i)
520  call void @llvm.lifetime.end.p0(i64 48, ptr %abc)
521  br label %if.end
522
523if.end:                                           ; preds = %if.then, %entry
524  %x.addr.0 = phi i32 [ %add.i9, %if.then ], [ %add.i, %entry ]
525  ret i32 %x.addr.0
526}
527
528;CHECK-LABEL: multi_segment:
529;YESCOLOR: subq  $256, %rsp
530;NOFIRSTUSE: subq  $256, %rsp
531;NOCOLOR: subq  $512, %rsp
532define i1 @multi_segment(i1, i1)
533{
534entry-block:
535  %foo = alloca [32 x i64]
536  %bar = alloca [32 x i64]
537  call void @llvm.lifetime.start.p0(i64 256, ptr %bar)
538  call void @baz(ptr %bar, i32 1)
539  call void @llvm.lifetime.end.p0(i64 256, ptr %bar)
540  call void @llvm.lifetime.start.p0(i64 256, ptr %foo)
541  call void @baz(ptr %foo, i32 1)
542  call void @llvm.lifetime.end.p0(i64 256, ptr %foo)
543  call void @llvm.lifetime.start.p0(i64 256, ptr %bar)
544  call void @baz(ptr %bar, i32 1)
545  call void @llvm.lifetime.end.p0(i64 256, ptr %bar)
546  ret i1 true
547}
548
549;CHECK-LABEL: pr32488:
550;YESCOLOR: subq  $256, %rsp
551;NOFIRSTUSE: subq  $256, %rsp
552;NOCOLOR: subq  $512, %rsp
553define i1 @pr32488(i1, i1)
554{
555entry-block:
556  %foo = alloca [32 x i64]
557  %bar = alloca [32 x i64]
558  br i1 %0, label %if_false, label %if_true
559if_false:
560  call void @llvm.lifetime.start.p0(i64 256, ptr %bar)
561  call void @baz(ptr %bar, i32 0)
562  br i1 %1, label %if_false.1, label %onerr
563if_false.1:
564  call void @llvm.lifetime.end.p0(i64 256, ptr %bar)
565  br label %merge
566if_true:
567  call void @llvm.lifetime.start.p0(i64 256, ptr %foo)
568  call void @baz(ptr %foo, i32 1)
569  br i1 %1, label %if_true.1, label %onerr
570if_true.1:
571  call void @llvm.lifetime.end.p0(i64 256, ptr %foo)
572  br label %merge
573merge:
574  ret i1 false
575onerr:
576  call void @llvm.lifetime.end.p0(i64 256, ptr %foo)
577  call void @llvm.lifetime.end.p0(i64 256, ptr %bar)
578  call void @destructor()
579  ret i1 true
580}
581
582%Data = type { [32 x i64] }
583
584declare void @destructor()
585
586declare void @inita(ptr)
587
588declare void @initb(ptr,ptr,ptr)
589
590declare void @bar(ptr , ptr) nounwind
591
592declare void @baz(ptr, i32)
593
594declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
595
596declare void @llvm.lifetime.end.p0(i64, ptr nocapture) nounwind
597
598declare i32 @foo(i32, ptr)
599