1; RUN: llc -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-I386 %s
2; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
3; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck --check-prefix=LINUX-KERNEL-X64 %s
4; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | FileCheck --check-prefix=DARWIN-X64 %s
5; RUN: llc -mtriple=amd64-pc-openbsd < %s -o - | FileCheck --check-prefix=OPENBSD-AMD64 %s
6
7%struct.foo = type { [16 x i8] }
8%struct.foo.0 = type { [4 x i8] }
9%struct.pair = type { i32, i32 }
10%struct.nest = type { %struct.pair, %struct.pair }
11%struct.vec = type { <4 x i32> }
12%class.A = type { [2 x i8] }
13%struct.deep = type { %union.anon }
14%union.anon = type { %struct.anon }
15%struct.anon = type { %struct.anon.0 }
16%struct.anon.0 = type { %union.anon.1 }
17%union.anon.1 = type { [2 x i8] }
18%struct.small = type { i8 }
19
20@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
21
22; test1a: array of [16 x i8]
23;         no ssp attribute
24; Requires no protector.
25define void @test1a(i8* %a) {
26entry:
27; LINUX-I386-LABEL: test1a:
28; LINUX-I386-NOT: calll __stack_chk_fail
29; LINUX-I386: .cfi_endproc
30
31; LINUX-X64-LABEL: test1a:
32; LINUX-X64-NOT: callq __stack_chk_fail
33; LINUX-X64: .cfi_endproc
34
35; LINUX-KERNEL-X64-LABEL: test1a:
36; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
37; LINUX-KERNEL-X64: .cfi_endproc
38
39; DARWIN-X64-LABEL: test1a:
40; DARWIN-X64-NOT: callq ___stack_chk_fail
41; DARWIN-X64: .cfi_endproc
42  %a.addr = alloca i8*, align 8
43  %buf = alloca [16 x i8], align 16
44  store i8* %a, i8** %a.addr, align 8
45  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
46  %0 = load i8** %a.addr, align 8
47  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
48  %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
49  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
50  ret void
51}
52
53; test1b: array of [16 x i8]
54;         ssp attribute
55; Requires protector.
56; Function Attrs: ssp
57define void @test1b(i8* %a) #0 {
58entry:
59; LINUX-I386-LABEL: test1b:
60; LINUX-I386: mov{{l|q}} %gs:
61; LINUX-I386: calll __stack_chk_fail
62
63; LINUX-X64-LABEL: test1b:
64; LINUX-X64: mov{{l|q}} %fs:
65; LINUX-X64: callq __stack_chk_fail
66
67; LINUX-KERNEL-X64-LABEL: test1b:
68; LINUX-KERNEL-X64: mov{{l|q}} %gs:
69; LINUX-KERNEL-X64: callq __stack_chk_fail
70
71; DARWIN-X64-LABEL: test1b:
72; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
73; DARWIN-X64: callq ___stack_chk_fail
74
75; OPENBSD-AMD64-LABEL: test1b:
76; OPENBSD-AMD64: movq __guard_local(%rip)
77; OPENBSD-AMD64: callq __stack_smash_handler
78  %a.addr = alloca i8*, align 8
79  %buf = alloca [16 x i8], align 16
80  store i8* %a, i8** %a.addr, align 8
81  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
82  %0 = load i8** %a.addr, align 8
83  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
84  %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
85  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
86  ret void
87}
88
89; test1c: array of [16 x i8]
90;         sspstrong attribute
91; Requires protector.
92; Function Attrs: sspstrong
93define void @test1c(i8* %a) #1 {
94entry:
95; LINUX-I386-LABEL: test1c:
96; LINUX-I386: mov{{l|q}} %gs:
97; LINUX-I386: calll __stack_chk_fail
98
99; LINUX-X64-LABEL: test1c:
100; LINUX-X64: mov{{l|q}} %fs:
101; LINUX-X64: callq __stack_chk_fail
102
103; LINUX-KERNEL-X64-LABEL: test1c:
104; LINUX-KERNEL-X64: mov{{l|q}} %gs:
105; LINUX-KERNEL-X64: callq __stack_chk_fail
106
107; DARWIN-X64-LABEL: test1c:
108; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
109; DARWIN-X64: callq ___stack_chk_fail
110  %a.addr = alloca i8*, align 8
111  %buf = alloca [16 x i8], align 16
112  store i8* %a, i8** %a.addr, align 8
113  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
114  %0 = load i8** %a.addr, align 8
115  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
116  %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
117  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
118  ret void
119}
120
121; test1d: array of [16 x i8]
122;         sspreq attribute
123; Requires protector.
124; Function Attrs: sspreq
125define void @test1d(i8* %a) #2 {
126entry:
127; LINUX-I386-LABEL: test1d:
128; LINUX-I386: mov{{l|q}} %gs:
129; LINUX-I386: calll __stack_chk_fail
130
131; LINUX-X64-LABEL: test1d:
132; LINUX-X64: mov{{l|q}} %fs:
133; LINUX-X64: callq __stack_chk_fail
134
135; LINUX-KERNEL-X64-LABEL: test1d:
136; LINUX-KERNEL-X64: mov{{l|q}} %gs:
137; LINUX-KERNEL-X64: callq __stack_chk_fail
138
139; DARWIN-X64-LABEL: test1d:
140; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
141; DARWIN-X64: callq ___stack_chk_fail
142  %a.addr = alloca i8*, align 8
143  %buf = alloca [16 x i8], align 16
144  store i8* %a, i8** %a.addr, align 8
145  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
146  %0 = load i8** %a.addr, align 8
147  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
148  %arraydecay1 = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
149  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
150  ret void
151}
152
153; test2a: struct { [16 x i8] }
154;         no ssp attribute
155; Requires no protector.
156define void @test2a(i8* %a) {
157entry:
158; LINUX-I386-LABEL: test2a:
159; LINUX-I386-NOT: calll __stack_chk_fail
160; LINUX-I386: .cfi_endproc
161
162; LINUX-X64-LABEL: test2a:
163; LINUX-X64-NOT: callq __stack_chk_fail
164; LINUX-X64: .cfi_endproc
165
166; LINUX-KERNEL-X64-LABEL: test2a:
167; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
168; LINUX-KERNEL-X64: .cfi_endproc
169
170; DARWIN-X64-LABEL: test2a:
171; DARWIN-X64-NOT: callq ___stack_chk_fail
172; DARWIN-X64: .cfi_endproc
173  %a.addr = alloca i8*, align 8
174  %b = alloca %struct.foo, align 1
175  store i8* %a, i8** %a.addr, align 8
176  %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
177  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
178  %0 = load i8** %a.addr, align 8
179  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
180  %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
181  %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
182  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
183  ret void
184}
185
186; test2b: struct { [16 x i8] }
187;          ssp attribute
188; Requires protector.
189; Function Attrs: ssp
190define void @test2b(i8* %a) #0 {
191entry:
192; LINUX-I386-LABEL: test2b:
193; LINUX-I386: mov{{l|q}} %gs:
194; LINUX-I386: calll __stack_chk_fail
195
196; LINUX-X64-LABEL: test2b:
197; LINUX-X64: mov{{l|q}} %fs:
198; LINUX-X64: callq __stack_chk_fail
199
200; LINUX-KERNEL-X64-LABEL: test2b:
201; LINUX-KERNEL-X64: mov{{l|q}} %gs:
202; LINUX-KERNEL-X64: callq __stack_chk_fail
203
204; DARWIN-X64-LABEL: test2b:
205; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
206; DARWIN-X64: callq ___stack_chk_fail
207  %a.addr = alloca i8*, align 8
208  %b = alloca %struct.foo, align 1
209  store i8* %a, i8** %a.addr, align 8
210  %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
211  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
212  %0 = load i8** %a.addr, align 8
213  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
214  %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
215  %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
216  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
217  ret void
218}
219
220; test2c: struct { [16 x i8] }
221;          sspstrong attribute
222; Requires protector.
223; Function Attrs: sspstrong
224define void @test2c(i8* %a) #1 {
225entry:
226; LINUX-I386-LABEL: test2c:
227; LINUX-I386: mov{{l|q}} %gs:
228; LINUX-I386: calll __stack_chk_fail
229
230; LINUX-X64-LABEL: test2c:
231; LINUX-X64: mov{{l|q}} %fs:
232; LINUX-X64: callq __stack_chk_fail
233
234; LINUX-KERNEL-X64-LABEL: test2c:
235; LINUX-KERNEL-X64: mov{{l|q}} %gs:
236; LINUX-KERNEL-X64: callq __stack_chk_fail
237
238; DARWIN-X64-LABEL: test2c:
239; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
240; DARWIN-X64: callq ___stack_chk_fail
241  %a.addr = alloca i8*, align 8
242  %b = alloca %struct.foo, align 1
243  store i8* %a, i8** %a.addr, align 8
244  %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
245  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
246  %0 = load i8** %a.addr, align 8
247  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
248  %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
249  %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
250  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
251  ret void
252}
253
254; test2d: struct { [16 x i8] }
255;          sspreq attribute
256; Requires protector.
257; Function Attrs: sspreq
258define void @test2d(i8* %a) #2 {
259entry:
260; LINUX-I386-LABEL: test2d:
261; LINUX-I386: mov{{l|q}} %gs:
262; LINUX-I386: calll __stack_chk_fail
263
264; LINUX-X64-LABEL: test2d:
265; LINUX-X64: mov{{l|q}} %fs:
266; LINUX-X64: callq __stack_chk_fail
267
268; LINUX-KERNEL-X64-LABEL: test2d:
269; LINUX-KERNEL-X64: mov{{l|q}} %gs:
270; LINUX-KERNEL-X64: callq __stack_chk_fail
271
272; DARWIN-X64-LABEL: test2d:
273; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
274; DARWIN-X64: callq ___stack_chk_fail
275  %a.addr = alloca i8*, align 8
276  %b = alloca %struct.foo, align 1
277  store i8* %a, i8** %a.addr, align 8
278  %buf = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
279  %arraydecay = getelementptr inbounds [16 x i8]* %buf, i32 0, i32 0
280  %0 = load i8** %a.addr, align 8
281  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
282  %buf1 = getelementptr inbounds %struct.foo* %b, i32 0, i32 0
283  %arraydecay2 = getelementptr inbounds [16 x i8]* %buf1, i32 0, i32 0
284  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
285  ret void
286}
287
288; test3a:  array of [4 x i8]
289;          no ssp attribute
290; Requires no protector.
291define void @test3a(i8* %a) {
292entry:
293; LINUX-I386-LABEL: test3a:
294; LINUX-I386-NOT: calll __stack_chk_fail
295; LINUX-I386: .cfi_endproc
296
297; LINUX-X64-LABEL: test3a:
298; LINUX-X64-NOT: callq __stack_chk_fail
299; LINUX-X64: .cfi_endproc
300
301; LINUX-KERNEL-X64-LABEL: test3a:
302; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
303; LINUX-KERNEL-X64: .cfi_endproc
304
305; DARWIN-X64-LABEL: test3a:
306; DARWIN-X64-NOT: callq ___stack_chk_fail
307; DARWIN-X64: .cfi_endproc
308  %a.addr = alloca i8*, align 8
309  %buf = alloca [4 x i8], align 1
310  store i8* %a, i8** %a.addr, align 8
311  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
312  %0 = load i8** %a.addr, align 8
313  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
314  %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
315  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
316  ret void
317}
318
319; test3b:  array [4 x i8]
320;          ssp attribute
321; Requires no protector.
322; Function Attrs: ssp
323define void @test3b(i8* %a) #0 {
324entry:
325; LINUX-I386-LABEL: test3b:
326; LINUX-I386-NOT: calll __stack_chk_fail
327; LINUX-I386: .cfi_endproc
328
329; LINUX-X64-LABEL: test3b:
330; LINUX-X64-NOT: callq __stack_chk_fail
331; LINUX-X64: .cfi_endproc
332
333; LINUX-KERNEL-X64-LABEL: test3b:
334; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
335; LINUX-KERNEL-X64: .cfi_endproc
336
337; DARWIN-X64-LABEL: test3b:
338; DARWIN-X64-NOT: callq ___stack_chk_fail
339; DARWIN-X64: .cfi_endproc
340  %a.addr = alloca i8*, align 8
341  %buf = alloca [4 x i8], align 1
342  store i8* %a, i8** %a.addr, align 8
343  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
344  %0 = load i8** %a.addr, align 8
345  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
346  %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
347  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
348  ret void
349}
350
351; test3c:  array of [4 x i8]
352;          sspstrong attribute
353; Requires protector.
354; Function Attrs: sspstrong
355define void @test3c(i8* %a) #1 {
356entry:
357; LINUX-I386-LABEL: test3c:
358; LINUX-I386: mov{{l|q}} %gs:
359; LINUX-I386: calll __stack_chk_fail
360
361; LINUX-X64-LABEL: test3c:
362; LINUX-X64: mov{{l|q}} %fs:
363; LINUX-X64: callq __stack_chk_fail
364
365; LINUX-KERNEL-X64-LABEL: test3c:
366; LINUX-KERNEL-X64: mov{{l|q}} %gs:
367; LINUX-KERNEL-X64: callq __stack_chk_fail
368
369; DARWIN-X64-LABEL: test3c:
370; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
371; DARWIN-X64: callq ___stack_chk_fail
372  %a.addr = alloca i8*, align 8
373  %buf = alloca [4 x i8], align 1
374  store i8* %a, i8** %a.addr, align 8
375  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
376  %0 = load i8** %a.addr, align 8
377  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
378  %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
379  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
380  ret void
381}
382
383; test3d:  array of [4 x i8]
384;          sspreq attribute
385; Requires protector.
386; Function Attrs: sspreq
387define void @test3d(i8* %a) #2 {
388entry:
389; LINUX-I386-LABEL: test3d:
390; LINUX-I386: mov{{l|q}} %gs:
391; LINUX-I386: calll __stack_chk_fail
392
393; LINUX-X64-LABEL: test3d:
394; LINUX-X64: mov{{l|q}} %fs:
395; LINUX-X64: callq __stack_chk_fail
396
397; LINUX-KERNEL-X64-LABEL: test3d:
398; LINUX-KERNEL-X64: mov{{l|q}} %gs:
399; LINUX-KERNEL-X64: callq __stack_chk_fail
400
401; DARWIN-X64-LABEL: test3d:
402; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
403; DARWIN-X64: callq ___stack_chk_fail
404  %a.addr = alloca i8*, align 8
405  %buf = alloca [4 x i8], align 1
406  store i8* %a, i8** %a.addr, align 8
407  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
408  %0 = load i8** %a.addr, align 8
409  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
410  %arraydecay1 = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
411  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
412  ret void
413}
414
415; test4a:  struct { [4 x i8] }
416;          no ssp attribute
417; Requires no protector.
418define void @test4a(i8* %a) {
419entry:
420; LINUX-I386-LABEL: test4a:
421; LINUX-I386-NOT: calll __stack_chk_fail
422; LINUX-I386: .cfi_endproc
423
424; LINUX-X64-LABEL: test4a:
425; LINUX-X64-NOT: callq __stack_chk_fail
426; LINUX-X64: .cfi_endproc
427
428; LINUX-KERNEL-X64-LABEL: test4a:
429; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
430; LINUX-KERNEL-X64: .cfi_endproc
431
432; DARWIN-X64-LABEL: test4a:
433; DARWIN-X64-NOT: callq ___stack_chk_fail
434; DARWIN-X64: .cfi_endproc
435  %a.addr = alloca i8*, align 8
436  %b = alloca %struct.foo.0, align 1
437  store i8* %a, i8** %a.addr, align 8
438  %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
439  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
440  %0 = load i8** %a.addr, align 8
441  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
442  %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
443  %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
444  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
445  ret void
446}
447
448; test4b:  struct { [4 x i8] }
449;          ssp attribute
450; Requires no protector.
451; Function Attrs: ssp
452define void @test4b(i8* %a) #0 {
453entry:
454; LINUX-I386-LABEL: test4b:
455; LINUX-I386-NOT: calll __stack_chk_fail
456; LINUX-I386: .cfi_endproc
457
458; LINUX-X64-LABEL: test4b:
459; LINUX-X64-NOT: callq __stack_chk_fail
460; LINUX-X64: .cfi_endproc
461
462; LINUX-KERNEL-X64-LABEL: test4b:
463; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
464; LINUX-KERNEL-X64: .cfi_endproc
465
466; DARWIN-X64-LABEL: test4b:
467; DARWIN-X64-NOT: callq ___stack_chk_fail
468; DARWIN-X64: .cfi_endproc
469  %a.addr = alloca i8*, align 8
470  %b = alloca %struct.foo.0, align 1
471  store i8* %a, i8** %a.addr, align 8
472  %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
473  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
474  %0 = load i8** %a.addr, align 8
475  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
476  %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
477  %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
478  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
479  ret void
480}
481
482; test4c:  struct { [4 x i8] }
483;          sspstrong attribute
484; Requires protector.
485; Function Attrs: sspstrong
486define void @test4c(i8* %a) #1 {
487entry:
488; LINUX-I386-LABEL: test4c:
489; LINUX-I386: mov{{l|q}} %gs:
490; LINUX-I386: calll __stack_chk_fail
491
492; LINUX-X64-LABEL: test4c:
493; LINUX-X64: mov{{l|q}} %fs:
494; LINUX-X64: callq __stack_chk_fail
495
496; LINUX-KERNEL-X64-LABEL: test4c:
497; LINUX-KERNEL-X64: mov{{l|q}} %gs:
498; LINUX-KERNEL-X64: callq __stack_chk_fail
499
500; DARWIN-X64-LABEL: test4c:
501; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
502; DARWIN-X64: callq ___stack_chk_fail
503  %a.addr = alloca i8*, align 8
504  %b = alloca %struct.foo.0, align 1
505  store i8* %a, i8** %a.addr, align 8
506  %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
507  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
508  %0 = load i8** %a.addr, align 8
509  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
510  %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
511  %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
512  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
513  ret void
514}
515
516; test4d:  struct { [4 x i8] }
517;          sspreq attribute
518; Requires protector.
519; Function Attrs: sspreq
520define void @test4d(i8* %a) #2 {
521entry:
522; LINUX-I386-LABEL: test4d:
523; LINUX-I386: mov{{l|q}} %gs:
524; LINUX-I386: calll __stack_chk_fail
525
526; LINUX-X64-LABEL: test4d:
527; LINUX-X64: mov{{l|q}} %fs:
528; LINUX-X64: callq __stack_chk_fail
529
530; LINUX-KERNEL-X64-LABEL: test4d:
531; LINUX-KERNEL-X64: mov{{l|q}} %gs:
532; LINUX-KERNEL-X64: callq __stack_chk_fail
533
534; DARWIN-X64-LABEL: test4d:
535; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
536; DARWIN-X64: callq ___stack_chk_fail
537  %a.addr = alloca i8*, align 8
538  %b = alloca %struct.foo.0, align 1
539  store i8* %a, i8** %a.addr, align 8
540  %buf = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
541  %arraydecay = getelementptr inbounds [4 x i8]* %buf, i32 0, i32 0
542  %0 = load i8** %a.addr, align 8
543  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
544  %buf1 = getelementptr inbounds %struct.foo.0* %b, i32 0, i32 0
545  %arraydecay2 = getelementptr inbounds [4 x i8]* %buf1, i32 0, i32 0
546  %call3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
547  ret void
548}
549
550; test5a:  no arrays / no nested arrays
551;          no ssp attribute
552; Requires no protector.
553define void @test5a(i8* %a) {
554entry:
555; LINUX-I386-LABEL: test5a:
556; LINUX-I386-NOT: calll __stack_chk_fail
557; LINUX-I386: .cfi_endproc
558
559; LINUX-X64-LABEL: test5a:
560; LINUX-X64-NOT: callq __stack_chk_fail
561; LINUX-X64: .cfi_endproc
562
563; LINUX-KERNEL-X64-LABEL: test5a:
564; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
565; LINUX-KERNEL-X64: .cfi_endproc
566
567; DARWIN-X64-LABEL: test5a:
568; DARWIN-X64-NOT: callq ___stack_chk_fail
569; DARWIN-X64: .cfi_endproc
570  %a.addr = alloca i8*, align 8
571  store i8* %a, i8** %a.addr, align 8
572  %0 = load i8** %a.addr, align 8
573  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
574  ret void
575}
576
577; test5b:  no arrays / no nested arrays
578;          ssp attribute
579; Requires no protector.
580; Function Attrs: ssp
581define void @test5b(i8* %a) #0 {
582entry:
583; LINUX-I386-LABEL: test5b:
584; LINUX-I386-NOT: calll __stack_chk_fail
585; LINUX-I386: .cfi_endproc
586
587; LINUX-X64-LABEL: test5b:
588; LINUX-X64-NOT: callq __stack_chk_fail
589; LINUX-X64: .cfi_endproc
590
591; LINUX-KERNEL-X64-LABEL: test5b:
592; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
593; LINUX-KERNEL-X64: .cfi_endproc
594
595; DARWIN-X64-LABEL: test5b:
596; DARWIN-X64-NOT: callq ___stack_chk_fail
597; DARWIN-X64: .cfi_endproc
598  %a.addr = alloca i8*, align 8
599  store i8* %a, i8** %a.addr, align 8
600  %0 = load i8** %a.addr, align 8
601  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
602  ret void
603}
604
605; test5c:  no arrays / no nested arrays
606;          sspstrong attribute
607; Requires no protector.
608; Function Attrs: sspstrong
609define void @test5c(i8* %a) #1 {
610entry:
611; LINUX-I386-LABEL: test5c:
612; LINUX-I386-NOT: calll __stack_chk_fail
613; LINUX-I386: .cfi_endproc
614
615; LINUX-X64-LABEL: test5c:
616; LINUX-X64-NOT: callq __stack_chk_fail
617; LINUX-X64: .cfi_endproc
618
619; LINUX-KERNEL-X64-LABEL: test5c:
620; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
621; LINUX-KERNEL-X64: .cfi_endproc
622
623; DARWIN-X64-LABEL: test5c:
624; DARWIN-X64-NOT: callq ___stack_chk_fail
625; DARWIN-X64: .cfi_endproc
626  %a.addr = alloca i8*, align 8
627  store i8* %a, i8** %a.addr, align 8
628  %0 = load i8** %a.addr, align 8
629  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
630  ret void
631}
632
633; test5d:  no arrays / no nested arrays
634;          sspreq attribute
635; Requires protector.
636; Function Attrs: sspreq
637define void @test5d(i8* %a) #2 {
638entry:
639; LINUX-I386-LABEL: test5d:
640; LINUX-I386: mov{{l|q}} %gs:
641; LINUX-I386: calll __stack_chk_fail
642
643; LINUX-X64-LABEL: test5d:
644; LINUX-X64: mov{{l|q}} %fs:
645; LINUX-X64: callq __stack_chk_fail
646
647; LINUX-KERNEL-X64-LABEL: test5d:
648; LINUX-KERNEL-X64: mov{{l|q}} %gs:
649; LINUX-KERNEL-X64: callq __stack_chk_fail
650
651; DARWIN-X64-LABEL: test5d:
652; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
653; DARWIN-X64: callq ___stack_chk_fail
654  %a.addr = alloca i8*, align 8
655  store i8* %a, i8** %a.addr, align 8
656  %0 = load i8** %a.addr, align 8
657  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i8* %0)
658  ret void
659}
660
661; test6a:  Address-of local taken (j = &a)
662;          no ssp attribute
663; Requires no protector.
664define void @test6a() {
665entry:
666; LINUX-I386-LABEL: test6a:
667; LINUX-I386-NOT: calll __stack_chk_fail
668; LINUX-I386: .cfi_endproc
669
670; LINUX-X64-LABEL: test6a:
671; LINUX-X64-NOT: callq __stack_chk_fail
672; LINUX-X64: .cfi_endproc
673
674; LINUX-KERNEL-X64-LABEL: test6a:
675; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
676; LINUX-KERNEL-X64: .cfi_endproc
677
678; DARWIN-X64-LABEL: test6a:
679; DARWIN-X64-NOT: callq ___stack_chk_fail
680; DARWIN-X64: .cfi_endproc
681  %retval = alloca i32, align 4
682  %a = alloca i32, align 4
683  %j = alloca i32*, align 8
684  store i32 0, i32* %retval
685  %0 = load i32* %a, align 4
686  %add = add nsw i32 %0, 1
687  store i32 %add, i32* %a, align 4
688  store i32* %a, i32** %j, align 8
689  ret void
690}
691
692; test6b:  Address-of local taken (j = &a)
693;          ssp attribute
694; Requires no protector.
695; Function Attrs: ssp
696define void @test6b() #0 {
697entry:
698; LINUX-I386-LABEL: test6b:
699; LINUX-I386-NOT: calll __stack_chk_fail
700; LINUX-I386: .cfi_endproc
701
702; LINUX-X64-LABEL: test6b:
703; LINUX-X64-NOT: callq __stack_chk_fail
704; LINUX-X64: .cfi_endproc
705
706; LINUX-KERNEL-X64-LABEL: test6b:
707; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
708; LINUX-KERNEL-X64: .cfi_endproc
709
710; DARWIN-X64-LABEL: test6b:
711; DARWIN-X64-NOT: callq ___stack_chk_fail
712; DARWIN-X64: .cfi_endproc
713  %retval = alloca i32, align 4
714  %a = alloca i32, align 4
715  %j = alloca i32*, align 8
716  store i32 0, i32* %retval
717  %0 = load i32* %a, align 4
718  %add = add nsw i32 %0, 1
719  store i32 %add, i32* %a, align 4
720  store i32* %a, i32** %j, align 8
721  ret void
722}
723
724; test6c:  Address-of local taken (j = &a)
725;          sspstrong attribute
726; Requires protector.
727; Function Attrs: sspstrong
728define void @test6c() #1 {
729entry:
730; LINUX-I386-LABEL: test6c:
731; LINUX-I386: mov{{l|q}} %gs:
732; LINUX-I386: calll __stack_chk_fail
733
734; LINUX-X64-LABEL: test6c:
735; LINUX-X64: mov{{l|q}} %fs:
736; LINUX-X64: callq __stack_chk_fail
737
738; LINUX-KERNEL-X64-LABEL: test6c:
739; LINUX-KERNEL-X64: mov{{l|q}} %gs:
740; LINUX-KERNEL-X64: callq __stack_chk_fail
741
742; DARWIN-X64-LABEL: test6c:
743; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
744; DARWIN-X64: callq ___stack_chk_fail
745  %retval = alloca i32, align 4
746  %a = alloca i32, align 4
747  %j = alloca i32*, align 8
748  store i32 0, i32* %retval
749  %0 = load i32* %a, align 4
750  %add = add nsw i32 %0, 1
751  store i32 %add, i32* %a, align 4
752  store i32* %a, i32** %j, align 8
753  ret void
754}
755
756; test6d:  Address-of local taken (j = &a)
757;          sspreq attribute
758; Requires protector.
759; Function Attrs: sspreq
760define void @test6d() #2 {
761entry:
762; LINUX-I386-LABEL: test6d:
763; LINUX-I386: mov{{l|q}} %gs:
764; LINUX-I386: calll __stack_chk_fail
765
766; LINUX-X64-LABEL: test6d:
767; LINUX-X64: mov{{l|q}} %fs:
768; LINUX-X64: callq __stack_chk_fail
769
770; LINUX-KERNEL-X64-LABEL: test6d:
771; LINUX-KERNEL-X64: mov{{l|q}} %gs:
772; LINUX-KERNEL-X64: callq __stack_chk_fail
773
774; DARWIN-X64-LABEL: test6d:
775; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
776; DARWIN-X64: callq ___stack_chk_fail
777  %retval = alloca i32, align 4
778  %a = alloca i32, align 4
779  %j = alloca i32*, align 8
780  store i32 0, i32* %retval
781  %0 = load i32* %a, align 4
782  %add = add nsw i32 %0, 1
783  store i32 %add, i32* %a, align 4
784  store i32* %a, i32** %j, align 8
785  ret void
786}
787
788; test7a:  PtrToInt Cast
789;          no ssp attribute
790; Requires no protector.
791define void @test7a()  {
792entry:
793; LINUX-I386-LABEL: test7a:
794; LINUX-I386-NOT: calll __stack_chk_fail
795; LINUX-I386: .cfi_endproc
796
797; LINUX-X64-LABEL: test7a:
798; LINUX-X64-NOT: callq __stack_chk_fail
799; LINUX-X64: .cfi_endproc
800
801; LINUX-KERNEL-X64-LABEL: test7a:
802; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
803; LINUX-KERNEL-X64: .cfi_endproc
804
805; DARWIN-X64-LABEL: test7a:
806; DARWIN-X64-NOT: callq ___stack_chk_fail
807; DARWIN-X64: .cfi_endproc
808  %a = alloca i32, align 4
809  %0 = ptrtoint i32* %a to i64
810  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
811  ret void
812}
813
814; test7b:  PtrToInt Cast
815;          ssp attribute
816; Requires no protector.
817; Function Attrs: ssp
818define void @test7b() #0 {
819entry:
820; LINUX-I386-LABEL: test7b:
821; LINUX-I386-NOT: calll __stack_chk_fail
822; LINUX-I386: .cfi_endproc
823
824; LINUX-X64-LABEL: test7b:
825; LINUX-X64-NOT: callq __stack_chk_fail
826; LINUX-X64: .cfi_endproc
827
828; LINUX-KERNEL-X64-LABEL: test7b:
829; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
830; LINUX-KERNEL-X64: .cfi_endproc
831
832; DARWIN-X64-LABEL: test7b:
833; DARWIN-X64-NOT: callq ___stack_chk_fail
834; DARWIN-X64: .cfi_endproc
835  %a = alloca i32, align 4
836  %0 = ptrtoint i32* %a to i64
837  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
838  ret void
839}
840
841; test7c:  PtrToInt Cast
842;          sspstrong attribute
843; Requires protector.
844; Function Attrs: sspstrong
845define void @test7c() #1 {
846entry:
847; LINUX-I386-LABEL: test7c:
848; LINUX-I386: mov{{l|q}} %gs:
849; LINUX-I386: calll __stack_chk_fail
850
851; LINUX-X64-LABEL: test7c:
852; LINUX-X64: mov{{l|q}} %fs:
853; LINUX-X64: callq __stack_chk_fail
854
855; LINUX-KERNEL-X64-LABEL: test7c:
856; LINUX-KERNEL-X64: mov{{l|q}} %gs:
857; LINUX-KERNEL-X64: callq __stack_chk_fail
858
859; DARWIN-X64-LABEL: test7c:
860; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
861; DARWIN-X64: callq ___stack_chk_fail
862  %a = alloca i32, align 4
863  %0 = ptrtoint i32* %a to i64
864  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
865  ret void
866}
867
868; test7d:  PtrToInt Cast
869;          sspreq attribute
870; Requires protector.
871; Function Attrs: sspreq
872define void @test7d() #2 {
873entry:
874; LINUX-I386-LABEL: test7d:
875; LINUX-I386: mov{{l|q}} %gs:
876; LINUX-I386: calll __stack_chk_fail
877
878; LINUX-X64-LABEL: test7d:
879; LINUX-X64: mov{{l|q}} %fs:
880; LINUX-X64: callq __stack_chk_fail
881
882; LINUX-KERNEL-X64-LABEL: test7d:
883; LINUX-KERNEL-X64: mov{{l|q}} %gs:
884; LINUX-KERNEL-X64: callq __stack_chk_fail
885
886; DARWIN-X64-LABEL: test7d:
887; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
888; DARWIN-X64: callq ___stack_chk_fail
889  %a = alloca i32, align 4
890  %0 = ptrtoint i32* %a to i64
891  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
892  ret void
893}
894
895; test8a:  Passing addr-of to function call
896;          no ssp attribute
897; Requires no protector.
898define void @test8a() {
899entry:
900; LINUX-I386-LABEL: test8a:
901; LINUX-I386-NOT: calll __stack_chk_fail
902; LINUX-I386: .cfi_endproc
903
904; LINUX-X64-LABEL: test8a:
905; LINUX-X64-NOT: callq __stack_chk_fail
906; LINUX-X64: .cfi_endproc
907
908; LINUX-KERNEL-X64-LABEL: test8a:
909; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
910; LINUX-KERNEL-X64: .cfi_endproc
911
912; DARWIN-X64-LABEL: test8a:
913; DARWIN-X64-NOT: callq ___stack_chk_fail
914; DARWIN-X64: .cfi_endproc
915  %b = alloca i32, align 4
916  call void @funcall(i32* %b)
917  ret void
918}
919
920; test8b:  Passing addr-of to function call
921;          ssp attribute
922; Requires no protector.
923; Function Attrs: ssp
924define void @test8b() #0 {
925entry:
926; LINUX-I386-LABEL: test8b:
927; LINUX-I386-NOT: calll __stack_chk_fail
928; LINUX-I386: .cfi_endproc
929
930; LINUX-X64-LABEL: test8b:
931; LINUX-X64-NOT: callq __stack_chk_fail
932; LINUX-X64: .cfi_endproc
933
934; LINUX-KERNEL-X64-LABEL: test8b:
935; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
936; LINUX-KERNEL-X64: .cfi_endproc
937
938; DARWIN-X64-LABEL: test8b:
939; DARWIN-X64-NOT: callq ___stack_chk_fail
940; DARWIN-X64: .cfi_endproc
941  %b = alloca i32, align 4
942  call void @funcall(i32* %b)
943  ret void
944}
945
946; test8c:  Passing addr-of to function call
947;          sspstrong attribute
948; Requires protector.
949; Function Attrs: sspstrong
950define void @test8c() #1 {
951entry:
952; LINUX-I386-LABEL: test8c:
953; LINUX-I386: mov{{l|q}} %gs:
954; LINUX-I386: calll __stack_chk_fail
955
956; LINUX-X64-LABEL: test8c:
957; LINUX-X64: mov{{l|q}} %fs:
958; LINUX-X64: callq __stack_chk_fail
959
960; LINUX-KERNEL-X64-LABEL: test8c:
961; LINUX-KERNEL-X64: mov{{l|q}} %gs:
962; LINUX-KERNEL-X64: callq __stack_chk_fail
963
964; DARWIN-X64-LABEL: test8c:
965; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
966; DARWIN-X64: callq ___stack_chk_fail
967  %b = alloca i32, align 4
968  call void @funcall(i32* %b)
969  ret void
970}
971
972; test8d:  Passing addr-of to function call
973;          sspreq attribute
974; Requires protector.
975; Function Attrs: sspreq
976define void @test8d() #2 {
977entry:
978; LINUX-I386-LABEL: test8d:
979; LINUX-I386: mov{{l|q}} %gs:
980; LINUX-I386: calll __stack_chk_fail
981
982; LINUX-X64-LABEL: test8d:
983; LINUX-X64: mov{{l|q}} %fs:
984; LINUX-X64: callq __stack_chk_fail
985
986; LINUX-KERNEL-X64-LABEL: test8d:
987; LINUX-KERNEL-X64: mov{{l|q}} %gs:
988; LINUX-KERNEL-X64: callq __stack_chk_fail
989
990; DARWIN-X64-LABEL: test8d:
991; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
992; DARWIN-X64: callq ___stack_chk_fail
993  %b = alloca i32, align 4
994  call void @funcall(i32* %b)
995  ret void
996}
997
998; test9a:  Addr-of in select instruction
999;          no ssp attribute
1000; Requires no protector.
1001define void @test9a() {
1002entry:
1003; LINUX-I386-LABEL: test9a:
1004; LINUX-I386-NOT: calll __stack_chk_fail
1005; LINUX-I386: .cfi_endproc
1006
1007; LINUX-X64-LABEL: test9a:
1008; LINUX-X64-NOT: callq __stack_chk_fail
1009; LINUX-X64: .cfi_endproc
1010
1011; LINUX-KERNEL-X64-LABEL: test9a:
1012; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1013; LINUX-KERNEL-X64: .cfi_endproc
1014
1015; DARWIN-X64-LABEL: test9a:
1016; DARWIN-X64-NOT: callq ___stack_chk_fail
1017; DARWIN-X64: .cfi_endproc
1018  %x = alloca double, align 8
1019  %call = call double @testi_aux()
1020  store double %call, double* %x, align 8
1021  %cmp2 = fcmp ogt double %call, 0.000000e+00
1022  %y.1 = select i1 %cmp2, double* %x, double* null
1023  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1024  ret void
1025}
1026
1027; test9b:  Addr-of in select instruction
1028;          ssp attribute
1029; Requires no protector.
1030; Function Attrs: ssp
1031define void @test9b() #0 {
1032entry:
1033; LINUX-I386-LABEL: test9b:
1034; LINUX-I386-NOT: calll __stack_chk_fail
1035; LINUX-I386: .cfi_endproc
1036
1037; LINUX-X64-LABEL: test9b:
1038; LINUX-X64-NOT: callq __stack_chk_fail
1039; LINUX-X64: .cfi_endproc
1040
1041; LINUX-KERNEL-X64-LABEL: test9b:
1042; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1043; LINUX-KERNEL-X64: .cfi_endproc
1044
1045; DARWIN-X64-LABEL: test9b:
1046; DARWIN-X64-NOT: callq ___stack_chk_fail
1047; DARWIN-X64: .cfi_endproc
1048  %x = alloca double, align 8
1049  %call = call double @testi_aux()
1050  store double %call, double* %x, align 8
1051  %cmp2 = fcmp ogt double %call, 0.000000e+00
1052  %y.1 = select i1 %cmp2, double* %x, double* null
1053  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1054  ret void
1055}
1056
1057; test9c:  Addr-of in select instruction
1058;          sspstrong attribute
1059; Requires protector.
1060; Function Attrs: sspstrong
1061define void @test9c() #1 {
1062entry:
1063; LINUX-I386-LABEL: test9c:
1064; LINUX-I386: mov{{l|q}} %gs:
1065; LINUX-I386: calll __stack_chk_fail
1066
1067; LINUX-X64-LABEL: test9c:
1068; LINUX-X64: mov{{l|q}} %fs:
1069; LINUX-X64: callq __stack_chk_fail
1070
1071; LINUX-KERNEL-X64-LABEL: test9c:
1072; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1073; LINUX-KERNEL-X64: callq __stack_chk_fail
1074
1075; DARWIN-X64-LABEL: test9c:
1076; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1077; DARWIN-X64: callq ___stack_chk_fail
1078  %x = alloca double, align 8
1079  %call = call double @testi_aux()
1080  store double %call, double* %x, align 8
1081  %cmp2 = fcmp ogt double %call, 0.000000e+00
1082  %y.1 = select i1 %cmp2, double* %x, double* null
1083  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1084  ret void
1085}
1086
1087; test9d:  Addr-of in select instruction
1088;          sspreq attribute
1089; Requires protector.
1090; Function Attrs: sspreq
1091define void @test9d() #2 {
1092entry:
1093; LINUX-I386-LABEL: test9d:
1094; LINUX-I386: mov{{l|q}} %gs:
1095; LINUX-I386: calll __stack_chk_fail
1096
1097; LINUX-X64-LABEL: test9d:
1098; LINUX-X64: mov{{l|q}} %fs:
1099; LINUX-X64: callq __stack_chk_fail
1100
1101; LINUX-KERNEL-X64-LABEL: test9d:
1102; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1103; LINUX-KERNEL-X64: callq __stack_chk_fail
1104
1105; DARWIN-X64-LABEL: test9d:
1106; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1107; DARWIN-X64: callq ___stack_chk_fail
1108  %x = alloca double, align 8
1109  %call = call double @testi_aux()
1110  store double %call, double* %x, align 8
1111  %cmp2 = fcmp ogt double %call, 0.000000e+00
1112  %y.1 = select i1 %cmp2, double* %x, double* null
1113  %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1114  ret void
1115}
1116
1117; test10a: Addr-of in phi instruction
1118;          no ssp attribute
1119; Requires no protector.
1120define void @test10a() {
1121entry:
1122; LINUX-I386-LABEL: test10a:
1123; LINUX-I386-NOT: calll __stack_chk_fail
1124; LINUX-I386: .cfi_endproc
1125
1126; LINUX-X64-LABEL: test10a:
1127; LINUX-X64-NOT: callq __stack_chk_fail
1128; LINUX-X64: .cfi_endproc
1129
1130; LINUX-KERNEL-X64-LABEL: test10a:
1131; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1132; LINUX-KERNEL-X64: .cfi_endproc
1133
1134; DARWIN-X64-LABEL: test10a:
1135; DARWIN-X64-NOT: callq ___stack_chk_fail
1136; DARWIN-X64: .cfi_endproc
1137  %x = alloca double, align 8
1138  %call = call double @testi_aux()
1139  store double %call, double* %x, align 8
1140  %cmp = fcmp ogt double %call, 3.140000e+00
1141  br i1 %cmp, label %if.then, label %if.else
1142
1143if.then:                                          ; preds = %entry
1144  %call1 = call double @testi_aux()
1145  store double %call1, double* %x, align 8
1146  br label %if.end4
1147
1148if.else:                                          ; preds = %entry
1149  %cmp2 = fcmp ogt double %call, 1.000000e+00
1150  br i1 %cmp2, label %if.then3, label %if.end4
1151
1152if.then3:                                         ; preds = %if.else
1153  br label %if.end4
1154
1155if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1156  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1157  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1158  ret void
1159}
1160
1161; test10b: Addr-of in phi instruction
1162;          ssp attribute
1163; Requires no protector.
1164; Function Attrs: ssp
1165define void @test10b() #0 {
1166entry:
1167; LINUX-I386-LABEL: test10b:
1168; LINUX-I386-NOT: calll __stack_chk_fail
1169; LINUX-I386: .cfi_endproc
1170
1171; LINUX-X64-LABEL: test10b:
1172; LINUX-X64-NOT: callq __stack_chk_fail
1173; LINUX-X64: .cfi_endproc
1174
1175; LINUX-KERNEL-X64-LABEL: test10b:
1176; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1177; LINUX-KERNEL-X64: .cfi_endproc
1178
1179; DARWIN-X64-LABEL: test10b:
1180; DARWIN-X64-NOT: callq ___stack_chk_fail
1181; DARWIN-X64: .cfi_endproc
1182  %x = alloca double, align 8
1183  %call = call double @testi_aux()
1184  store double %call, double* %x, align 8
1185  %cmp = fcmp ogt double %call, 3.140000e+00
1186  br i1 %cmp, label %if.then, label %if.else
1187
1188if.then:                                          ; preds = %entry
1189  %call1 = call double @testi_aux()
1190  store double %call1, double* %x, align 8
1191  br label %if.end4
1192
1193if.else:                                          ; preds = %entry
1194  %cmp2 = fcmp ogt double %call, 1.000000e+00
1195  br i1 %cmp2, label %if.then3, label %if.end4
1196
1197if.then3:                                         ; preds = %if.else
1198  br label %if.end4
1199
1200if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1201  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1202  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1203  ret void
1204}
1205
1206; test10c: Addr-of in phi instruction
1207;          sspstrong attribute
1208; Requires protector.
1209; Function Attrs: sspstrong
1210define void @test10c() #1 {
1211entry:
1212; LINUX-I386-LABEL: test10c:
1213; LINUX-I386: mov{{l|q}} %gs:
1214; LINUX-I386: calll __stack_chk_fail
1215
1216; LINUX-X64-LABEL: test10c:
1217; LINUX-X64: mov{{l|q}} %fs:
1218; LINUX-X64: callq __stack_chk_fail
1219
1220; LINUX-KERNEL-X64-LABEL: test10c:
1221; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1222; LINUX-KERNEL-X64: callq __stack_chk_fail
1223
1224; DARWIN-X64-LABEL: test10c:
1225; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1226; DARWIN-X64: callq ___stack_chk_fail
1227  %x = alloca double, align 8
1228  %call = call double @testi_aux()
1229  store double %call, double* %x, align 8
1230  %cmp = fcmp ogt double %call, 3.140000e+00
1231  br i1 %cmp, label %if.then, label %if.else
1232
1233if.then:                                          ; preds = %entry
1234  %call1 = call double @testi_aux()
1235  store double %call1, double* %x, align 8
1236  br label %if.end4
1237
1238if.else:                                          ; preds = %entry
1239  %cmp2 = fcmp ogt double %call, 1.000000e+00
1240  br i1 %cmp2, label %if.then3, label %if.end4
1241
1242if.then3:                                         ; preds = %if.else
1243  br label %if.end4
1244
1245if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1246  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1247  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1248  ret void
1249}
1250
1251; test10d: Addr-of in phi instruction
1252;          sspreq attribute
1253; Requires protector.
1254; Function Attrs: sspreq
1255define void @test10d() #2 {
1256entry:
1257; LINUX-I386-LABEL: test10d:
1258; LINUX-I386: mov{{l|q}} %gs:
1259; LINUX-I386: calll __stack_chk_fail
1260
1261; LINUX-X64-LABEL: test10d:
1262; LINUX-X64: mov{{l|q}} %fs:
1263; LINUX-X64: callq __stack_chk_fail
1264
1265; LINUX-KERNEL-X64-LABEL: test10d:
1266; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1267; LINUX-KERNEL-X64: callq __stack_chk_fail
1268
1269; DARWIN-X64-LABEL: test10d:
1270; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1271; DARWIN-X64: callq ___stack_chk_fail
1272  %x = alloca double, align 8
1273  %call = call double @testi_aux()
1274  store double %call, double* %x, align 8
1275  %cmp = fcmp ogt double %call, 3.140000e+00
1276  br i1 %cmp, label %if.then, label %if.else
1277
1278if.then:                                          ; preds = %entry
1279  %call1 = call double @testi_aux()
1280  store double %call1, double* %x, align 8
1281  br label %if.end4
1282
1283if.else:                                          ; preds = %entry
1284  %cmp2 = fcmp ogt double %call, 1.000000e+00
1285  br i1 %cmp2, label %if.then3, label %if.end4
1286
1287if.then3:                                         ; preds = %if.else
1288  br label %if.end4
1289
1290if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1291  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1292  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1293  ret void
1294}
1295
1296; test11a: Addr-of struct element. (GEP followed by store).
1297;          no ssp attribute
1298; Requires no protector.
1299define void @test11a() {
1300entry:
1301; LINUX-I386-LABEL: test11a:
1302; LINUX-I386-NOT: calll __stack_chk_fail
1303; LINUX-I386: .cfi_endproc
1304
1305; LINUX-X64-LABEL: test11a:
1306; LINUX-X64-NOT: callq __stack_chk_fail
1307; LINUX-X64: .cfi_endproc
1308
1309; LINUX-KERNEL-X64-LABEL: test11a:
1310; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1311; LINUX-KERNEL-X64: .cfi_endproc
1312
1313; DARWIN-X64-LABEL: test11a:
1314; DARWIN-X64-NOT: callq ___stack_chk_fail
1315; DARWIN-X64: .cfi_endproc
1316  %c = alloca %struct.pair, align 4
1317  %b = alloca i32*, align 8
1318  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1319  store i32* %y, i32** %b, align 8
1320  %0 = load i32** %b, align 8
1321  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1322  ret void
1323}
1324
1325; test11b: Addr-of struct element. (GEP followed by store).
1326;          ssp attribute
1327; Requires no protector.
1328; Function Attrs: ssp
1329define void @test11b() #0 {
1330entry:
1331; LINUX-I386-LABEL: test11b:
1332; LINUX-I386-NOT: calll __stack_chk_fail
1333; LINUX-I386: .cfi_endproc
1334
1335; LINUX-X64-LABEL: test11b:
1336; LINUX-X64-NOT: callq __stack_chk_fail
1337; LINUX-X64: .cfi_endproc
1338
1339; LINUX-KERNEL-X64-LABEL: test11b:
1340; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1341; LINUX-KERNEL-X64: .cfi_endproc
1342
1343; DARWIN-X64-LABEL: test11b:
1344; DARWIN-X64-NOT: callq ___stack_chk_fail
1345; DARWIN-X64: .cfi_endproc
1346  %c = alloca %struct.pair, align 4
1347  %b = alloca i32*, align 8
1348  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1349  store i32* %y, i32** %b, align 8
1350  %0 = load i32** %b, align 8
1351  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1352  ret void
1353}
1354
1355; test11c: Addr-of struct element. (GEP followed by store).
1356;          sspstrong attribute
1357; Requires protector.
1358; Function Attrs: sspstrong
1359define void @test11c() #1 {
1360entry:
1361; LINUX-I386-LABEL: test11c:
1362; LINUX-I386: mov{{l|q}} %gs:
1363; LINUX-I386: calll __stack_chk_fail
1364
1365; LINUX-X64-LABEL: test11c:
1366; LINUX-X64: mov{{l|q}} %fs:
1367; LINUX-X64: callq __stack_chk_fail
1368
1369; LINUX-KERNEL-X64-LABEL: test11c:
1370; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1371; LINUX-KERNEL-X64: callq __stack_chk_fail
1372
1373; DARWIN-X64-LABEL: test11c:
1374; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1375; DARWIN-X64: callq ___stack_chk_fail
1376  %c = alloca %struct.pair, align 4
1377  %b = alloca i32*, align 8
1378  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1379  store i32* %y, i32** %b, align 8
1380  %0 = load i32** %b, align 8
1381  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1382  ret void
1383}
1384
1385; test11d: Addr-of struct element. (GEP followed by store).
1386;          sspreq attribute
1387; Requires protector.
1388; Function Attrs: sspreq
1389define void @test11d() #2 {
1390entry:
1391; LINUX-I386-LABEL: test11d:
1392; LINUX-I386: mov{{l|q}} %gs:
1393; LINUX-I386: calll __stack_chk_fail
1394
1395; LINUX-X64-LABEL: test11d:
1396; LINUX-X64: mov{{l|q}} %fs:
1397; LINUX-X64: callq __stack_chk_fail
1398
1399; LINUX-KERNEL-X64-LABEL: test11d:
1400; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1401; LINUX-KERNEL-X64: callq __stack_chk_fail
1402
1403; DARWIN-X64-LABEL: test11d:
1404; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1405; DARWIN-X64: callq ___stack_chk_fail
1406  %c = alloca %struct.pair, align 4
1407  %b = alloca i32*, align 8
1408  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1409  store i32* %y, i32** %b, align 8
1410  %0 = load i32** %b, align 8
1411  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %0)
1412  ret void
1413}
1414
1415; test12a: Addr-of struct element, GEP followed by ptrtoint.
1416;          no ssp attribute
1417; Requires no protector.
1418define void @test12a() {
1419entry:
1420; LINUX-I386-LABEL: test12a:
1421; LINUX-I386-NOT: calll __stack_chk_fail
1422; LINUX-I386: .cfi_endproc
1423
1424; LINUX-X64-LABEL: test12a:
1425; LINUX-X64-NOT: callq __stack_chk_fail
1426; LINUX-X64: .cfi_endproc
1427
1428; LINUX-KERNEL-X64-LABEL: test12a:
1429; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1430; LINUX-KERNEL-X64: .cfi_endproc
1431
1432; DARWIN-X64-LABEL: test12a:
1433; DARWIN-X64-NOT: callq ___stack_chk_fail
1434; DARWIN-X64: .cfi_endproc
1435  %c = alloca %struct.pair, align 4
1436  %b = alloca i32*, align 8
1437  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1438  %0 = ptrtoint i32* %y to i64
1439  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1440  ret void
1441}
1442
1443; test12b: Addr-of struct element, GEP followed by ptrtoint.
1444;          ssp attribute
1445; Requires no protector.
1446; Function Attrs: ssp
1447define void @test12b() #0 {
1448entry:
1449; LINUX-I386-LABEL: test12b:
1450; LINUX-I386-NOT: calll __stack_chk_fail
1451; LINUX-I386: .cfi_endproc
1452
1453; LINUX-X64-LABEL: test12b:
1454; LINUX-X64-NOT: callq __stack_chk_fail
1455; LINUX-X64: .cfi_endproc
1456
1457; LINUX-KERNEL-X64-LABEL: test12b:
1458; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1459; LINUX-KERNEL-X64: .cfi_endproc
1460
1461; DARWIN-X64-LABEL: test12b:
1462; DARWIN-X64-NOT: callq ___stack_chk_fail
1463; DARWIN-X64: .cfi_endproc
1464  %c = alloca %struct.pair, align 4
1465  %b = alloca i32*, align 8
1466  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1467  %0 = ptrtoint i32* %y to i64
1468  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1469  ret void
1470}
1471
1472; test12c: Addr-of struct element, GEP followed by ptrtoint.
1473;          sspstrong attribute
1474; Function Attrs: sspstrong
1475define void @test12c() #1 {
1476entry:
1477; LINUX-I386-LABEL: test12c:
1478; LINUX-I386: mov{{l|q}} %gs:
1479; LINUX-I386: calll __stack_chk_fail
1480
1481; LINUX-X64-LABEL: test12c:
1482; LINUX-X64: mov{{l|q}} %fs:
1483; LINUX-X64: callq __stack_chk_fail
1484
1485; LINUX-KERNEL-X64-LABEL: test12c:
1486; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1487; LINUX-KERNEL-X64: callq __stack_chk_fail
1488
1489; DARWIN-X64-LABEL: test12c:
1490; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1491; DARWIN-X64: callq ___stack_chk_fail
1492  %c = alloca %struct.pair, align 4
1493  %b = alloca i32*, align 8
1494  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1495  %0 = ptrtoint i32* %y to i64
1496  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1497  ret void
1498}
1499
1500; test12d: Addr-of struct element, GEP followed by ptrtoint.
1501;          sspreq attribute
1502; Requires protector.
1503; Function Attrs: sspreq
1504define void @test12d() #2 {
1505entry:
1506; LINUX-I386-LABEL: test12d:
1507; LINUX-I386: mov{{l|q}} %gs:
1508; LINUX-I386: calll __stack_chk_fail
1509
1510; LINUX-X64-LABEL: test12d:
1511; LINUX-X64: mov{{l|q}} %fs:
1512; LINUX-X64: callq __stack_chk_fail
1513
1514; LINUX-KERNEL-X64-LABEL: test12d:
1515; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1516; LINUX-KERNEL-X64: callq __stack_chk_fail
1517
1518; DARWIN-X64-LABEL: test12d:
1519; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1520; DARWIN-X64: callq ___stack_chk_fail
1521  %c = alloca %struct.pair, align 4
1522  %b = alloca i32*, align 8
1523  %y = getelementptr inbounds %struct.pair* %c, i32 0, i32 1
1524  %0 = ptrtoint i32* %y to i64
1525  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i64 %0)
1526  ret void
1527}
1528
1529; test13a: Addr-of struct element, GEP followed by callinst.
1530;          no ssp attribute
1531; Requires no protector.
1532define void @test13a() {
1533entry:
1534; LINUX-I386-LABEL: test13a:
1535; LINUX-I386-NOT: calll __stack_chk_fail
1536; LINUX-I386: .cfi_endproc
1537
1538; LINUX-X64-LABEL: test13a:
1539; LINUX-X64-NOT: callq __stack_chk_fail
1540; LINUX-X64: .cfi_endproc
1541
1542; LINUX-KERNEL-X64-LABEL: test13a:
1543; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1544; LINUX-KERNEL-X64: .cfi_endproc
1545
1546; DARWIN-X64-LABEL: test13a:
1547; DARWIN-X64-NOT: callq ___stack_chk_fail
1548; DARWIN-X64: .cfi_endproc
1549  %c = alloca %struct.pair, align 4
1550  %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1551  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y)
1552  ret void
1553}
1554
1555; test13b: Addr-of struct element, GEP followed by callinst.
1556;          ssp attribute
1557; Requires no protector.
1558; Function Attrs: ssp
1559define void @test13b() #0 {
1560entry:
1561; LINUX-I386-LABEL: test13b:
1562; LINUX-I386-NOT: calll __stack_chk_fail
1563; LINUX-I386: .cfi_endproc
1564
1565; LINUX-X64-LABEL: test13b:
1566; LINUX-X64-NOT: callq __stack_chk_fail
1567; LINUX-X64: .cfi_endproc
1568
1569; LINUX-KERNEL-X64-LABEL: test13b:
1570; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1571; LINUX-KERNEL-X64: .cfi_endproc
1572
1573; DARWIN-X64-LABEL: test13b:
1574; DARWIN-X64-NOT: callq ___stack_chk_fail
1575; DARWIN-X64: .cfi_endproc
1576  %c = alloca %struct.pair, align 4
1577  %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1578  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y)
1579  ret void
1580}
1581
1582; test13c: Addr-of struct element, GEP followed by callinst.
1583;          sspstrong attribute
1584; Requires protector.
1585; Function Attrs: sspstrong
1586define void @test13c() #1 {
1587entry:
1588; LINUX-I386-LABEL: test13c:
1589; LINUX-I386: mov{{l|q}} %gs:
1590; LINUX-I386: calll __stack_chk_fail
1591
1592; LINUX-X64-LABEL: test13c:
1593; LINUX-X64: mov{{l|q}} %fs:
1594; LINUX-X64: callq __stack_chk_fail
1595
1596; LINUX-KERNEL-X64-LABEL: test13c:
1597; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1598; LINUX-KERNEL-X64: callq __stack_chk_fail
1599
1600; DARWIN-X64-LABEL: test13c:
1601; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1602; DARWIN-X64: callq ___stack_chk_fail
1603  %c = alloca %struct.pair, align 4
1604  %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1605  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y)
1606  ret void
1607}
1608
1609; test13d: Addr-of struct element, GEP followed by callinst.
1610;          sspreq attribute
1611; Requires protector.
1612; Function Attrs: sspreq
1613define void @test13d() #2 {
1614entry:
1615; LINUX-I386-LABEL: test13d:
1616; LINUX-I386: mov{{l|q}} %gs:
1617; LINUX-I386: calll __stack_chk_fail
1618
1619; LINUX-X64-LABEL: test13d:
1620; LINUX-X64: mov{{l|q}} %fs:
1621; LINUX-X64: callq __stack_chk_fail
1622
1623; LINUX-KERNEL-X64-LABEL: test13d:
1624; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1625; LINUX-KERNEL-X64: callq __stack_chk_fail
1626
1627; DARWIN-X64-LABEL: test13d:
1628; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1629; DARWIN-X64: callq ___stack_chk_fail
1630  %c = alloca %struct.pair, align 4
1631  %y = getelementptr inbounds %struct.pair* %c, i64 0, i32 1
1632  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %y)
1633  ret void
1634}
1635
1636; test14a: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1637;          no ssp attribute
1638; Requires no protector.
1639define void @test14a() {
1640entry:
1641; LINUX-I386-LABEL: test14a:
1642; LINUX-I386-NOT: calll __stack_chk_fail
1643; LINUX-I386: .cfi_endproc
1644
1645; LINUX-X64-LABEL: test14a:
1646; LINUX-X64-NOT: callq __stack_chk_fail
1647; LINUX-X64: .cfi_endproc
1648
1649; LINUX-KERNEL-X64-LABEL: test14a:
1650; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1651; LINUX-KERNEL-X64: .cfi_endproc
1652
1653; DARWIN-X64-LABEL: test14a:
1654; DARWIN-X64-NOT: callq ___stack_chk_fail
1655; DARWIN-X64: .cfi_endproc
1656  %a = alloca i32, align 4
1657  %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1658  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
1659  ret void
1660}
1661
1662; test14b: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1663;          ssp attribute
1664; Requires no protector.
1665; Function Attrs: ssp
1666define void @test14b() #0 {
1667entry:
1668; LINUX-I386-LABEL: test14b:
1669; LINUX-I386-NOT: calll __stack_chk_fail
1670; LINUX-I386: .cfi_endproc
1671
1672; LINUX-X64-LABEL: test14b:
1673; LINUX-X64-NOT: callq __stack_chk_fail
1674; LINUX-X64: .cfi_endproc
1675
1676; LINUX-KERNEL-X64-LABEL: test14b:
1677; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1678; LINUX-KERNEL-X64: .cfi_endproc
1679
1680; DARWIN-X64-LABEL: test14b:
1681; DARWIN-X64-NOT: callq ___stack_chk_fail
1682; DARWIN-X64: .cfi_endproc
1683  %a = alloca i32, align 4
1684  %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1685  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
1686  ret void
1687}
1688
1689; test14c: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1690;          sspstrong attribute
1691; Requires protector.
1692; Function Attrs: sspstrong
1693define void @test14c() #1 {
1694entry:
1695; LINUX-I386-LABEL: test14c:
1696; LINUX-I386: mov{{l|q}} %gs:
1697; LINUX-I386: calll __stack_chk_fail
1698
1699; LINUX-X64-LABEL: test14c:
1700; LINUX-X64: mov{{l|q}} %fs:
1701; LINUX-X64: callq __stack_chk_fail
1702
1703; LINUX-KERNEL-X64-LABEL: test14c:
1704; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1705; LINUX-KERNEL-X64: callq __stack_chk_fail
1706
1707; DARWIN-X64-LABEL: test14c:
1708; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1709; DARWIN-X64: callq ___stack_chk_fail
1710  %a = alloca i32, align 4
1711  %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1712  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
1713  ret void
1714}
1715
1716; test14d: Addr-of a local, optimized into a GEP (e.g., &a - 12)
1717;          sspreq  attribute
1718; Requires protector.
1719; Function Attrs: sspreq
1720define void @test14d() #2 {
1721entry:
1722; LINUX-I386-LABEL: test14d:
1723; LINUX-I386: mov{{l|q}} %gs:
1724; LINUX-I386: calll __stack_chk_fail
1725
1726; LINUX-X64-LABEL: test14d:
1727; LINUX-X64: mov{{l|q}} %fs:
1728; LINUX-X64: callq __stack_chk_fail
1729
1730; LINUX-KERNEL-X64-LABEL: test14d:
1731; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1732; LINUX-KERNEL-X64: callq __stack_chk_fail
1733
1734; DARWIN-X64-LABEL: test14d:
1735; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1736; DARWIN-X64: callq ___stack_chk_fail
1737  %a = alloca i32, align 4
1738  %add.ptr5 = getelementptr inbounds i32* %a, i64 -12
1739  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
1740  ret void
1741}
1742
1743; test15a: Addr-of a local cast to a ptr of a different type
1744;           (e.g., int a; ... ; float *b = &a;)
1745;          no ssp attribute
1746; Requires no protector.
1747define void @test15a() {
1748entry:
1749; LINUX-I386-LABEL: test15a:
1750; LINUX-I386-NOT: calll __stack_chk_fail
1751; LINUX-I386: .cfi_endproc
1752
1753; LINUX-X64-LABEL: test15a:
1754; LINUX-X64-NOT: callq __stack_chk_fail
1755; LINUX-X64: .cfi_endproc
1756
1757; LINUX-KERNEL-X64-LABEL: test15a:
1758; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1759; LINUX-KERNEL-X64: .cfi_endproc
1760
1761; DARWIN-X64-LABEL: test15a:
1762; DARWIN-X64-NOT: callq ___stack_chk_fail
1763; DARWIN-X64: .cfi_endproc
1764  %a = alloca i32, align 4
1765  %b = alloca float*, align 8
1766  store i32 0, i32* %a, align 4
1767  %0 = bitcast i32* %a to float*
1768  store float* %0, float** %b, align 8
1769  %1 = load float** %b, align 8
1770  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1771  ret void
1772}
1773
1774; test15b: Addr-of a local cast to a ptr of a different type
1775;           (e.g., int a; ... ; float *b = &a;)
1776;          ssp attribute
1777; Requires no protector.
1778; Function Attrs: ssp
1779define void @test15b() #0 {
1780entry:
1781; LINUX-I386-LABEL: test15b:
1782; LINUX-I386-NOT: calll __stack_chk_fail
1783; LINUX-I386: .cfi_endproc
1784
1785; LINUX-X64-LABEL: test15b:
1786; LINUX-X64-NOT: callq __stack_chk_fail
1787; LINUX-X64: .cfi_endproc
1788
1789; LINUX-KERNEL-X64-LABEL: test15b:
1790; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1791; LINUX-KERNEL-X64: .cfi_endproc
1792
1793; DARWIN-X64-LABEL: test15b:
1794; DARWIN-X64-NOT: callq ___stack_chk_fail
1795; DARWIN-X64: .cfi_endproc
1796  %a = alloca i32, align 4
1797  %b = alloca float*, align 8
1798  store i32 0, i32* %a, align 4
1799  %0 = bitcast i32* %a to float*
1800  store float* %0, float** %b, align 8
1801  %1 = load float** %b, align 8
1802  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1803  ret void
1804}
1805
1806; test15c: Addr-of a local cast to a ptr of a different type
1807;           (e.g., int a; ... ; float *b = &a;)
1808;          sspstrong attribute
1809; Requires protector.
1810; Function Attrs: sspstrong
1811define void @test15c() #1 {
1812entry:
1813; LINUX-I386-LABEL: test15c:
1814; LINUX-I386: mov{{l|q}} %gs:
1815; LINUX-I386: calll __stack_chk_fail
1816
1817; LINUX-X64-LABEL: test15c:
1818; LINUX-X64: mov{{l|q}} %fs:
1819; LINUX-X64: callq __stack_chk_fail
1820
1821; LINUX-KERNEL-X64-LABEL: test15c:
1822; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1823; LINUX-KERNEL-X64: callq __stack_chk_fail
1824
1825; DARWIN-X64-LABEL: test15c:
1826; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1827; DARWIN-X64: callq ___stack_chk_fail
1828  %a = alloca i32, align 4
1829  %b = alloca float*, align 8
1830  store i32 0, i32* %a, align 4
1831  %0 = bitcast i32* %a to float*
1832  store float* %0, float** %b, align 8
1833  %1 = load float** %b, align 8
1834  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1835  ret void
1836}
1837
1838; test15d: Addr-of a local cast to a ptr of a different type
1839;           (e.g., int a; ... ; float *b = &a;)
1840;          sspreq attribute
1841; Requires protector.
1842; Function Attrs: sspreq
1843define void @test15d() #2 {
1844entry:
1845; LINUX-I386-LABEL: test15d:
1846; LINUX-I386: mov{{l|q}} %gs:
1847; LINUX-I386: calll __stack_chk_fail
1848
1849; LINUX-X64-LABEL: test15d:
1850; LINUX-X64: mov{{l|q}} %fs:
1851; LINUX-X64: callq __stack_chk_fail
1852
1853; LINUX-KERNEL-X64-LABEL: test15d:
1854; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1855; LINUX-KERNEL-X64: callq __stack_chk_fail
1856
1857; DARWIN-X64-LABEL: test15d:
1858; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1859; DARWIN-X64: callq ___stack_chk_fail
1860  %a = alloca i32, align 4
1861  %b = alloca float*, align 8
1862  store i32 0, i32* %a, align 4
1863  %0 = bitcast i32* %a to float*
1864  store float* %0, float** %b, align 8
1865  %1 = load float** %b, align 8
1866  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), float* %1)
1867  ret void
1868}
1869
1870; test16a: Addr-of a local cast to a ptr of a different type (optimized)
1871;           (e.g., int a; ... ; float *b = &a;)
1872;          no ssp attribute
1873; Requires no protector.
1874define void @test16a() {
1875entry:
1876; LINUX-I386-LABEL: test16a:
1877; LINUX-I386-NOT: calll __stack_chk_fail
1878; LINUX-I386: .cfi_endproc
1879
1880; LINUX-X64-LABEL: test16a:
1881; LINUX-X64-NOT: callq __stack_chk_fail
1882; LINUX-X64: .cfi_endproc
1883
1884; LINUX-KERNEL-X64-LABEL: test16a:
1885; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1886; LINUX-KERNEL-X64: .cfi_endproc
1887
1888; DARWIN-X64-LABEL: test16a:
1889; DARWIN-X64-NOT: callq ___stack_chk_fail
1890; DARWIN-X64: .cfi_endproc
1891  %a = alloca i32, align 4
1892  store i32 0, i32* %a, align 4
1893  %0 = bitcast i32* %a to float*
1894  call void @funfloat(float* %0)
1895  ret void
1896}
1897
1898; test16b: Addr-of a local cast to a ptr of a different type (optimized)
1899;           (e.g., int a; ... ; float *b = &a;)
1900;          ssp attribute
1901; Requires no protector.
1902; Function Attrs: ssp
1903define void @test16b() #0 {
1904entry:
1905; LINUX-I386-LABEL: test16b:
1906; LINUX-I386-NOT: calll __stack_chk_fail
1907; LINUX-I386: .cfi_endproc
1908
1909; LINUX-X64-LABEL: test16b:
1910; LINUX-X64-NOT: callq __stack_chk_fail
1911; LINUX-X64: .cfi_endproc
1912
1913; LINUX-KERNEL-X64-LABEL: test16b:
1914; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1915; LINUX-KERNEL-X64: .cfi_endproc
1916
1917; DARWIN-X64-LABEL: test16b:
1918; DARWIN-X64-NOT: callq ___stack_chk_fail
1919; DARWIN-X64: .cfi_endproc
1920  %a = alloca i32, align 4
1921  store i32 0, i32* %a, align 4
1922  %0 = bitcast i32* %a to float*
1923  call void @funfloat(float* %0)
1924  ret void
1925}
1926
1927; test16c: Addr-of a local cast to a ptr of a different type (optimized)
1928;           (e.g., int a; ... ; float *b = &a;)
1929;          sspstrong attribute
1930; Requires protector.
1931; Function Attrs: sspstrong
1932define void @test16c() #1 {
1933entry:
1934; LINUX-I386-LABEL: test16c:
1935; LINUX-I386: mov{{l|q}} %gs:
1936; LINUX-I386: calll __stack_chk_fail
1937
1938; LINUX-X64-LABEL: test16c:
1939; LINUX-X64: mov{{l|q}} %fs:
1940; LINUX-X64: callq __stack_chk_fail
1941
1942; LINUX-KERNEL-X64-LABEL: test16c:
1943; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1944; LINUX-KERNEL-X64: callq __stack_chk_fail
1945
1946; DARWIN-X64-LABEL: test16c:
1947; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1948; DARWIN-X64: callq ___stack_chk_fail
1949  %a = alloca i32, align 4
1950  store i32 0, i32* %a, align 4
1951  %0 = bitcast i32* %a to float*
1952  call void @funfloat(float* %0)
1953  ret void
1954}
1955
1956; test16d: Addr-of a local cast to a ptr of a different type (optimized)
1957;           (e.g., int a; ... ; float *b = &a;)
1958;          sspreq attribute
1959; Requires protector.
1960; Function Attrs: sspreq
1961define void @test16d() #2 {
1962entry:
1963; LINUX-I386-LABEL: test16d:
1964; LINUX-I386: mov{{l|q}} %gs:
1965; LINUX-I386: calll __stack_chk_fail
1966
1967; LINUX-X64-LABEL: test16d:
1968; LINUX-X64: mov{{l|q}} %fs:
1969; LINUX-X64: callq __stack_chk_fail
1970
1971; LINUX-KERNEL-X64-LABEL: test16d:
1972; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1973; LINUX-KERNEL-X64: callq __stack_chk_fail
1974
1975; DARWIN-X64-LABEL: test16d:
1976; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1977; DARWIN-X64: callq ___stack_chk_fail
1978  %a = alloca i32, align 4
1979  store i32 0, i32* %a, align 4
1980  %0 = bitcast i32* %a to float*
1981  call void @funfloat(float* %0)
1982  ret void
1983}
1984
1985; test17a: Addr-of a vector nested in a struct
1986;          no ssp attribute
1987; Requires no protector.
1988define void @test17a() {
1989entry:
1990; LINUX-I386-LABEL: test17a:
1991; LINUX-I386-NOT: calll __stack_chk_fail
1992; LINUX-I386: .cfi_endproc
1993
1994; LINUX-X64-LABEL: test17a:
1995; LINUX-X64-NOT: callq __stack_chk_fail
1996; LINUX-X64: .cfi_endproc
1997
1998; LINUX-KERNEL-X64-LABEL: test17a:
1999; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2000; LINUX-KERNEL-X64: .cfi_endproc
2001
2002; DARWIN-X64-LABEL: test17a:
2003; DARWIN-X64-NOT: callq ___stack_chk_fail
2004; DARWIN-X64: .cfi_endproc
2005  %c = alloca %struct.vec, align 16
2006  %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
2007  %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
2008  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2009  ret void
2010}
2011
2012; test17b: Addr-of a vector nested in a struct
2013;          ssp attribute
2014; Requires no protector.
2015; Function Attrs: ssp
2016define void @test17b() #0 {
2017entry:
2018; LINUX-I386-LABEL: test17b:
2019; LINUX-I386-NOT: calll __stack_chk_fail
2020; LINUX-I386: .cfi_endproc
2021
2022; LINUX-X64-LABEL: test17b:
2023; LINUX-X64-NOT: callq __stack_chk_fail
2024; LINUX-X64: .cfi_endproc
2025
2026; LINUX-KERNEL-X64-LABEL: test17b:
2027; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2028; LINUX-KERNEL-X64: .cfi_endproc
2029
2030; DARWIN-X64-LABEL: test17b:
2031; DARWIN-X64-NOT: callq ___stack_chk_fail
2032; DARWIN-X64: .cfi_endproc
2033  %c = alloca %struct.vec, align 16
2034  %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
2035  %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
2036  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2037  ret void
2038}
2039
2040; test17c: Addr-of a vector nested in a struct
2041;          sspstrong attribute
2042; Requires protector.
2043; Function Attrs: sspstrong
2044define void @test17c() #1 {
2045entry:
2046; LINUX-I386-LABEL: test17c:
2047; LINUX-I386: mov{{l|q}} %gs:
2048; LINUX-I386: calll __stack_chk_fail
2049
2050; LINUX-X64-LABEL: test17c:
2051; LINUX-X64: mov{{l|q}} %fs:
2052; LINUX-X64: callq __stack_chk_fail
2053
2054; LINUX-KERNEL-X64-LABEL: test17c:
2055; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2056; LINUX-KERNEL-X64: callq __stack_chk_fail
2057
2058; DARWIN-X64-LABEL: test17c:
2059; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2060; DARWIN-X64: callq ___stack_chk_fail
2061  %c = alloca %struct.vec, align 16
2062  %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
2063  %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
2064  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2065  ret void
2066}
2067
2068; test17d: Addr-of a vector nested in a struct
2069;          sspreq attribute
2070; Requires protector.
2071; Function Attrs: sspreq
2072define void @test17d() #2 {
2073entry:
2074; LINUX-I386-LABEL: test17d:
2075; LINUX-I386: mov{{l|q}} %gs:
2076; LINUX-I386: calll __stack_chk_fail
2077
2078; LINUX-X64-LABEL: test17d:
2079; LINUX-X64: mov{{l|q}} %fs:
2080; LINUX-X64: callq __stack_chk_fail
2081
2082; LINUX-KERNEL-X64-LABEL: test17d:
2083; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2084; LINUX-KERNEL-X64: callq __stack_chk_fail
2085
2086; DARWIN-X64-LABEL: test17d:
2087; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2088; DARWIN-X64: callq ___stack_chk_fail
2089  %c = alloca %struct.vec, align 16
2090  %y = getelementptr inbounds %struct.vec* %c, i64 0, i32 0
2091  %add.ptr = getelementptr inbounds <4 x i32>* %y, i64 -12
2092  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2093  ret void
2094}
2095
2096; test18a: Addr-of a variable passed into an invoke instruction.
2097;          no ssp attribute
2098; Requires no protector.
2099define i32 @test18a()  {
2100entry:
2101; LINUX-I386-LABEL: test18a:
2102; LINUX-I386-NOT: calll __stack_chk_fail
2103; LINUX-I386: .cfi_endproc
2104
2105; LINUX-X64-LABEL: test18a:
2106; LINUX-X64-NOT: callq __stack_chk_fail
2107; LINUX-X64: .cfi_endproc
2108
2109; LINUX-KERNEL-X64-LABEL: test18a:
2110; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2111; LINUX-KERNEL-X64: .cfi_endproc
2112
2113; DARWIN-X64-LABEL: test18a:
2114; DARWIN-X64-NOT: callq ___stack_chk_fail
2115; DARWIN-X64: .cfi_endproc
2116  %a = alloca i32, align 4
2117  %exn.slot = alloca i8*
2118  %ehselector.slot = alloca i32
2119  store i32 0, i32* %a, align 4
2120  invoke void @_Z3exceptPi(i32* %a)
2121          to label %invoke.cont unwind label %lpad
2122
2123invoke.cont:
2124  ret i32 0
2125
2126lpad:
2127  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2128          catch i8* null
2129  ret i32 0
2130}
2131
2132; test18b: Addr-of a variable passed into an invoke instruction.
2133;          ssp attribute
2134; Requires no protector.
2135; Function Attrs: ssp
2136define i32 @test18b() #0 {
2137entry:
2138; LINUX-I386-LABEL: test18b:
2139; LINUX-I386-NOT: calll __stack_chk_fail
2140; LINUX-I386: .cfi_endproc
2141
2142; LINUX-X64-LABEL: test18b:
2143; LINUX-X64-NOT: callq __stack_chk_fail
2144; LINUX-X64: .cfi_endproc
2145
2146; LINUX-KERNEL-X64-LABEL: test18b:
2147; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2148; LINUX-KERNEL-X64: .cfi_endproc
2149
2150; DARWIN-X64-LABEL: test18b:
2151; DARWIN-X64-NOT: callq ___stack_chk_fail
2152; DARWIN-X64: .cfi_endproc
2153  %a = alloca i32, align 4
2154  %exn.slot = alloca i8*
2155  %ehselector.slot = alloca i32
2156  store i32 0, i32* %a, align 4
2157  invoke void @_Z3exceptPi(i32* %a)
2158          to label %invoke.cont unwind label %lpad
2159
2160invoke.cont:
2161  ret i32 0
2162
2163lpad:
2164  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2165          catch i8* null
2166  ret i32 0
2167}
2168
2169; test18c: Addr-of a variable passed into an invoke instruction.
2170;          sspstrong attribute
2171; Requires protector.
2172; Function Attrs: sspstrong
2173define i32 @test18c() #1 {
2174entry:
2175; LINUX-I386-LABEL: test18c:
2176; LINUX-I386: mov{{l|q}} %gs:
2177; LINUX-I386: calll __stack_chk_fail
2178
2179; LINUX-X64-LABEL: test18c:
2180; LINUX-X64: mov{{l|q}} %fs:
2181; LINUX-X64: callq __stack_chk_fail
2182
2183; LINUX-KERNEL-X64-LABEL: test18c:
2184; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2185; LINUX-KERNEL-X64: callq __stack_chk_fail
2186
2187; DARWIN-X64-LABEL: test18c:
2188; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2189; DARWIN-X64: callq ___stack_chk_fail
2190  %a = alloca i32, align 4
2191  %exn.slot = alloca i8*
2192  %ehselector.slot = alloca i32
2193  store i32 0, i32* %a, align 4
2194  invoke void @_Z3exceptPi(i32* %a)
2195          to label %invoke.cont unwind label %lpad
2196
2197invoke.cont:
2198  ret i32 0
2199
2200lpad:
2201  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2202          catch i8* null
2203  ret i32 0
2204}
2205
2206; test18d: Addr-of a variable passed into an invoke instruction.
2207;          sspreq attribute
2208; Requires protector.
2209; Function Attrs: sspreq
2210define i32 @test18d() #2 {
2211entry:
2212; LINUX-I386-LABEL: test18d:
2213; LINUX-I386: mov{{l|q}} %gs:
2214; LINUX-I386: calll __stack_chk_fail
2215
2216; LINUX-X64-LABEL: test18d:
2217; LINUX-X64: mov{{l|q}} %fs:
2218; LINUX-X64: callq __stack_chk_fail
2219
2220; LINUX-KERNEL-X64-LABEL: test18d:
2221; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2222; LINUX-KERNEL-X64: callq __stack_chk_fail
2223
2224; DARWIN-X64-LABEL: test18d:
2225; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2226; DARWIN-X64: callq ___stack_chk_fail
2227  %a = alloca i32, align 4
2228  %exn.slot = alloca i8*
2229  %ehselector.slot = alloca i32
2230  store i32 0, i32* %a, align 4
2231  invoke void @_Z3exceptPi(i32* %a)
2232          to label %invoke.cont unwind label %lpad
2233
2234invoke.cont:
2235  ret i32 0
2236
2237lpad:
2238  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2239          catch i8* null
2240  ret i32 0
2241}
2242; test19a: Addr-of a struct element passed into an invoke instruction.
2243;           (GEP followed by an invoke)
2244;          no ssp attribute
2245; Requires no protector.
2246define i32 @test19a()  {
2247entry:
2248; LINUX-I386-LABEL: test19a:
2249; LINUX-I386-NOT: calll __stack_chk_fail
2250; LINUX-I386: .cfi_endproc
2251
2252; LINUX-X64-LABEL: test19a:
2253; LINUX-X64-NOT: callq __stack_chk_fail
2254; LINUX-X64: .cfi_endproc
2255
2256; LINUX-KERNEL-X64-LABEL: test19a:
2257; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2258; LINUX-KERNEL-X64: .cfi_endproc
2259
2260; DARWIN-X64-LABEL: test19a:
2261; DARWIN-X64-NOT: callq ___stack_chk_fail
2262; DARWIN-X64: .cfi_endproc
2263  %c = alloca %struct.pair, align 4
2264  %exn.slot = alloca i8*
2265  %ehselector.slot = alloca i32
2266  %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2267  store i32 0, i32* %a, align 4
2268  %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2269  invoke void @_Z3exceptPi(i32* %a1)
2270          to label %invoke.cont unwind label %lpad
2271
2272invoke.cont:
2273  ret i32 0
2274
2275lpad:
2276  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2277          catch i8* null
2278  ret i32 0
2279}
2280
2281; test19b: Addr-of a struct element passed into an invoke instruction.
2282;           (GEP followed by an invoke)
2283;          ssp attribute
2284; Requires no protector.
2285; Function Attrs: ssp
2286define i32 @test19b() #0 {
2287entry:
2288; LINUX-I386-LABEL: test19b:
2289; LINUX-I386-NOT: calll __stack_chk_fail
2290; LINUX-I386: .cfi_endproc
2291
2292; LINUX-X64-LABEL: test19b:
2293; LINUX-X64-NOT: callq __stack_chk_fail
2294; LINUX-X64: .cfi_endproc
2295
2296; LINUX-KERNEL-X64-LABEL: test19b:
2297; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2298; LINUX-KERNEL-X64: .cfi_endproc
2299
2300; DARWIN-X64-LABEL: test19b:
2301; DARWIN-X64-NOT: callq ___stack_chk_fail
2302; DARWIN-X64: .cfi_endproc
2303  %c = alloca %struct.pair, align 4
2304  %exn.slot = alloca i8*
2305  %ehselector.slot = alloca i32
2306  %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2307  store i32 0, i32* %a, align 4
2308  %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2309  invoke void @_Z3exceptPi(i32* %a1)
2310          to label %invoke.cont unwind label %lpad
2311
2312invoke.cont:
2313  ret i32 0
2314
2315lpad:
2316  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2317          catch i8* null
2318  ret i32 0
2319}
2320
2321; test19c: Addr-of a struct element passed into an invoke instruction.
2322;           (GEP followed by an invoke)
2323;          sspstrong attribute
2324; Requires protector.
2325; Function Attrs: sspstrong
2326define i32 @test19c() #1 {
2327entry:
2328; LINUX-I386-LABEL: test19c:
2329; LINUX-I386: mov{{l|q}} %gs:
2330; LINUX-I386: calll __stack_chk_fail
2331
2332; LINUX-X64-LABEL: test19c:
2333; LINUX-X64: mov{{l|q}} %fs:
2334; LINUX-X64: callq __stack_chk_fail
2335
2336; LINUX-KERNEL-X64-LABEL: test19c:
2337; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2338; LINUX-KERNEL-X64: callq __stack_chk_fail
2339
2340; DARWIN-X64-LABEL: test19c:
2341; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2342; DARWIN-X64: callq ___stack_chk_fail
2343  %c = alloca %struct.pair, align 4
2344  %exn.slot = alloca i8*
2345  %ehselector.slot = alloca i32
2346  %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2347  store i32 0, i32* %a, align 4
2348  %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2349  invoke void @_Z3exceptPi(i32* %a1)
2350          to label %invoke.cont unwind label %lpad
2351
2352invoke.cont:
2353  ret i32 0
2354
2355lpad:
2356  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2357          catch i8* null
2358  ret i32 0
2359}
2360
2361; test19d: Addr-of a struct element passed into an invoke instruction.
2362;           (GEP followed by an invoke)
2363;          sspreq attribute
2364; Requires protector.
2365; Function Attrs: sspreq
2366define i32 @test19d() #2 {
2367entry:
2368; LINUX-I386-LABEL: test19d:
2369; LINUX-I386: mov{{l|q}} %gs:
2370; LINUX-I386: calll __stack_chk_fail
2371; LINUX-I386-NOT: calll __stack_chk_fail
2372
2373; LINUX-X64-LABEL: test19d:
2374; LINUX-X64: mov{{l|q}} %fs:
2375; LINUX-X64: callq __stack_chk_fail
2376; LINUX-X64-NOT: callq __stack_chk_fail
2377
2378; LINUX-KERNEL-X64-LABEL: test19d:
2379; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2380; LINUX-KERNEL-X64: callq __stack_chk_fail
2381; LINUX-KERNEL-X64-NOT: callq ___stack_chk_fail
2382
2383; DARWIN-X64-LABEL: test19d:
2384; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2385; DARWIN-X64: callq ___stack_chk_fail
2386; DARWIN-X64-NOT: callq ___stack_chk_fail
2387  %c = alloca %struct.pair, align 4
2388  %exn.slot = alloca i8*
2389  %ehselector.slot = alloca i32
2390  %a = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2391  store i32 0, i32* %a, align 4
2392  %a1 = getelementptr inbounds %struct.pair* %c, i32 0, i32 0
2393  invoke void @_Z3exceptPi(i32* %a1)
2394          to label %invoke.cont unwind label %lpad
2395
2396invoke.cont:
2397  ret i32 0
2398
2399lpad:
2400  %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
2401          catch i8* null
2402  ret i32 0
2403}
2404
2405; test20a: Addr-of a pointer
2406;          no ssp attribute
2407; Requires no protector.
2408define void @test20a() {
2409entry:
2410; LINUX-I386-LABEL: test20a:
2411; LINUX-I386-NOT: calll __stack_chk_fail
2412; LINUX-I386: .cfi_endproc
2413
2414; LINUX-X64-LABEL: test20a:
2415; LINUX-X64-NOT: callq __stack_chk_fail
2416; LINUX-X64: .cfi_endproc
2417
2418; LINUX-KERNEL-X64-LABEL: test20a:
2419; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2420; LINUX-KERNEL-X64: .cfi_endproc
2421
2422; DARWIN-X64-LABEL: test20a:
2423; DARWIN-X64-NOT: callq ___stack_chk_fail
2424; DARWIN-X64: .cfi_endproc
2425  %a = alloca i32*, align 8
2426  %b = alloca i32**, align 8
2427  %call = call i32* @getp()
2428  store i32* %call, i32** %a, align 8
2429  store i32** %a, i32*** %b, align 8
2430  %0 = load i32*** %b, align 8
2431  call void @funcall2(i32** %0)
2432  ret void
2433}
2434
2435; test20b: Addr-of a pointer
2436;          ssp attribute
2437; Requires no protector.
2438; Function Attrs: ssp
2439define void @test20b() #0 {
2440entry:
2441; LINUX-I386-LABEL: test20b:
2442; LINUX-I386-NOT: calll __stack_chk_fail
2443; LINUX-I386: .cfi_endproc
2444
2445; LINUX-X64-LABEL: test20b:
2446; LINUX-X64-NOT: callq __stack_chk_fail
2447; LINUX-X64: .cfi_endproc
2448
2449; LINUX-KERNEL-X64-LABEL: test20b:
2450; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2451; LINUX-KERNEL-X64: .cfi_endproc
2452
2453; DARWIN-X64-LABEL: test20b:
2454; DARWIN-X64-NOT: callq ___stack_chk_fail
2455; DARWIN-X64: .cfi_endproc
2456  %a = alloca i32*, align 8
2457  %b = alloca i32**, align 8
2458  %call = call i32* @getp()
2459  store i32* %call, i32** %a, align 8
2460  store i32** %a, i32*** %b, align 8
2461  %0 = load i32*** %b, align 8
2462  call void @funcall2(i32** %0)
2463  ret void
2464}
2465
2466; test20c: Addr-of a pointer
2467;          sspstrong attribute
2468; Requires protector.
2469; Function Attrs: sspstrong
2470define void @test20c() #1 {
2471entry:
2472; LINUX-I386-LABEL: test20c:
2473; LINUX-I386: mov{{l|q}} %gs:
2474; LINUX-I386: calll __stack_chk_fail
2475
2476; LINUX-X64-LABEL: test20c:
2477; LINUX-X64: mov{{l|q}} %fs:
2478; LINUX-X64: callq __stack_chk_fail
2479
2480; LINUX-KERNEL-X64-LABEL: test20c:
2481; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2482; LINUX-KERNEL-X64: callq __stack_chk_fail
2483
2484; DARWIN-X64-LABEL: test20c:
2485; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2486; DARWIN-X64: callq ___stack_chk_fail
2487  %a = alloca i32*, align 8
2488  %b = alloca i32**, align 8
2489  %call = call i32* @getp()
2490  store i32* %call, i32** %a, align 8
2491  store i32** %a, i32*** %b, align 8
2492  %0 = load i32*** %b, align 8
2493  call void @funcall2(i32** %0)
2494  ret void
2495}
2496
2497; test20d: Addr-of a pointer
2498;          sspreq attribute
2499; Requires protector.
2500; Function Attrs: sspreq
2501define void @test20d() #2 {
2502entry:
2503; LINUX-I386-LABEL: test20d:
2504; LINUX-I386: mov{{l|q}} %gs:
2505; LINUX-I386: calll __stack_chk_fail
2506
2507; LINUX-X64-LABEL: test20d:
2508; LINUX-X64: mov{{l|q}} %fs:
2509; LINUX-X64: callq __stack_chk_fail
2510
2511; LINUX-KERNEL-X64-LABEL: test20d:
2512; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2513; LINUX-KERNEL-X64: callq __stack_chk_fail
2514
2515; DARWIN-X64-LABEL: test20d:
2516; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2517; DARWIN-X64: callq ___stack_chk_fail
2518  %a = alloca i32*, align 8
2519  %b = alloca i32**, align 8
2520  %call = call i32* @getp()
2521  store i32* %call, i32** %a, align 8
2522  store i32** %a, i32*** %b, align 8
2523  %0 = load i32*** %b, align 8
2524  call void @funcall2(i32** %0)
2525  ret void
2526}
2527
2528; test21a: Addr-of a casted pointer
2529;          no ssp attribute
2530; Requires no protector.
2531define void @test21a() {
2532entry:
2533; LINUX-I386-LABEL: test21a:
2534; LINUX-I386-NOT: calll __stack_chk_fail
2535; LINUX-I386: .cfi_endproc
2536
2537; LINUX-X64-LABEL: test21a:
2538; LINUX-X64-NOT: callq __stack_chk_fail
2539; LINUX-X64: .cfi_endproc
2540
2541; LINUX-KERNEL-X64-LABEL: test21a:
2542; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2543; LINUX-KERNEL-X64: .cfi_endproc
2544
2545; DARWIN-X64-LABEL: test21a:
2546; DARWIN-X64-NOT: callq ___stack_chk_fail
2547; DARWIN-X64: .cfi_endproc
2548  %a = alloca i32*, align 8
2549  %b = alloca float**, align 8
2550  %call = call i32* @getp()
2551  store i32* %call, i32** %a, align 8
2552  %0 = bitcast i32** %a to float**
2553  store float** %0, float*** %b, align 8
2554  %1 = load float*** %b, align 8
2555  call void @funfloat2(float** %1)
2556  ret void
2557}
2558
2559; test21b: Addr-of a casted pointer
2560;          ssp attribute
2561; Requires no protector.
2562; Function Attrs: ssp
2563define void @test21b() #0 {
2564entry:
2565; LINUX-I386-LABEL: test21b:
2566; LINUX-I386-NOT: calll __stack_chk_fail
2567; LINUX-I386: .cfi_endproc
2568
2569; LINUX-X64-LABEL: test21b:
2570; LINUX-X64-NOT: callq __stack_chk_fail
2571; LINUX-X64: .cfi_endproc
2572
2573; LINUX-KERNEL-X64-LABEL: test21b:
2574; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2575; LINUX-KERNEL-X64: .cfi_endproc
2576
2577; DARWIN-X64-LABEL: test21b:
2578; DARWIN-X64-NOT: callq ___stack_chk_fail
2579; DARWIN-X64: .cfi_endproc
2580  %a = alloca i32*, align 8
2581  %b = alloca float**, align 8
2582  %call = call i32* @getp()
2583  store i32* %call, i32** %a, align 8
2584  %0 = bitcast i32** %a to float**
2585  store float** %0, float*** %b, align 8
2586  %1 = load float*** %b, align 8
2587  call void @funfloat2(float** %1)
2588  ret void
2589}
2590
2591; test21c: Addr-of a casted pointer
2592;          sspstrong attribute
2593; Requires protector.
2594; Function Attrs: sspstrong
2595define void @test21c() #1 {
2596entry:
2597; LINUX-I386-LABEL: test21c:
2598; LINUX-I386: mov{{l|q}} %gs:
2599; LINUX-I386: calll __stack_chk_fail
2600
2601; LINUX-X64-LABEL: test21c:
2602; LINUX-X64: mov{{l|q}} %fs:
2603; LINUX-X64: callq __stack_chk_fail
2604
2605; LINUX-KERNEL-X64-LABEL: test21c:
2606; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2607; LINUX-KERNEL-X64: callq __stack_chk_fail
2608
2609; DARWIN-X64-LABEL: test21c:
2610; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2611; DARWIN-X64: callq ___stack_chk_fail
2612  %a = alloca i32*, align 8
2613  %b = alloca float**, align 8
2614  %call = call i32* @getp()
2615  store i32* %call, i32** %a, align 8
2616  %0 = bitcast i32** %a to float**
2617  store float** %0, float*** %b, align 8
2618  %1 = load float*** %b, align 8
2619  call void @funfloat2(float** %1)
2620  ret void
2621}
2622
2623; test21d: Addr-of a casted pointer
2624;          sspreq attribute
2625; Requires protector.
2626; Function Attrs: sspreq
2627define void @test21d() #2 {
2628entry:
2629; LINUX-I386-LABEL: test21d:
2630; LINUX-I386: mov{{l|q}} %gs:
2631; LINUX-I386: calll __stack_chk_fail
2632
2633; LINUX-X64-LABEL: test21d:
2634; LINUX-X64: mov{{l|q}} %fs:
2635; LINUX-X64: callq __stack_chk_fail
2636
2637; LINUX-KERNEL-X64-LABEL: test21d:
2638; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2639; LINUX-KERNEL-X64: callq __stack_chk_fail
2640
2641; DARWIN-X64-LABEL: test21d:
2642; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2643; DARWIN-X64: callq ___stack_chk_fail
2644  %a = alloca i32*, align 8
2645  %b = alloca float**, align 8
2646  %call = call i32* @getp()
2647  store i32* %call, i32** %a, align 8
2648  %0 = bitcast i32** %a to float**
2649  store float** %0, float*** %b, align 8
2650  %1 = load float*** %b, align 8
2651  call void @funfloat2(float** %1)
2652  ret void
2653}
2654
2655; test22a: [2 x i8] in a class
2656;          no ssp attribute
2657; Requires no protector.
2658define signext i8 @test22a() {
2659entry:
2660; LINUX-I386-LABEL: test22a:
2661; LINUX-I386-NOT: calll __stack_chk_fail
2662; LINUX-I386: .cfi_endproc
2663
2664; LINUX-X64-LABEL: test22a:
2665; LINUX-X64-NOT: callq __stack_chk_fail
2666; LINUX-X64: .cfi_endproc
2667
2668; LINUX-KERNEL-X64-LABEL: test22a:
2669; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2670; LINUX-KERNEL-X64: .cfi_endproc
2671
2672; DARWIN-X64-LABEL: test22a:
2673; DARWIN-X64-NOT: callq ___stack_chk_fail
2674; DARWIN-X64: .cfi_endproc
2675  %a = alloca %class.A, align 1
2676  %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2677  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2678  %0 = load i8* %arrayidx, align 1
2679  ret i8 %0
2680}
2681
2682; test22b: [2 x i8] in a class
2683;          ssp attribute
2684; Requires no protector.
2685; Function Attrs: ssp
2686define signext i8 @test22b() #0 {
2687entry:
2688; LINUX-I386-LABEL: test22b:
2689; LINUX-I386-NOT: calll __stack_chk_fail
2690; LINUX-I386: .cfi_endproc
2691
2692; LINUX-X64-LABEL: test22b:
2693; LINUX-X64-NOT: callq __stack_chk_fail
2694; LINUX-X64: .cfi_endproc
2695
2696; LINUX-KERNEL-X64-LABEL: test22b:
2697; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2698; LINUX-KERNEL-X64: .cfi_endproc
2699
2700; DARWIN-X64-LABEL: test22b:
2701; DARWIN-X64-NOT: callq ___stack_chk_fail
2702; DARWIN-X64: .cfi_endproc
2703  %a = alloca %class.A, align 1
2704  %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2705  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2706  %0 = load i8* %arrayidx, align 1
2707  ret i8 %0
2708}
2709
2710; test22c: [2 x i8] in a class
2711;          sspstrong attribute
2712; Requires protector.
2713; Function Attrs: sspstrong
2714define signext i8 @test22c() #1 {
2715entry:
2716; LINUX-I386-LABEL: test22c:
2717; LINUX-I386: mov{{l|q}} %gs:
2718; LINUX-I386: calll __stack_chk_fail
2719
2720; LINUX-X64-LABEL: test22c:
2721; LINUX-X64: mov{{l|q}} %fs:
2722; LINUX-X64: callq __stack_chk_fail
2723
2724; LINUX-KERNEL-X64-LABEL: test22c:
2725; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2726; LINUX-KERNEL-X64: callq __stack_chk_fail
2727
2728; DARWIN-X64-LABEL: test22c:
2729; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2730; DARWIN-X64: callq ___stack_chk_fail
2731  %a = alloca %class.A, align 1
2732  %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2733  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2734  %0 = load i8* %arrayidx, align 1
2735  ret i8 %0
2736}
2737
2738; test22d: [2 x i8] in a class
2739;          sspreq attribute
2740; Requires protector.
2741; Function Attrs: sspreq
2742define signext i8 @test22d() #2 {
2743entry:
2744; LINUX-I386-LABEL: test22d:
2745; LINUX-I386: mov{{l|q}} %gs:
2746; LINUX-I386: calll __stack_chk_fail
2747
2748; LINUX-X64-LABEL: test22d:
2749; LINUX-X64: mov{{l|q}} %fs:
2750; LINUX-X64: callq __stack_chk_fail
2751
2752; LINUX-KERNEL-X64-LABEL: test22d:
2753; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2754; LINUX-KERNEL-X64: callq __stack_chk_fail
2755
2756; DARWIN-X64-LABEL: test22d:
2757; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2758; DARWIN-X64: callq ___stack_chk_fail
2759  %a = alloca %class.A, align 1
2760  %array = getelementptr inbounds %class.A* %a, i32 0, i32 0
2761  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2762  %0 = load i8* %arrayidx, align 1
2763  ret i8 %0
2764}
2765
2766; test23a: [2 x i8] nested in several layers of structs and unions
2767;          no ssp attribute
2768; Requires no protector.
2769define signext i8 @test23a() {
2770entry:
2771; LINUX-I386-LABEL: test23a:
2772; LINUX-I386-NOT: calll __stack_chk_fail
2773; LINUX-I386: .cfi_endproc
2774
2775; LINUX-X64-LABEL: test23a:
2776; LINUX-X64-NOT: callq __stack_chk_fail
2777; LINUX-X64: .cfi_endproc
2778
2779; LINUX-KERNEL-X64-LABEL: test23a:
2780; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2781; LINUX-KERNEL-X64: .cfi_endproc
2782
2783; DARWIN-X64-LABEL: test23a:
2784; DARWIN-X64-NOT: callq ___stack_chk_fail
2785; DARWIN-X64: .cfi_endproc
2786  %x = alloca %struct.deep, align 1
2787  %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2788  %c = bitcast %union.anon* %b to %struct.anon*
2789  %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2790  %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2791  %array = bitcast %union.anon.1* %e to [2 x i8]*
2792  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2793  %0 = load i8* %arrayidx, align 1
2794  ret i8 %0
2795}
2796
2797; test23b: [2 x i8] nested in several layers of structs and unions
2798;          ssp attribute
2799; Requires no protector.
2800; Function Attrs: ssp
2801define signext i8 @test23b() #0 {
2802entry:
2803; LINUX-I386-LABEL: test23b:
2804; LINUX-I386-NOT: calll __stack_chk_fail
2805; LINUX-I386: .cfi_endproc
2806
2807; LINUX-X64-LABEL: test23b:
2808; LINUX-X64-NOT: callq __stack_chk_fail
2809; LINUX-X64: .cfi_endproc
2810
2811; LINUX-KERNEL-X64-LABEL: test23b:
2812; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2813; LINUX-KERNEL-X64: .cfi_endproc
2814
2815; DARWIN-X64-LABEL: test23b:
2816; DARWIN-X64-NOT: callq ___stack_chk_fail
2817; DARWIN-X64: .cfi_endproc
2818  %x = alloca %struct.deep, align 1
2819  %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2820  %c = bitcast %union.anon* %b to %struct.anon*
2821  %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2822  %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2823  %array = bitcast %union.anon.1* %e to [2 x i8]*
2824  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2825  %0 = load i8* %arrayidx, align 1
2826  ret i8 %0
2827}
2828
2829; test23c: [2 x i8] nested in several layers of structs and unions
2830;          sspstrong attribute
2831; Requires protector.
2832; Function Attrs: sspstrong
2833define signext i8 @test23c() #1 {
2834entry:
2835; LINUX-I386-LABEL: test23c:
2836; LINUX-I386: mov{{l|q}} %gs:
2837; LINUX-I386: calll __stack_chk_fail
2838
2839; LINUX-X64-LABEL: test23c:
2840; LINUX-X64: mov{{l|q}} %fs:
2841; LINUX-X64: callq __stack_chk_fail
2842
2843; LINUX-KERNEL-X64-LABEL: test23c:
2844; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2845; LINUX-KERNEL-X64: callq __stack_chk_fail
2846
2847; DARWIN-X64-LABEL: test23c:
2848; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2849; DARWIN-X64: callq ___stack_chk_fail
2850  %x = alloca %struct.deep, align 1
2851  %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2852  %c = bitcast %union.anon* %b to %struct.anon*
2853  %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2854  %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2855  %array = bitcast %union.anon.1* %e to [2 x i8]*
2856  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2857  %0 = load i8* %arrayidx, align 1
2858  ret i8 %0
2859}
2860
2861; test23d: [2 x i8] nested in several layers of structs and unions
2862;          sspreq attribute
2863; Requires protector.
2864; Function Attrs: sspreq
2865define signext i8 @test23d() #2 {
2866entry:
2867; LINUX-I386-LABEL: test23d:
2868; LINUX-I386: mov{{l|q}} %gs:
2869; LINUX-I386: calll __stack_chk_fail
2870
2871; LINUX-X64-LABEL: test23d:
2872; LINUX-X64: mov{{l|q}} %fs:
2873; LINUX-X64: callq __stack_chk_fail
2874
2875; LINUX-KERNEL-X64-LABEL: test23d:
2876; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2877; LINUX-KERNEL-X64: callq __stack_chk_fail
2878
2879; DARWIN-X64-LABEL: test23d:
2880; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2881; DARWIN-X64: callq ___stack_chk_fail
2882  %x = alloca %struct.deep, align 1
2883  %b = getelementptr inbounds %struct.deep* %x, i32 0, i32 0
2884  %c = bitcast %union.anon* %b to %struct.anon*
2885  %d = getelementptr inbounds %struct.anon* %c, i32 0, i32 0
2886  %e = getelementptr inbounds %struct.anon.0* %d, i32 0, i32 0
2887  %array = bitcast %union.anon.1* %e to [2 x i8]*
2888  %arrayidx = getelementptr inbounds [2 x i8]* %array, i32 0, i64 0
2889  %0 = load i8* %arrayidx, align 1
2890  ret i8 %0
2891}
2892
2893; test24a: Variable sized alloca
2894;          no ssp attribute
2895; Requires no protector.
2896define void @test24a(i32 %n) {
2897entry:
2898; LINUX-I386-LABEL: test24a:
2899; LINUX-I386-NOT: calll __stack_chk_fail
2900; LINUX-I386: .cfi_endproc
2901
2902; LINUX-X64-LABEL: test24a:
2903; LINUX-X64-NOT: callq __stack_chk_fail
2904; LINUX-X64: .cfi_endproc
2905
2906; LINUX-KERNEL-X64-LABEL: test24a:
2907; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2908; LINUX-KERNEL-X64: .cfi_endproc
2909
2910; DARWIN-X64-LABEL: test24a:
2911; DARWIN-X64-NOT: callq ___stack_chk_fail
2912; DARWIN-X64: .cfi_endproc
2913  %n.addr = alloca i32, align 4
2914  %a = alloca i32*, align 8
2915  store i32 %n, i32* %n.addr, align 4
2916  %0 = load i32* %n.addr, align 4
2917  %conv = sext i32 %0 to i64
2918  %1 = alloca i8, i64 %conv
2919  %2 = bitcast i8* %1 to i32*
2920  store i32* %2, i32** %a, align 8
2921  ret void
2922}
2923
2924; test24b: Variable sized alloca
2925;          ssp attribute
2926; Requires protector.
2927; Function Attrs: ssp
2928define void @test24b(i32 %n) #0 {
2929entry:
2930; LINUX-I386-LABEL: test24b:
2931; LINUX-I386: mov{{l|q}} %gs:
2932; LINUX-I386: calll __stack_chk_fail
2933
2934; LINUX-X64-LABEL: test24b:
2935; LINUX-X64: mov{{l|q}} %fs:
2936; LINUX-X64: callq __stack_chk_fail
2937
2938; LINUX-KERNEL-X64-LABEL: test24b:
2939; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2940; LINUX-KERNEL-X64: callq __stack_chk_fail
2941
2942; DARWIN-X64-LABEL: test24b:
2943; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2944; DARWIN-X64: callq ___stack_chk_fail
2945  %n.addr = alloca i32, align 4
2946  %a = alloca i32*, align 8
2947  store i32 %n, i32* %n.addr, align 4
2948  %0 = load i32* %n.addr, align 4
2949  %conv = sext i32 %0 to i64
2950  %1 = alloca i8, i64 %conv
2951  %2 = bitcast i8* %1 to i32*
2952  store i32* %2, i32** %a, align 8
2953  ret void
2954}
2955
2956; test24c: Variable sized alloca
2957;          sspstrong attribute
2958; Requires protector.
2959; Function Attrs: sspstrong
2960define void @test24c(i32 %n) #1 {
2961entry:
2962; LINUX-I386-LABEL: test24c:
2963; LINUX-I386: mov{{l|q}} %gs:
2964; LINUX-I386: calll __stack_chk_fail
2965
2966; LINUX-X64-LABEL: test24c:
2967; LINUX-X64: mov{{l|q}} %fs:
2968; LINUX-X64: callq __stack_chk_fail
2969
2970; LINUX-KERNEL-X64-LABEL: test24c:
2971; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2972; LINUX-KERNEL-X64: callq __stack_chk_fail
2973
2974; DARWIN-X64-LABEL: test24c:
2975; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2976; DARWIN-X64: callq ___stack_chk_fail
2977  %n.addr = alloca i32, align 4
2978  %a = alloca i32*, align 8
2979  store i32 %n, i32* %n.addr, align 4
2980  %0 = load i32* %n.addr, align 4
2981  %conv = sext i32 %0 to i64
2982  %1 = alloca i8, i64 %conv
2983  %2 = bitcast i8* %1 to i32*
2984  store i32* %2, i32** %a, align 8
2985  ret void
2986}
2987
2988; test24d: Variable sized alloca
2989;          sspreq attribute
2990; Requires protector.
2991; Function Attrs: sspreq
2992define void @test24d(i32 %n) #2 {
2993entry:
2994; LINUX-I386-LABEL: test24d:
2995; LINUX-I386: mov{{l|q}} %gs:
2996; LINUX-I386: calll __stack_chk_fail
2997
2998; LINUX-X64-LABEL: test24d:
2999; LINUX-X64: mov{{l|q}} %fs:
3000; LINUX-X64: callq __stack_chk_fail
3001
3002; LINUX-KERNEL-X64-LABEL: test24d:
3003; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3004; LINUX-KERNEL-X64: callq __stack_chk_fail
3005
3006; DARWIN-X64-LABEL: test24d:
3007; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3008; DARWIN-X64: callq ___stack_chk_fail
3009  %n.addr = alloca i32, align 4
3010  %a = alloca i32*, align 8
3011  store i32 %n, i32* %n.addr, align 4
3012  %0 = load i32* %n.addr, align 4
3013  %conv = sext i32 %0 to i64
3014  %1 = alloca i8, i64 %conv
3015  %2 = bitcast i8* %1 to i32*
3016  store i32* %2, i32** %a, align 8
3017  ret void
3018}
3019
3020; test25a: array of [4 x i32]
3021;          no ssp attribute
3022; Requires no protector.
3023define i32 @test25a() {
3024entry:
3025; LINUX-I386-LABEL: test25a:
3026; LINUX-I386-NOT: calll __stack_chk_fail
3027; LINUX-I386: .cfi_endproc
3028
3029; LINUX-X64-LABEL: test25a:
3030; LINUX-X64-NOT: callq __stack_chk_fail
3031; LINUX-X64: .cfi_endproc
3032
3033; LINUX-KERNEL-X64-LABEL: test25a:
3034; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3035; LINUX-KERNEL-X64: .cfi_endproc
3036
3037; DARWIN-X64-LABEL: test25a:
3038; DARWIN-X64-NOT: callq ___stack_chk_fail
3039; DARWIN-X64: .cfi_endproc
3040  %a = alloca [4 x i32], align 16
3041  %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
3042  %0 = load i32* %arrayidx, align 4
3043  ret i32 %0
3044}
3045
3046; test25b: array of [4 x i32]
3047;          ssp attribute
3048; Requires no protector, except for Darwin which _does_ require a protector.
3049; Function Attrs: ssp
3050define i32 @test25b() #0 {
3051entry:
3052; LINUX-I386-LABEL: test25b:
3053; LINUX-I386-NOT: calll __stack_chk_fail
3054; LINUX-I386: .cfi_endproc
3055
3056; LINUX-X64-LABEL: test25b:
3057; LINUX-X64-NOT: callq __stack_chk_fail
3058; LINUX-X64: .cfi_endproc
3059
3060; LINUX-KERNEL-X64-LABEL: test25b:
3061; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3062; LINUX-KERNEL-X64: .cfi_endproc
3063
3064; DARWIN-X64-LABEL: test25b:
3065; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3066; DARWIN-X64: callq ___stack_chk_fail
3067  %a = alloca [4 x i32], align 16
3068  %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
3069  %0 = load i32* %arrayidx, align 4
3070  ret i32 %0
3071}
3072
3073; test25c: array of [4 x i32]
3074;          sspstrong attribute
3075; Requires protector.
3076; Function Attrs: sspstrong
3077define i32 @test25c() #1 {
3078entry:
3079; LINUX-I386-LABEL: test25c:
3080; LINUX-I386: mov{{l|q}} %gs:
3081; LINUX-I386: calll __stack_chk_fail
3082
3083; LINUX-X64-LABEL: test25c:
3084; LINUX-X64: mov{{l|q}} %fs:
3085; LINUX-X64: callq __stack_chk_fail
3086
3087; LINUX-KERNEL-X64-LABEL: test25c:
3088; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3089; LINUX-KERNEL-X64: callq __stack_chk_fail
3090
3091; DARWIN-X64-LABEL: test25c:
3092; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3093; DARWIN-X64: callq ___stack_chk_fail
3094  %a = alloca [4 x i32], align 16
3095  %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
3096  %0 = load i32* %arrayidx, align 4
3097  ret i32 %0
3098}
3099
3100; test25d: array of [4 x i32]
3101;          sspreq attribute
3102; Requires protector.
3103; Function Attrs: sspreq
3104define i32 @test25d() #2 {
3105entry:
3106; LINUX-I386-LABEL: test25d:
3107; LINUX-I386: mov{{l|q}} %gs:
3108; LINUX-I386: calll __stack_chk_fail
3109
3110; LINUX-X64-LABEL: test25d:
3111; LINUX-X64: mov{{l|q}} %fs:
3112; LINUX-X64: callq __stack_chk_fail
3113
3114; LINUX-KERNEL-X64-LABEL: test25d:
3115; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3116; LINUX-KERNEL-X64: callq __stack_chk_fail
3117
3118; DARWIN-X64-LABEL: test25d:
3119; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3120; DARWIN-X64: callq ___stack_chk_fail
3121  %a = alloca [4 x i32], align 16
3122  %arrayidx = getelementptr inbounds [4 x i32]* %a, i32 0, i64 0
3123  %0 = load i32* %arrayidx, align 4
3124  ret i32 %0
3125}
3126
3127; test26: Nested structure, no arrays, no address-of expressions.
3128;         Verify that the resulting gep-of-gep does not incorrectly trigger
3129;         a stack protector.
3130;         ssptrong attribute
3131; Requires no protector.
3132; Function Attrs: sspstrong
3133define void @test26() #1 {
3134entry:
3135; LINUX-I386-LABEL: test26:
3136; LINUX-I386-NOT: calll __stack_chk_fail
3137; LINUX-I386: .cfi_endproc
3138
3139; LINUX-X64-LABEL: test26:
3140; LINUX-X64-NOT: callq __stack_chk_fail
3141; LINUX-X64: .cfi_endproc
3142
3143; LINUX-KERNEL-X64-LABEL: test26:
3144; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3145; LINUX-KERNEL-X64: .cfi_endproc
3146
3147; DARWIN-X64-LABEL: test26:
3148; DARWIN-X64-NOT: callq ___stack_chk_fail
3149; DARWIN-X64: .cfi_endproc
3150  %c = alloca %struct.nest, align 4
3151  %b = getelementptr inbounds %struct.nest* %c, i32 0, i32 1
3152  %_a = getelementptr inbounds %struct.pair* %b, i32 0, i32 0
3153  %0 = load i32* %_a, align 4
3154  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %0)
3155  ret void
3156}
3157
3158; test27: Address-of a structure taken in a function with a loop where
3159;         the alloca is an incoming value to a PHI node and a use of that PHI
3160;         node is also an incoming value.
3161;         Verify that the address-of analysis does not get stuck in infinite
3162;         recursion when chasing the alloca through the PHI nodes.
3163; Requires protector.
3164; Function Attrs: sspstrong
3165define i32 @test27(i32 %arg) #1 {
3166bb:
3167; LINUX-I386-LABEL: test27:
3168; LINUX-I386: mov{{l|q}} %gs:
3169; LINUX-I386: calll __stack_chk_fail
3170
3171; LINUX-X64-LABEL: test27:
3172; LINUX-X64: mov{{l|q}} %fs:
3173; LINUX-X64: callq __stack_chk_fail
3174
3175; LINUX-KERNEL-X64-LABEL: test27:
3176; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3177; LINUX-KERNEL-X64: callq __stack_chk_fail
3178
3179; DARWIN-X64-LABEL: test27:
3180; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3181; DARWIN-X64: callq ___stack_chk_fail
3182  %tmp = alloca %struct.small*, align 8
3183  %tmp1 = call i32 (...)* @dummy(%struct.small** %tmp)
3184  %tmp2 = load %struct.small** %tmp, align 8
3185  %tmp3 = ptrtoint %struct.small* %tmp2 to i64
3186  %tmp4 = trunc i64 %tmp3 to i32
3187  %tmp5 = icmp sgt i32 %tmp4, 0
3188  br i1 %tmp5, label %bb6, label %bb21
3189
3190bb6:                                              ; preds = %bb17, %bb
3191  %tmp7 = phi %struct.small* [ %tmp19, %bb17 ], [ %tmp2, %bb ]
3192  %tmp8 = phi i64 [ %tmp20, %bb17 ], [ 1, %bb ]
3193  %tmp9 = phi i32 [ %tmp14, %bb17 ], [ %tmp1, %bb ]
3194  %tmp10 = getelementptr inbounds %struct.small* %tmp7, i64 0, i32 0
3195  %tmp11 = load i8* %tmp10, align 1
3196  %tmp12 = icmp eq i8 %tmp11, 1
3197  %tmp13 = add nsw i32 %tmp9, 8
3198  %tmp14 = select i1 %tmp12, i32 %tmp13, i32 %tmp9
3199  %tmp15 = trunc i64 %tmp8 to i32
3200  %tmp16 = icmp eq i32 %tmp15, %tmp4
3201  br i1 %tmp16, label %bb21, label %bb17
3202
3203bb17:                                             ; preds = %bb6
3204  %tmp18 = getelementptr inbounds %struct.small** %tmp, i64 %tmp8
3205  %tmp19 = load %struct.small** %tmp18, align 8
3206  %tmp20 = add i64 %tmp8, 1
3207  br label %bb6
3208
3209bb21:                                             ; preds = %bb6, %bb
3210  %tmp22 = phi i32 [ %tmp1, %bb ], [ %tmp14, %bb6 ]
3211  %tmp23 = call i32 (...)* @dummy(i32 %tmp22)
3212  ret i32 undef
3213}
3214
3215declare double @testi_aux()
3216declare i8* @strcpy(i8*, i8*)
3217declare i32 @printf(i8*, ...)
3218declare void @funcall(i32*)
3219declare void @funcall2(i32**)
3220declare void @funfloat(float*)
3221declare void @funfloat2(float**)
3222declare void @_Z3exceptPi(i32*)
3223declare i32 @__gxx_personality_v0(...)
3224declare i32* @getp()
3225declare i32 @dummy(...)
3226
3227attributes #0 = { ssp }
3228attributes #1 = { sspstrong }
3229attributes #2 = { sspreq }
3230