1; RUN: opt -safe-stack -safe-stack-coloring=1 -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s
2; RUN: opt -safe-stack -safe-stack-coloring=1 -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s
3
4; x and y share the stack slot.
5define void @f() safestack {
6; CHECK-LABEL: define void @f
7entry:
8; CHECK:  %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
9; CHECK:   getelementptr i8, i8* %[[USP]], i32 -16
10
11  %x = alloca i32, align 4
12  %y = alloca i32, align 4
13  %z = alloca i32, align 4
14  %x0 = bitcast i32* %x to i8*
15  %y0 = bitcast i32* %y to i8*
16  %z0 = bitcast i32* %z to i8*
17
18  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %z0)
19  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
20
21; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
22  call void @capture32(i32* %x)
23  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
24  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
25
26; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
27  call void @capture32(i32* %y)
28  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0)
29
30; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
31  call void @capture32(i32* %z)
32  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %z0)
33
34  ret void
35}
36
37define void @no_markers() safestack {
38; CHECK-LABEL: define void @no_markers(
39entry:
40; CHECK:  %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
41; CHECK:   getelementptr i8, i8* %[[USP]], i32 -16
42
43  %x = alloca i32, align 4
44  %y = alloca i32, align 4
45  %x0 = bitcast i32* %x to i8*
46
47  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
48
49; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
50  call void @capture32(i32* %x)
51  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
52
53; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
54  call void @capture32(i32* %y)
55
56  ret void
57}
58
59; x and y can't share memory, but they can split z's storage.
60define void @g() safestack {
61; CHECK-LABEL: define void @g
62entry:
63; CHECK:  %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
64; CHECK:   getelementptr i8, i8* %[[USP]], i32 -16
65
66  %x = alloca i32, align 4
67  %y = alloca i32, align 4
68  %z = alloca i64, align 4
69  %x0 = bitcast i32* %x to i8*
70  %y0 = bitcast i32* %y to i8*
71  %z0 = bitcast i64* %z to i8*
72
73  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
74  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
75
76; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
77  call void @capture32(i32* %x)
78  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
79
80; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
81  call void @capture32(i32* %y)
82  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0)
83  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %z0)
84
85; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
86  call void @capture64(i64* %z)
87  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %z0)
88
89  ret void
90}
91
92; Both y and z fit in x's alignment gap.
93define void @h() safestack {
94; CHECK-LABEL: define void @h
95entry:
96; CHECK:  %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
97; CHECK:   getelementptr i8, i8* %[[USP]], i32 -16
98
99  %x = alloca i32, align 16
100  %z = alloca i64, align 4
101  %y = alloca i32, align 4
102  %x0 = bitcast i32* %x to i8*
103  %y0 = bitcast i32* %y to i8*
104  %z0 = bitcast i64* %z to i8*
105
106  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
107  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
108  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %z0)
109
110; CHECK:   getelementptr i8, i8* %[[USP]], i32 -16
111  call void @capture32(i32* %x)
112
113; CHECK:   getelementptr i8, i8* %[[USP]], i32 -12
114  call void @capture32(i32* %y)
115
116; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
117  call void @capture64(i64* %z)
118
119  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
120  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0)
121  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %z0)
122
123  ret void
124}
125
126; void f(bool a, bool b) {
127;   long x1, x2; capture64(&x1); capture64(&x2);
128;   if (a) {
129;     long y; capture64(&y);
130;     if (b) {
131;       long y1; capture64(&y1);
132;     } else {
133;       long y2; capture64(&y2);
134;     }
135;   } else {
136;     long z; capture64(&z);
137;     if (b) {
138;       long z1; capture64(&z1);
139;     } else {
140;       long z2; capture64(&z2);
141;     }
142;   }
143; }
144; Everything fits in 4 x 64-bit slots.
145define void @i(i1 zeroext %a, i1 zeroext %b) safestack {
146; CHECK-LABEL: define void @i
147entry:
148; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
149; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -32
150  %x1 = alloca i64, align 8
151  %x2 = alloca i64, align 8
152  %y = alloca i64, align 8
153  %y1 = alloca i64, align 8
154  %y2 = alloca i64, align 8
155  %z = alloca i64, align 8
156  %z1 = alloca i64, align 8
157  %z2 = alloca i64, align 8
158  %0 = bitcast i64* %x1 to i8*
159  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0)
160  %1 = bitcast i64* %x2 to i8*
161  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %1)
162; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
163; CHECK:   call void @capture64(
164  call void @capture64(i64* nonnull %x1)
165; CHECK:   getelementptr i8, i8* %[[USP]], i32 -16
166; CHECK:   call void @capture64(
167  call void @capture64(i64* nonnull %x2)
168  br i1 %a, label %if.then, label %if.else4
169
170if.then:                                          ; preds = %entry
171  %2 = bitcast i64* %y to i8*
172  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %2)
173; CHECK:   getelementptr i8, i8* %[[USP]], i32 -24
174; CHECK:   call void @capture64(
175  call void @capture64(i64* nonnull %y)
176  br i1 %b, label %if.then3, label %if.else
177
178if.then3:                                         ; preds = %if.then
179  %3 = bitcast i64* %y1 to i8*
180  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %3)
181; CHECK:   getelementptr i8, i8* %[[USP]], i32 -32
182; CHECK:   call void @capture64(
183  call void @capture64(i64* nonnull %y1)
184  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %3)
185  br label %if.end
186
187if.else:                                          ; preds = %if.then
188  %4 = bitcast i64* %y2 to i8*
189  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %4)
190; CHECK:   getelementptr i8, i8* %[[USP]], i32 -32
191; CHECK:   call void @capture64(
192  call void @capture64(i64* nonnull %y2)
193  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %4)
194  br label %if.end
195
196if.end:                                           ; preds = %if.else, %if.then3
197  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %2)
198  br label %if.end9
199
200if.else4:                                         ; preds = %entry
201  %5 = bitcast i64* %z to i8*
202  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5)
203; CHECK:   getelementptr i8, i8* %[[USP]], i32 -24
204; CHECK:   call void @capture64(
205  call void @capture64(i64* nonnull %z)
206  br i1 %b, label %if.then6, label %if.else7
207
208if.then6:                                         ; preds = %if.else4
209  %6 = bitcast i64* %z1 to i8*
210  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6)
211; CHECK:   getelementptr i8, i8* %[[USP]], i32 -32
212; CHECK:   call void @capture64(
213  call void @capture64(i64* nonnull %z1)
214  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %6)
215  br label %if.end8
216
217if.else7:                                         ; preds = %if.else4
218  %7 = bitcast i64* %z2 to i8*
219  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7)
220; CHECK:   getelementptr i8, i8* %[[USP]], i32 -32
221; CHECK:   call void @capture64(
222  call void @capture64(i64* nonnull %z2)
223  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %7)
224  br label %if.end8
225
226if.end8:                                          ; preds = %if.else7, %if.then6
227  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %5)
228  br label %if.end9
229
230if.end9:                                          ; preds = %if.end8, %if.end
231  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %1)
232  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
233  ret void
234}
235
236; lifetime for x ends in 2 different BBs
237define void @no_merge1(i1 %d) safestack {
238; CHECK-LABEL: define void @no_merge1(
239entry:
240; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
241; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
242  %x = alloca i32, align 4
243  %y = alloca i32, align 4
244  %x0 = bitcast i32* %x to i8*
245  %y0 = bitcast i32* %y to i8*
246  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
247; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
248; CHECK:   call void @capture32(
249  call void @capture32(i32* %x)
250  br i1 %d, label %bb2, label %bb3
251bb2:
252  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
253; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
254; CHECK:   call void @capture32(
255  call void @capture32(i32* %y)
256  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0)
257  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
258  ret void
259bb3:
260  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
261  ret void
262}
263
264define void @merge1(i1 %d) safestack {
265; CHECK-LABEL: define void @merge1(
266entry:
267; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
268; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
269  %x = alloca i32, align 4
270  %y = alloca i32, align 4
271  %x0 = bitcast i32* %x to i8*
272  %y0 = bitcast i32* %y to i8*
273  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
274; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
275; CHECK:   call void @capture32(
276  call void @capture32(i32* %x)
277  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
278  br i1 %d, label %bb2, label %bb3
279bb2:
280  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
281; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
282; CHECK:   call void @capture32(
283  call void @capture32(i32* %y)
284  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0)
285  ret void
286bb3:
287  ret void
288}
289
290; Missing lifetime.end
291define void @merge2_noend(i1 %d) safestack {
292; CHECK-LABEL: define void @merge2_noend(
293entry:
294; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
295; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
296  %x = alloca i32, align 4
297  %y = alloca i32, align 4
298  %x0 = bitcast i32* %x to i8*
299  %y0 = bitcast i32* %y to i8*
300  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
301; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
302; CHECK:   call void @capture32(
303  call void @capture32(i32* %x)
304  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
305  br i1 %d, label %bb2, label %bb3
306bb2:
307  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
308; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
309; CHECK:   call void @capture32(
310  call void @capture32(i32* %y)
311  ret void
312bb3:
313  ret void
314}
315
316; Missing lifetime.end
317define void @merge3_noend(i1 %d) safestack {
318; CHECK-LABEL: define void @merge3_noend(
319entry:
320; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
321; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
322  %x = alloca i32, align 4
323  %y = alloca i32, align 4
324  %x0 = bitcast i32* %x to i8*
325  %y0 = bitcast i32* %y to i8*
326  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0)
327; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
328; CHECK:   call void @capture32(
329  call void @capture32(i32* %x)
330  br i1 %d, label %bb2, label %bb3
331bb2:
332  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
333  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
334; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
335; CHECK:   call void @capture32(
336  call void @capture32(i32* %y)
337  ret void
338bb3:
339  ret void
340}
341
342; Missing lifetime.start
343define void @nomerge4_nostart(i1 %d) safestack {
344; CHECK-LABEL: define void @nomerge4_nostart(
345entry:
346; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
347; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
348  %x = alloca i32, align 4
349  %y = alloca i32, align 4
350  %x0 = bitcast i32* %x to i8*
351  %y0 = bitcast i32* %y to i8*
352; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
353; CHECK:   call void @capture32(
354  call void @capture32(i32* %x)
355  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0)
356  br i1 %d, label %bb2, label %bb3
357bb2:
358  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0)
359; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
360; CHECK:   call void @capture32(
361  call void @capture32(i32* %y)
362  ret void
363bb3:
364  ret void
365}
366
367define void @array_merge() safestack {
368; CHECK-LABEL: define void @array_merge(
369entry:
370; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
371; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -800
372  %A.i1 = alloca [100 x i32], align 4
373  %B.i2 = alloca [100 x i32], align 4
374  %A.i = alloca [100 x i32], align 4
375  %B.i = alloca [100 x i32], align 4
376  %0 = bitcast [100 x i32]* %A.i to i8*
377  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0)
378  %1 = bitcast [100 x i32]* %B.i to i8*
379  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %1)
380; CHECK:   getelementptr i8, i8* %[[USP]], i32 -400
381; CHECK:   call void @capture100x32(
382  call void @capture100x32([100 x i32]* %A.i)
383; CHECK:   getelementptr i8, i8* %[[USP]], i32 -800
384; CHECK:   call void @capture100x32(
385  call void @capture100x32([100 x i32]* %B.i)
386  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
387  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %1)
388  %2 = bitcast [100 x i32]* %A.i1 to i8*
389  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %2)
390  %3 = bitcast [100 x i32]* %B.i2 to i8*
391  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %3)
392; CHECK:   getelementptr i8, i8* %[[USP]], i32 -400
393; CHECK:   call void @capture100x32(
394  call void @capture100x32([100 x i32]* %A.i1)
395; CHECK:   getelementptr i8, i8* %[[USP]], i32 -800
396; CHECK:   call void @capture100x32(
397  call void @capture100x32([100 x i32]* %B.i2)
398  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %2)
399  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %3)
400  ret void
401}
402
403define void @myCall_pr15707() safestack {
404; CHECK-LABEL: define void @myCall_pr15707(
405entry:
406; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
407; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -200000
408  %buf1 = alloca i8, i32 100000, align 16
409  %buf2 = alloca i8, i32 100000, align 16
410
411  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %buf1)
412  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %buf1)
413
414  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %buf1)
415  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %buf2)
416  call void @capture8(i8* %buf1)
417  call void @capture8(i8* %buf2)
418  ret void
419}
420
421; Check that we don't assert and crash even when there are allocas
422; outside the declared lifetime regions.
423define void @bad_range() safestack {
424; CHECK-LABEL: define void @bad_range(
425entry:
426; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
427; A.i and B.i unsafe, not merged
428; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -800
429; A.i1 and B.i2 safe
430; CHECK: = alloca [100 x i32], align 4
431; CHECK: = alloca [100 x i32], align 4
432
433  %A.i1 = alloca [100 x i32], align 4
434  %B.i2 = alloca [100 x i32], align 4
435  %A.i = alloca [100 x i32], align 4
436  %B.i = alloca [100 x i32], align 4
437  %0 = bitcast [100 x i32]* %A.i to i8*
438  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0) nounwind
439  %1 = bitcast [100 x i32]* %B.i to i8*
440  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %1) nounwind
441  call void @capture100x32([100 x i32]* %A.i)
442  call void @capture100x32([100 x i32]* %B.i)
443  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0) nounwind
444  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %1) nounwind
445  br label %block2
446
447block2:
448  ; I am used outside the marked lifetime.
449  call void @capture100x32([100 x i32]* %A.i)
450  call void @capture100x32([100 x i32]* %B.i)
451  ret void
452}
453
454%struct.Klass = type { i32, i32 }
455
456define i32 @shady_range(i32 %argc, i8** nocapture %argv) safestack {
457; CHECK-LABEL: define i32 @shady_range(
458entry:
459; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
460; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -64
461  %a.i = alloca [4 x %struct.Klass], align 16
462  %b.i = alloca [4 x %struct.Klass], align 16
463  %a8 = bitcast [4 x %struct.Klass]* %a.i to i8*
464  %b8 = bitcast [4 x %struct.Klass]* %b.i to i8*
465  ; I am used outside the lifetime zone below:
466  %z2 = getelementptr inbounds [4 x %struct.Klass], [4 x %struct.Klass]* %a.i, i64 0, i64 0, i32 0
467  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a8)
468  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %b8)
469  call void @capture8(i8* %a8)
470  call void @capture8(i8* %b8)
471  %z3 = load i32, i32* %z2, align 16
472  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %a8)
473  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %b8)
474  ret i32 %z3
475}
476
477define void @end_loop() safestack {
478; CHECK-LABEL: define void @end_loop()
479entry:
480; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
481; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
482  %x = alloca i8, align 4
483  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) nounwind
484  br label %l2
485
486l2:
487  call void @capture8(i8* %x)
488  call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) nounwind
489  br label %l2
490}
491
492; Check that @x and @y get distinct stack slots => @x lifetime does not break
493; when control re-enters l2.
494define void @start_loop() safestack {
495; CHECK-LABEL: define void @start_loop()
496entry:
497; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
498; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -16
499  %x = alloca i8, align 4
500  %y = alloca i8, align 4
501  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) nounwind
502  br label %l2
503
504l2:
505; CHECK:   getelementptr i8, i8* %[[USP]], i32 -8
506  call void @llvm.lifetime.start.p0i8(i64 4, i8* %y) nounwind
507  call void @capture8(i8* %y)
508  call void @llvm.lifetime.end.p0i8(i64 4, i8* %y) nounwind
509
510; CHECK:   getelementptr i8, i8* %[[USP]], i32 -4
511  call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) nounwind
512  call void @capture8(i8* %x)
513  br label %l2
514}
515
516; This test checks for a bug where the stack coloring algorithm was not tracking
517; the live range of allocas through phi instructions, so it did not consider
518; alloca and alloca2 to be live at the same time.  As a result it was using
519; the same stack slot for both allocas.  To ensure this bug isn't present, we
520; check that there are 64 bytes allocated for the unsafe stack which is enough
521; space for both allocas.
522; CHECK-LABEL: @stack_coloring_liveness_bug
523define void @stack_coloring_liveness_bug(i32 %arg0) #0 {
524entry:
525; CHECK:        %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
526; CHECK-NEXT:   getelementptr i8, i8* %[[USP]], i32 -64
527  %alloca = alloca [32 x i8], align 16
528  %alloca2 = alloca [32 x i8], align 16
529  %cond = icmp eq i32 %arg0, 0
530  br i1 %cond, label %if, label %else
531
532if:
533  %alloca.if = bitcast [32 x i8]* %alloca to i8*
534  br label %end
535
536else:
537; CHECK:   getelementptr i8, i8* %[[USP]], i32 -32
538  %alloca.else = bitcast [32 x i8]* %alloca to i8*
539  call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %alloca.else)
540  call void @capture8(i8* %alloca.else)
541  call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %alloca.else)
542  br label %end
543
544end:
545; CHECK:   getelementptr i8, i8* %[[USP]], i32 -64
546  %alloca.end = phi i8* [ %alloca.if, %if], [%alloca.else, %else]
547  %alloca2.bitcast = bitcast [32 x i8]* %alloca2 to i8*
548  call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %alloca2.bitcast)
549  call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %alloca.end)
550  call void @capture2_8(i8* %alloca2.bitcast, i8* %alloca.end)
551  call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %alloca2.bitcast)
552  call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %alloca.end)
553  ret void
554}
555
556attributes #0 = { safestack }
557
558declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
559declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
560declare void @capture8(i8*)
561declare void @capture32(i32*)
562declare void @capture64(i64*)
563declare void @capture100x32([100 x i32]*)
564declare void @capture2_8(i8*, i8*)
565