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; RUN: llc -mtriple=i386-pc-windows-msvc < %s -o - | FileCheck -check-prefix=MSVC-I386 %s
7; RUN: llc -mtriple=x86_64-w64-mingw32 < %s -o - | FileCheck --check-prefix=MINGW-X64 %s
8
9%struct.foo = type { [16 x i8] }
10%struct.foo.0 = type { [4 x i8] }
11%struct.pair = type { i32, i32 }
12%struct.nest = type { %struct.pair, %struct.pair }
13%struct.vec = type { <4 x i32> }
14%class.A = type { [2 x i8] }
15%struct.deep = type { %union.anon }
16%union.anon = type { %struct.anon }
17%struct.anon = type { %struct.anon.0 }
18%struct.anon.0 = type { %union.anon.1 }
19%union.anon.1 = type { [2 x i8] }
20%struct.small = type { i8 }
21%struct.small_char = type { i32, [5 x i8] }
22
23@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
24
25; test1a: array of [16 x i8]
26;         no ssp attribute
27; Requires no protector.
28define void @test1a(i8* %a) {
29entry:
30; LINUX-I386-LABEL: test1a:
31; LINUX-I386-NOT: calll __stack_chk_fail
32; LINUX-I386: .cfi_endproc
33
34; LINUX-X64-LABEL: test1a:
35; LINUX-X64-NOT: callq __stack_chk_fail
36; LINUX-X64: .cfi_endproc
37
38; LINUX-KERNEL-X64-LABEL: test1a:
39; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
40; LINUX-KERNEL-X64: .cfi_endproc
41
42; DARWIN-X64-LABEL: test1a:
43; DARWIN-X64-NOT: callq ___stack_chk_fail
44; DARWIN-X64: .cfi_endproc
45
46; MSVC-I386-LABEL: test1a:
47; MSVC-I386-NOT: calll  @__security_check_cookie@4
48; MSVC-I386: retl
49
50; MINGW-X64-LABEL: test1a:
51; MINGW-X64-NOT: callq __stack_chk_fail
52; MINGW-X64: .seh_endproc
53
54  %a.addr = alloca i8*, align 8
55  %buf = alloca [16 x i8], align 16
56  store i8* %a, i8** %a.addr, align 8
57  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
58  %0 = load i8*, i8** %a.addr, align 8
59  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
60  %arraydecay1 = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
61  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
62  ret void
63}
64
65; test1b: array of [16 x i8]
66;         ssp attribute
67; Requires protector.
68; Function Attrs: ssp
69define void @test1b(i8* %a) #0 {
70entry:
71; LINUX-I386-LABEL: test1b:
72; LINUX-I386: mov{{l|q}} %gs:
73; LINUX-I386: calll __stack_chk_fail
74
75; LINUX-X64-LABEL: test1b:
76; LINUX-X64: mov{{l|q}} %fs:
77; LINUX-X64: callq __stack_chk_fail
78
79; LINUX-KERNEL-X64-LABEL: test1b:
80; LINUX-KERNEL-X64: mov{{l|q}} %gs:
81; LINUX-KERNEL-X64: callq __stack_chk_fail
82
83; DARWIN-X64-LABEL: test1b:
84; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
85; DARWIN-X64: callq ___stack_chk_fail
86
87; OPENBSD-AMD64-LABEL: test1b:
88; OPENBSD-AMD64: movq __guard_local(%rip)
89; OPENBSD-AMD64: callq __stack_smash_handler
90
91; MSVC-I386-LABEL: test1b:
92; MSVC-I386: movl ___security_cookie,
93; MSVC-I386: calll @__security_check_cookie@4
94
95; MINGW-X64-LABEL: test1b:
96; MINGW-X64: mov{{l|q}} __stack_chk_guard
97; MINGW-X64: callq __stack_chk_fail
98
99  %a.addr = alloca i8*, align 8
100  %buf = alloca [16 x i8], align 16
101  store i8* %a, i8** %a.addr, align 8
102  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
103  %0 = load i8*, i8** %a.addr, align 8
104  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
105  %arraydecay1 = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
106  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
107  ret void
108}
109
110; test1c: array of [16 x i8]
111;         sspstrong attribute
112; Requires protector.
113; Function Attrs: sspstrong
114define void @test1c(i8* %a) #1 {
115entry:
116; LINUX-I386-LABEL: test1c:
117; LINUX-I386: mov{{l|q}} %gs:
118; LINUX-I386: calll __stack_chk_fail
119
120; LINUX-X64-LABEL: test1c:
121; LINUX-X64: mov{{l|q}} %fs:
122; LINUX-X64: callq __stack_chk_fail
123
124; LINUX-KERNEL-X64-LABEL: test1c:
125; LINUX-KERNEL-X64: mov{{l|q}} %gs:
126; LINUX-KERNEL-X64: callq __stack_chk_fail
127
128; DARWIN-X64-LABEL: test1c:
129; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
130; DARWIN-X64: callq ___stack_chk_fail
131
132; MSVC-I386-LABEL: test1c:
133; MSVC-I386: movl ___security_cookie,
134; MSVC-I386: calll @__security_check_cookie@4
135
136; MINGW-X64-LABEL: test1c:
137; MINGW-X64: mov{{l|q}} __stack_chk_guard
138; MINGW-X64: callq __stack_chk_fail
139
140  %a.addr = alloca i8*, align 8
141  %buf = alloca [16 x i8], align 16
142  store i8* %a, i8** %a.addr, align 8
143  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
144  %0 = load i8*, i8** %a.addr, align 8
145  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
146  %arraydecay1 = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
147  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
148  ret void
149}
150
151; test1d: array of [16 x i8]
152;         sspreq attribute
153; Requires protector.
154; Function Attrs: sspreq
155define void @test1d(i8* %a) #2 {
156entry:
157; LINUX-I386-LABEL: test1d:
158; LINUX-I386: mov{{l|q}} %gs:
159; LINUX-I386: calll __stack_chk_fail
160
161; LINUX-X64-LABEL: test1d:
162; LINUX-X64: mov{{l|q}} %fs:
163; LINUX-X64: callq __stack_chk_fail
164
165; LINUX-KERNEL-X64-LABEL: test1d:
166; LINUX-KERNEL-X64: mov{{l|q}} %gs:
167; LINUX-KERNEL-X64: callq __stack_chk_fail
168
169; DARWIN-X64-LABEL: test1d:
170; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
171; DARWIN-X64: callq ___stack_chk_fail
172
173; MSVC-I386-LABEL: test1d:
174; MSVC-I386: movl ___security_cookie,
175; MSVC-I386: calll @__security_check_cookie@4
176
177; MINGW-X64-LABEL: test1d:
178; MINGW-X64: mov{{l|q}} __stack_chk_guard
179; MINGW-X64: callq __stack_chk_fail
180
181  %a.addr = alloca i8*, align 8
182  %buf = alloca [16 x i8], align 16
183  store i8* %a, i8** %a.addr, align 8
184  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
185  %0 = load i8*, i8** %a.addr, align 8
186  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
187  %arraydecay1 = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
188  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
189  ret void
190}
191
192; test2a: struct { [16 x i8] }
193;         no ssp attribute
194; Requires no protector.
195define void @test2a(i8* %a) {
196entry:
197; LINUX-I386-LABEL: test2a:
198; LINUX-I386-NOT: calll __stack_chk_fail
199; LINUX-I386: .cfi_endproc
200
201; LINUX-X64-LABEL: test2a:
202; LINUX-X64-NOT: callq __stack_chk_fail
203; LINUX-X64: .cfi_endproc
204
205; LINUX-KERNEL-X64-LABEL: test2a:
206; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
207; LINUX-KERNEL-X64: .cfi_endproc
208
209; DARWIN-X64-LABEL: test2a:
210; DARWIN-X64-NOT: callq ___stack_chk_fail
211; DARWIN-X64: .cfi_endproc
212
213; MSVC-I386-LABEL: test2a:
214; MSVC-I386-NOT: calll @__security_check_cookie@4
215; MSVC-I386: retl
216
217; MINGW-X64-LABEL: test2a:
218; MINGW-X64-NOT: callq __stack_chk_fail
219; MINGW-X64: .seh_endproc
220
221  %a.addr = alloca i8*, align 8
222  %b = alloca %struct.foo, align 1
223  store i8* %a, i8** %a.addr, align 8
224  %buf = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
225  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
226  %0 = load i8*, i8** %a.addr, align 8
227  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
228  %buf1 = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
229  %arraydecay2 = getelementptr inbounds [16 x i8], [16 x i8]* %buf1, i32 0, i32 0
230  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
231  ret void
232}
233
234; test2b: struct { [16 x i8] }
235;          ssp attribute
236; Requires protector.
237; Function Attrs: ssp
238define void @test2b(i8* %a) #0 {
239entry:
240; LINUX-I386-LABEL: test2b:
241; LINUX-I386: mov{{l|q}} %gs:
242; LINUX-I386: calll __stack_chk_fail
243
244; LINUX-X64-LABEL: test2b:
245; LINUX-X64: mov{{l|q}} %fs:
246; LINUX-X64: callq __stack_chk_fail
247
248; LINUX-KERNEL-X64-LABEL: test2b:
249; LINUX-KERNEL-X64: mov{{l|q}} %gs:
250; LINUX-KERNEL-X64: callq __stack_chk_fail
251
252; DARWIN-X64-LABEL: test2b:
253; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
254; DARWIN-X64: callq ___stack_chk_fail
255
256; MINGW-X64-LABEL: test2b:
257; MINGW-X64: mov{{l|q}} __stack_chk_guard
258; MINGW-X64: callq __stack_chk_fail
259
260  %a.addr = alloca i8*, align 8
261  %b = alloca %struct.foo, align 1
262  store i8* %a, i8** %a.addr, align 8
263  %buf = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
264  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
265  %0 = load i8*, i8** %a.addr, align 8
266  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
267  %buf1 = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
268  %arraydecay2 = getelementptr inbounds [16 x i8], [16 x i8]* %buf1, i32 0, i32 0
269  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
270  ret void
271}
272
273; test2c: struct { [16 x i8] }
274;          sspstrong attribute
275; Requires protector.
276; Function Attrs: sspstrong
277define void @test2c(i8* %a) #1 {
278entry:
279; LINUX-I386-LABEL: test2c:
280; LINUX-I386: mov{{l|q}} %gs:
281; LINUX-I386: calll __stack_chk_fail
282
283; LINUX-X64-LABEL: test2c:
284; LINUX-X64: mov{{l|q}} %fs:
285; LINUX-X64: callq __stack_chk_fail
286
287; LINUX-KERNEL-X64-LABEL: test2c:
288; LINUX-KERNEL-X64: mov{{l|q}} %gs:
289; LINUX-KERNEL-X64: callq __stack_chk_fail
290
291; DARWIN-X64-LABEL: test2c:
292; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
293; DARWIN-X64: callq ___stack_chk_fail
294
295; MSVC-I386-LABEL: test2c:
296; MSVC-I386: movl ___security_cookie,
297; MSVC-I386: calll @__security_check_cookie@4
298
299; MINGW-X64-LABEL: test2c:
300; MINGW-X64: mov{{l|q}} __stack_chk_guard
301; MINGW-X64: callq __stack_chk_fail
302
303  %a.addr = alloca i8*, align 8
304  %b = alloca %struct.foo, align 1
305  store i8* %a, i8** %a.addr, align 8
306  %buf = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
307  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
308  %0 = load i8*, i8** %a.addr, align 8
309  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
310  %buf1 = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
311  %arraydecay2 = getelementptr inbounds [16 x i8], [16 x i8]* %buf1, i32 0, i32 0
312  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
313  ret void
314}
315
316; test2d: struct { [16 x i8] }
317;          sspreq attribute
318; Requires protector.
319; Function Attrs: sspreq
320define void @test2d(i8* %a) #2 {
321entry:
322; LINUX-I386-LABEL: test2d:
323; LINUX-I386: mov{{l|q}} %gs:
324; LINUX-I386: calll __stack_chk_fail
325
326; LINUX-X64-LABEL: test2d:
327; LINUX-X64: mov{{l|q}} %fs:
328; LINUX-X64: callq __stack_chk_fail
329
330; LINUX-KERNEL-X64-LABEL: test2d:
331; LINUX-KERNEL-X64: mov{{l|q}} %gs:
332; LINUX-KERNEL-X64: callq __stack_chk_fail
333
334; DARWIN-X64-LABEL: test2d:
335; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
336; DARWIN-X64: callq ___stack_chk_fail
337
338; MSVC-I386-LABEL: test2d:
339; MSVC-I386: movl ___security_cookie,
340; MSVC-I386: calll @__security_check_cookie@4
341
342; MINGW-X64-LABEL: test2d:
343; MINGW-X64: mov{{l|q}} __stack_chk_guard
344; MINGW-X64: callq __stack_chk_fail
345
346  %a.addr = alloca i8*, align 8
347  %b = alloca %struct.foo, align 1
348  store i8* %a, i8** %a.addr, align 8
349  %buf = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
350  %arraydecay = getelementptr inbounds [16 x i8], [16 x i8]* %buf, i32 0, i32 0
351  %0 = load i8*, i8** %a.addr, align 8
352  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
353  %buf1 = getelementptr inbounds %struct.foo, %struct.foo* %b, i32 0, i32 0
354  %arraydecay2 = getelementptr inbounds [16 x i8], [16 x i8]* %buf1, i32 0, i32 0
355  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
356  ret void
357}
358
359; test3a:  array of [4 x i8]
360;          no ssp attribute
361; Requires no protector.
362define void @test3a(i8* %a) {
363entry:
364; LINUX-I386-LABEL: test3a:
365; LINUX-I386-NOT: calll __stack_chk_fail
366; LINUX-I386: .cfi_endproc
367
368; LINUX-X64-LABEL: test3a:
369; LINUX-X64-NOT: callq __stack_chk_fail
370; LINUX-X64: .cfi_endproc
371
372; LINUX-KERNEL-X64-LABEL: test3a:
373; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
374; LINUX-KERNEL-X64: .cfi_endproc
375
376; DARWIN-X64-LABEL: test3a:
377; DARWIN-X64-NOT: callq ___stack_chk_fail
378; DARWIN-X64: .cfi_endproc
379
380; MSVC-I386-LABEL: test3a:
381; MSVC-I386-NOT: calll @__security_check_cookie@4
382; MSVC-I386: retl
383
384; MINGW-X64-LABEL: test3a:
385; MINGW-X64-NOT: callq __stack_chk_fail
386; MINGW-X64: .seh_endproc
387
388  %a.addr = alloca i8*, align 8
389  %buf = alloca [4 x i8], align 1
390  store i8* %a, i8** %a.addr, align 8
391  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
392  %0 = load i8*, i8** %a.addr, align 8
393  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
394  %arraydecay1 = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
395  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
396  ret void
397}
398
399; test3b:  array [4 x i8]
400;          ssp attribute
401; Requires no protector.
402; Function Attrs: ssp
403define void @test3b(i8* %a) #0 {
404entry:
405; LINUX-I386-LABEL: test3b:
406; LINUX-I386-NOT: calll __stack_chk_fail
407; LINUX-I386: .cfi_endproc
408
409; LINUX-X64-LABEL: test3b:
410; LINUX-X64-NOT: callq __stack_chk_fail
411; LINUX-X64: .cfi_endproc
412
413; LINUX-KERNEL-X64-LABEL: test3b:
414; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
415; LINUX-KERNEL-X64: .cfi_endproc
416
417; DARWIN-X64-LABEL: test3b:
418; DARWIN-X64-NOT: callq ___stack_chk_fail
419; DARWIN-X64: .cfi_endproc
420
421; MSVC-I386-LABEL: test3b:
422; MSVC-I386-NOT: calll @__security_check_cookie@4
423; MSVC-I386: retl
424
425; MINGW-X64-LABEL: test3b:
426; MINGW-X64-NOT: callq __stack_chk_fail
427; MINGW-X64: .seh_endproc
428
429  %a.addr = alloca i8*, align 8
430  %buf = alloca [4 x i8], align 1
431  store i8* %a, i8** %a.addr, align 8
432  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
433  %0 = load i8*, i8** %a.addr, align 8
434  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
435  %arraydecay1 = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
436  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
437  ret void
438}
439
440; test3c:  array of [4 x i8]
441;          sspstrong attribute
442; Requires protector.
443; Function Attrs: sspstrong
444define void @test3c(i8* %a) #1 {
445entry:
446; LINUX-I386-LABEL: test3c:
447; LINUX-I386: mov{{l|q}} %gs:
448; LINUX-I386: calll __stack_chk_fail
449
450; LINUX-X64-LABEL: test3c:
451; LINUX-X64: mov{{l|q}} %fs:
452; LINUX-X64: callq __stack_chk_fail
453
454; LINUX-KERNEL-X64-LABEL: test3c:
455; LINUX-KERNEL-X64: mov{{l|q}} %gs:
456; LINUX-KERNEL-X64: callq __stack_chk_fail
457
458; DARWIN-X64-LABEL: test3c:
459; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
460; DARWIN-X64: callq ___stack_chk_fail
461
462; MSVC-I386-LABEL: test3c:
463; MSVC-I386: movl ___security_cookie,
464; MSVC-I386: calll @__security_check_cookie@4
465
466; MINGW-X64-LABEL: test3c:
467; MINGW-X64: mov{{l|q}} __stack_chk_guard
468; MINGW-X64: callq __stack_chk_fail
469
470  %a.addr = alloca i8*, align 8
471  %buf = alloca [4 x i8], align 1
472  store i8* %a, i8** %a.addr, align 8
473  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
474  %0 = load i8*, i8** %a.addr, align 8
475  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
476  %arraydecay1 = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
477  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
478  ret void
479}
480
481; test3d:  array of [4 x i8]
482;          sspreq attribute
483; Requires protector.
484; Function Attrs: sspreq
485define void @test3d(i8* %a) #2 {
486entry:
487; LINUX-I386-LABEL: test3d:
488; LINUX-I386: mov{{l|q}} %gs:
489; LINUX-I386: calll __stack_chk_fail
490
491; LINUX-X64-LABEL: test3d:
492; LINUX-X64: mov{{l|q}} %fs:
493; LINUX-X64: callq __stack_chk_fail
494
495; LINUX-KERNEL-X64-LABEL: test3d:
496; LINUX-KERNEL-X64: mov{{l|q}} %gs:
497; LINUX-KERNEL-X64: callq __stack_chk_fail
498
499; DARWIN-X64-LABEL: test3d:
500; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
501; DARWIN-X64: callq ___stack_chk_fail
502
503; MSVC-I386-LABEL: test3d:
504; MSVC-I386: movl ___security_cookie,
505; MSVC-I386: calll @__security_check_cookie@4
506
507; MINGW-X64-LABEL: test3d:
508; MINGW-X64: mov{{l|q}} __stack_chk_guard
509; MINGW-X64: callq __stack_chk_fail
510
511  %a.addr = alloca i8*, align 8
512  %buf = alloca [4 x i8], align 1
513  store i8* %a, i8** %a.addr, align 8
514  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
515  %0 = load i8*, i8** %a.addr, align 8
516  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
517  %arraydecay1 = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
518  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay1)
519  ret void
520}
521
522; test4a:  struct { [4 x i8] }
523;          no ssp attribute
524; Requires no protector.
525define void @test4a(i8* %a) {
526entry:
527; LINUX-I386-LABEL: test4a:
528; LINUX-I386-NOT: calll __stack_chk_fail
529; LINUX-I386: .cfi_endproc
530
531; LINUX-X64-LABEL: test4a:
532; LINUX-X64-NOT: callq __stack_chk_fail
533; LINUX-X64: .cfi_endproc
534
535; LINUX-KERNEL-X64-LABEL: test4a:
536; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
537; LINUX-KERNEL-X64: .cfi_endproc
538
539; DARWIN-X64-LABEL: test4a:
540; DARWIN-X64-NOT: callq ___stack_chk_fail
541; DARWIN-X64: .cfi_endproc
542
543; MSVC-I386-LABEL: test4a:
544; MSVC-I386-NOT: calll @__security_check_cookie@4
545; MSVC-I386: retl
546
547; MINGW-X64-LABEL: test4a:
548; MINGW-X64-NOT: callq __stack_chk_fail
549; MINGW-X64: .seh_endproc
550
551  %a.addr = alloca i8*, align 8
552  %b = alloca %struct.foo.0, align 1
553  store i8* %a, i8** %a.addr, align 8
554  %buf = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
555  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
556  %0 = load i8*, i8** %a.addr, align 8
557  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
558  %buf1 = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
559  %arraydecay2 = getelementptr inbounds [4 x i8], [4 x i8]* %buf1, i32 0, i32 0
560  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
561  ret void
562}
563
564; test4b:  struct { [4 x i8] }
565;          ssp attribute
566; Requires no protector.
567; Function Attrs: ssp
568define void @test4b(i8* %a) #0 {
569entry:
570; LINUX-I386-LABEL: test4b:
571; LINUX-I386-NOT: calll __stack_chk_fail
572; LINUX-I386: .cfi_endproc
573
574; LINUX-X64-LABEL: test4b:
575; LINUX-X64-NOT: callq __stack_chk_fail
576; LINUX-X64: .cfi_endproc
577
578; LINUX-KERNEL-X64-LABEL: test4b:
579; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
580; LINUX-KERNEL-X64: .cfi_endproc
581
582; DARWIN-X64-LABEL: test4b:
583; DARWIN-X64-NOT: callq ___stack_chk_fail
584; DARWIN-X64: .cfi_endproc
585
586; MSVC-I386-LABEL: test4b:
587; MSVC-I386-NOT: calll @__security_check_cookie@4
588; MSVC-I386: retl
589
590; MINGW-X64-LABEL: test4b:
591; MINGW-X64-NOT: callq __stack_chk_fail
592; MINGW-X64: .seh_endproc
593
594  %a.addr = alloca i8*, align 8
595  %b = alloca %struct.foo.0, align 1
596  store i8* %a, i8** %a.addr, align 8
597  %buf = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
598  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
599  %0 = load i8*, i8** %a.addr, align 8
600  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
601  %buf1 = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
602  %arraydecay2 = getelementptr inbounds [4 x i8], [4 x i8]* %buf1, i32 0, i32 0
603  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
604  ret void
605}
606
607; test4c:  struct { [4 x i8] }
608;          sspstrong attribute
609; Requires protector.
610; Function Attrs: sspstrong
611define void @test4c(i8* %a) #1 {
612entry:
613; LINUX-I386-LABEL: test4c:
614; LINUX-I386: mov{{l|q}} %gs:
615; LINUX-I386: calll __stack_chk_fail
616
617; LINUX-X64-LABEL: test4c:
618; LINUX-X64: mov{{l|q}} %fs:
619; LINUX-X64: callq __stack_chk_fail
620
621; LINUX-KERNEL-X64-LABEL: test4c:
622; LINUX-KERNEL-X64: mov{{l|q}} %gs:
623; LINUX-KERNEL-X64: callq __stack_chk_fail
624
625; DARWIN-X64-LABEL: test4c:
626; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
627; DARWIN-X64: callq ___stack_chk_fail
628
629; MSVC-I386-LABEL: test4c:
630; MSVC-I386: movl ___security_cookie,
631; MSVC-I386: calll @__security_check_cookie@4
632
633; MINGW-X64-LABEL: test4c:
634; MINGW-X64: mov{{l|q}} __stack_chk_guard
635; MINGW-X64: callq __stack_chk_fail
636
637  %a.addr = alloca i8*, align 8
638  %b = alloca %struct.foo.0, align 1
639  store i8* %a, i8** %a.addr, align 8
640  %buf = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
641  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
642  %0 = load i8*, i8** %a.addr, align 8
643  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
644  %buf1 = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
645  %arraydecay2 = getelementptr inbounds [4 x i8], [4 x i8]* %buf1, i32 0, i32 0
646  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
647  ret void
648}
649
650; test4d:  struct { [4 x i8] }
651;          sspreq attribute
652; Requires protector.
653; Function Attrs: sspreq
654define void @test4d(i8* %a) #2 {
655entry:
656; LINUX-I386-LABEL: test4d:
657; LINUX-I386: mov{{l|q}} %gs:
658; LINUX-I386: calll __stack_chk_fail
659
660; LINUX-X64-LABEL: test4d:
661; LINUX-X64: mov{{l|q}} %fs:
662; LINUX-X64: callq __stack_chk_fail
663
664; LINUX-KERNEL-X64-LABEL: test4d:
665; LINUX-KERNEL-X64: mov{{l|q}} %gs:
666; LINUX-KERNEL-X64: callq __stack_chk_fail
667
668; DARWIN-X64-LABEL: test4d:
669; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
670; DARWIN-X64: callq ___stack_chk_fail
671
672; MSVC-I386-LABEL: test4d:
673; MSVC-I386: movl ___security_cookie,
674; MSVC-I386: calll @__security_check_cookie@4
675
676; MINGW-X64-LABEL: test4d:
677; MINGW-X64: mov{{l|q}} __stack_chk_guard
678; MINGW-X64: callq __stack_chk_fail
679
680  %a.addr = alloca i8*, align 8
681  %b = alloca %struct.foo.0, align 1
682  store i8* %a, i8** %a.addr, align 8
683  %buf = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
684  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i32 0, i32 0
685  %0 = load i8*, i8** %a.addr, align 8
686  %call = call i8* @strcpy(i8* %arraydecay, i8* %0)
687  %buf1 = getelementptr inbounds %struct.foo.0, %struct.foo.0* %b, i32 0, i32 0
688  %arraydecay2 = getelementptr inbounds [4 x i8], [4 x i8]* %buf1, i32 0, i32 0
689  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay2)
690  ret void
691}
692
693; test5a:  no arrays / no nested arrays
694;          no ssp attribute
695; Requires no protector.
696define void @test5a(i8* %a) {
697entry:
698; LINUX-I386-LABEL: test5a:
699; LINUX-I386-NOT: calll __stack_chk_fail
700; LINUX-I386: .cfi_endproc
701
702; LINUX-X64-LABEL: test5a:
703; LINUX-X64-NOT: callq __stack_chk_fail
704; LINUX-X64: .cfi_endproc
705
706; LINUX-KERNEL-X64-LABEL: test5a:
707; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
708; LINUX-KERNEL-X64: .cfi_endproc
709
710; DARWIN-X64-LABEL: test5a:
711; DARWIN-X64-NOT: callq ___stack_chk_fail
712; DARWIN-X64: .cfi_endproc
713
714; MSVC-I386-LABEL: test5a:
715; MSVC-I386-NOT: calll @__security_check_cookie@4
716; MSVC-I386: retl
717
718; MINGW-X64-LABEL: test5a:
719; MINGW-X64-NOT: callq __stack_chk_fail
720; MINGW-X64: .seh_endproc
721
722  %a.addr = alloca i8*, align 8
723  store i8* %a, i8** %a.addr, align 8
724  %0 = load i8*, i8** %a.addr, align 8
725  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %0)
726  ret void
727}
728
729; test5b:  no arrays / no nested arrays
730;          ssp attribute
731; Requires no protector.
732; Function Attrs: ssp
733define void @test5b(i8* %a) #0 {
734entry:
735; LINUX-I386-LABEL: test5b:
736; LINUX-I386-NOT: calll __stack_chk_fail
737; LINUX-I386: .cfi_endproc
738
739; LINUX-X64-LABEL: test5b:
740; LINUX-X64-NOT: callq __stack_chk_fail
741; LINUX-X64: .cfi_endproc
742
743; LINUX-KERNEL-X64-LABEL: test5b:
744; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
745; LINUX-KERNEL-X64: .cfi_endproc
746
747; DARWIN-X64-LABEL: test5b:
748; DARWIN-X64-NOT: callq ___stack_chk_fail
749; DARWIN-X64: .cfi_endproc
750
751; MSVC-I386-LABEL: test5b:
752; MSVC-I386-NOT: calll @__security_check_cookie@4
753; MSVC-I386: retl
754
755; MINGW-X64-LABEL: test5b:
756; MINGW-X64-NOT: callq __stack_chk_fail
757; MINGW-X64: .seh_endproc
758
759  %a.addr = alloca i8*, align 8
760  store i8* %a, i8** %a.addr, align 8
761  %0 = load i8*, i8** %a.addr, align 8
762  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %0)
763  ret void
764}
765
766; test5c:  no arrays / no nested arrays
767;          sspstrong attribute
768; Requires no protector.
769; Function Attrs: sspstrong
770define void @test5c(i8* %a) #1 {
771entry:
772; LINUX-I386-LABEL: test5c:
773; LINUX-I386-NOT: calll __stack_chk_fail
774; LINUX-I386: .cfi_endproc
775
776; LINUX-X64-LABEL: test5c:
777; LINUX-X64-NOT: callq __stack_chk_fail
778; LINUX-X64: .cfi_endproc
779
780; LINUX-KERNEL-X64-LABEL: test5c:
781; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
782; LINUX-KERNEL-X64: .cfi_endproc
783
784; DARWIN-X64-LABEL: test5c:
785; DARWIN-X64-NOT: callq ___stack_chk_fail
786; DARWIN-X64: .cfi_endproc
787
788; MSVC-I386-LABEL: test5c:
789; MSVC-I386-NOT: calll @__security_check_cookie@4
790; MSVC-I386: retl
791
792; MINGW-X64-LABEL: test5c:
793; MINGW-X64-NOT: callq __stack_chk_fail
794; MINGW-X64: .seh_endproc
795
796  %a.addr = alloca i8*, align 8
797  store i8* %a, i8** %a.addr, align 8
798  %0 = load i8*, i8** %a.addr, align 8
799  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %0)
800  ret void
801}
802
803; test5d:  no arrays / no nested arrays
804;          sspreq attribute
805; Requires protector.
806; Function Attrs: sspreq
807define void @test5d(i8* %a) #2 {
808entry:
809; LINUX-I386-LABEL: test5d:
810; LINUX-I386: mov{{l|q}} %gs:
811; LINUX-I386: calll __stack_chk_fail
812
813; LINUX-X64-LABEL: test5d:
814; LINUX-X64: mov{{l|q}} %fs:
815; LINUX-X64: callq __stack_chk_fail
816
817; LINUX-KERNEL-X64-LABEL: test5d:
818; LINUX-KERNEL-X64: mov{{l|q}} %gs:
819; LINUX-KERNEL-X64: callq __stack_chk_fail
820
821; DARWIN-X64-LABEL: test5d:
822; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
823; DARWIN-X64: callq ___stack_chk_fail
824
825; MSVC-I386-LABEL: test5d:
826; MSVC-I386: movl ___security_cookie,
827; MSVC-I386: calll @__security_check_cookie@4
828
829; MINGW-X64-LABEL: test5d:
830; MINGW-X64: mov{{l|q}} __stack_chk_guard
831; MINGW-X64: callq __stack_chk_fail
832
833  %a.addr = alloca i8*, align 8
834  store i8* %a, i8** %a.addr, align 8
835  %0 = load i8*, i8** %a.addr, align 8
836  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %0)
837  ret void
838}
839
840; test6a:  Address-of local taken (j = &a)
841;          no ssp attribute
842; Requires no protector.
843define void @test6a() {
844entry:
845; LINUX-I386-LABEL: test6a:
846; LINUX-I386-NOT: calll __stack_chk_fail
847; LINUX-I386: .cfi_endproc
848
849; LINUX-X64-LABEL: test6a:
850; LINUX-X64-NOT: callq __stack_chk_fail
851; LINUX-X64: .cfi_endproc
852
853; LINUX-KERNEL-X64-LABEL: test6a:
854; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
855; LINUX-KERNEL-X64: .cfi_endproc
856
857; DARWIN-X64-LABEL: test6a:
858; DARWIN-X64-NOT: callq ___stack_chk_fail
859; DARWIN-X64: .cfi_endproc
860
861; MSVC-I386-LABEL: test6a:
862; MSVC-I386-NOT: calll @__security_check_cookie@4
863; MSVC-I386: retl
864
865; MINGW-X64-LABEL: test6a:
866; MINGW-X64-NOT: callq __stack_chk_fail
867; MINGW-X64: .seh_endproc
868
869  %retval = alloca i32, align 4
870  %a = alloca i32, align 4
871  %j = alloca i32*, align 8
872  store i32 0, i32* %retval
873  %0 = load i32, i32* %a, align 4
874  %add = add nsw i32 %0, 1
875  store i32 %add, i32* %a, align 4
876  store i32* %a, i32** %j, align 8
877  ret void
878}
879
880; test6b:  Address-of local taken (j = &a)
881;          ssp attribute
882; Requires no protector.
883; Function Attrs: ssp
884define void @test6b() #0 {
885entry:
886; LINUX-I386-LABEL: test6b:
887; LINUX-I386-NOT: calll __stack_chk_fail
888; LINUX-I386: .cfi_endproc
889
890; LINUX-X64-LABEL: test6b:
891; LINUX-X64-NOT: callq __stack_chk_fail
892; LINUX-X64: .cfi_endproc
893
894; LINUX-KERNEL-X64-LABEL: test6b:
895; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
896; LINUX-KERNEL-X64: .cfi_endproc
897
898; DARWIN-X64-LABEL: test6b:
899; DARWIN-X64-NOT: callq ___stack_chk_fail
900; DARWIN-X64: .cfi_endproc
901
902; MSVC-I386-LABEL: test6b:
903; MSVC-I386-NOT: calll @__security_check_cookie@4
904; MSVC-I386: retl
905
906; MINGW-X64-LABEL: test6b:
907; MINGW-X64-NOT: callq __stack_chk_fail
908; MINGW-X64: .seh_endproc
909
910  %retval = alloca i32, align 4
911  %a = alloca i32, align 4
912  %j = alloca i32*, align 8
913  store i32 0, i32* %retval
914  %0 = load i32, i32* %a, align 4
915  %add = add nsw i32 %0, 1
916  store i32 %add, i32* %a, align 4
917  store i32* %a, i32** %j, align 8
918  ret void
919}
920
921; test6c:  Address-of local taken (j = &a)
922;          sspstrong attribute
923; Requires protector.
924; Function Attrs: sspstrong
925define void @test6c() #1 {
926entry:
927; LINUX-I386-LABEL: test6c:
928; LINUX-I386: mov{{l|q}} %gs:
929; LINUX-I386: calll __stack_chk_fail
930
931; LINUX-X64-LABEL: test6c:
932; LINUX-X64: mov{{l|q}} %fs:
933; LINUX-X64: callq __stack_chk_fail
934
935; LINUX-KERNEL-X64-LABEL: test6c:
936; LINUX-KERNEL-X64: mov{{l|q}} %gs:
937; LINUX-KERNEL-X64: callq __stack_chk_fail
938
939; DARWIN-X64-LABEL: test6c:
940; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
941; DARWIN-X64: callq ___stack_chk_fail
942
943; MSVC-I386-LABEL: test6c:
944; MSVC-I386: movl ___security_cookie,
945; MSVC-I386: calll @__security_check_cookie@4
946
947; MINGW-X64-LABEL: test6c:
948; MINGW-X64: mov{{l|q}} __stack_chk_guard
949; MINGW-X64: callq __stack_chk_fail
950
951  %retval = alloca i32, align 4
952  %a = alloca i32, align 4
953  %j = alloca i32*, align 8
954  store i32 0, i32* %retval
955  %0 = load i32, i32* %a, align 4
956  %add = add nsw i32 %0, 1
957  store i32 %add, i32* %a, align 4
958  store i32* %a, i32** %j, align 8
959  ret void
960}
961
962; test6d:  Address-of local taken (j = &a)
963;          sspreq attribute
964; Requires protector.
965; Function Attrs: sspreq
966define void @test6d() #2 {
967entry:
968; LINUX-I386-LABEL: test6d:
969; LINUX-I386: mov{{l|q}} %gs:
970; LINUX-I386: calll __stack_chk_fail
971
972; LINUX-X64-LABEL: test6d:
973; LINUX-X64: mov{{l|q}} %fs:
974; LINUX-X64: callq __stack_chk_fail
975
976; LINUX-KERNEL-X64-LABEL: test6d:
977; LINUX-KERNEL-X64: mov{{l|q}} %gs:
978; LINUX-KERNEL-X64: callq __stack_chk_fail
979
980; DARWIN-X64-LABEL: test6d:
981; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
982; DARWIN-X64: callq ___stack_chk_fail
983
984; MSVC-I386-LABEL: test6d:
985; MSVC-I386: movl ___security_cookie,
986; MSVC-I386: calll @__security_check_cookie@4
987
988; MINGW-X64-LABEL: test6d:
989; MINGW-X64: mov{{l|q}} __stack_chk_guard
990; MINGW-X64: callq __stack_chk_fail
991
992  %retval = alloca i32, align 4
993  %a = alloca i32, align 4
994  %j = alloca i32*, align 8
995  store i32 0, i32* %retval
996  %0 = load i32, i32* %a, align 4
997  %add = add nsw i32 %0, 1
998  store i32 %add, i32* %a, align 4
999  store i32* %a, i32** %j, align 8
1000  ret void
1001}
1002
1003; test7a:  PtrToInt Cast
1004;          no ssp attribute
1005; Requires no protector.
1006define void @test7a()  {
1007entry:
1008; LINUX-I386-LABEL: test7a:
1009; LINUX-I386-NOT: calll __stack_chk_fail
1010; LINUX-I386: .cfi_endproc
1011
1012; LINUX-X64-LABEL: test7a:
1013; LINUX-X64-NOT: callq __stack_chk_fail
1014; LINUX-X64: .cfi_endproc
1015
1016; LINUX-KERNEL-X64-LABEL: test7a:
1017; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1018; LINUX-KERNEL-X64: .cfi_endproc
1019
1020; DARWIN-X64-LABEL: test7a:
1021; DARWIN-X64-NOT: callq ___stack_chk_fail
1022; DARWIN-X64: .cfi_endproc
1023
1024; MSVC-I386-LABEL: test7a:
1025; MSVC-I386-NOT: calll @__security_check_cookie@4
1026; MSVC-I386: retl
1027
1028; MINGW-X64-LABEL: test7a:
1029; MINGW-X64-NOT: callq __stack_chk_fail
1030; MINGW-X64: .seh_endproc
1031
1032  %a = alloca i32, align 4
1033  %0 = ptrtoint i32* %a to i64
1034  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1035  ret void
1036}
1037
1038; test7b:  PtrToInt Cast
1039;          ssp attribute
1040; Requires no protector.
1041; Function Attrs: ssp
1042define void @test7b() #0 {
1043entry:
1044; LINUX-I386-LABEL: test7b:
1045; LINUX-I386-NOT: calll __stack_chk_fail
1046; LINUX-I386: .cfi_endproc
1047
1048; LINUX-X64-LABEL: test7b:
1049; LINUX-X64-NOT: callq __stack_chk_fail
1050; LINUX-X64: .cfi_endproc
1051
1052; LINUX-KERNEL-X64-LABEL: test7b:
1053; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1054; LINUX-KERNEL-X64: .cfi_endproc
1055
1056; DARWIN-X64-LABEL: test7b:
1057; DARWIN-X64-NOT: callq ___stack_chk_fail
1058; DARWIN-X64: .cfi_endproc
1059
1060; MSVC-I386-LABEL: test7b:
1061; MSVC-I386-NOT: calll @__security_check_cookie@4
1062; MSVC-I386: retl
1063
1064; MINGW-X64-LABEL: test7b:
1065; MINGW-X64-NOT: callq __stack_chk_fail
1066; MINGW-X64: .seh_endproc
1067
1068  %a = alloca i32, align 4
1069  %0 = ptrtoint i32* %a to i64
1070  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1071  ret void
1072}
1073
1074; test7c:  PtrToInt Cast
1075;          sspstrong attribute
1076; Requires protector.
1077; Function Attrs: sspstrong
1078define void @test7c() #1 {
1079entry:
1080; LINUX-I386-LABEL: test7c:
1081; LINUX-I386: mov{{l|q}} %gs:
1082; LINUX-I386: calll __stack_chk_fail
1083
1084; LINUX-X64-LABEL: test7c:
1085; LINUX-X64: mov{{l|q}} %fs:
1086; LINUX-X64: callq __stack_chk_fail
1087
1088; LINUX-KERNEL-X64-LABEL: test7c:
1089; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1090; LINUX-KERNEL-X64: callq __stack_chk_fail
1091
1092; DARWIN-X64-LABEL: test7c:
1093; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1094; DARWIN-X64: callq ___stack_chk_fail
1095
1096; MSVC-I386-LABEL: test7c:
1097; MSVC-I386: movl ___security_cookie,
1098; MSVC-I386: calll @__security_check_cookie@4
1099
1100; MINGW-X64-LABEL: test7c:
1101; MINGW-X64: mov{{l|q}} __stack_chk_guard
1102; MINGW-X64: .seh_endproc
1103
1104  %a = alloca i32, align 4
1105  %0 = ptrtoint i32* %a to i64
1106  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1107  ret void
1108}
1109
1110; test7d:  PtrToInt Cast
1111;          sspreq attribute
1112; Requires protector.
1113; Function Attrs: sspreq
1114define void @test7d() #2 {
1115entry:
1116; LINUX-I386-LABEL: test7d:
1117; LINUX-I386: mov{{l|q}} %gs:
1118; LINUX-I386: calll __stack_chk_fail
1119
1120; LINUX-X64-LABEL: test7d:
1121; LINUX-X64: mov{{l|q}} %fs:
1122; LINUX-X64: callq __stack_chk_fail
1123
1124; LINUX-KERNEL-X64-LABEL: test7d:
1125; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1126; LINUX-KERNEL-X64: callq __stack_chk_fail
1127
1128; DARWIN-X64-LABEL: test7d:
1129; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1130; DARWIN-X64: callq ___stack_chk_fail
1131
1132; MSVC-I386-LABEL: test7d:
1133; MSVC-I386: movl ___security_cookie,
1134; MSVC-I386: calll @__security_check_cookie@4
1135
1136; MINGW-X64-LABEL: test7d:
1137; MINGW-X64: mov{{l|q}} __stack_chk_guard
1138; MINGW-X64: callq __stack_chk_fail
1139
1140  %a = alloca i32, align 4
1141  %0 = ptrtoint i32* %a to i64
1142  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1143  ret void
1144}
1145
1146; test8a:  Passing addr-of to function call
1147;          no ssp attribute
1148; Requires no protector.
1149define void @test8a() {
1150entry:
1151; LINUX-I386-LABEL: test8a:
1152; LINUX-I386-NOT: calll __stack_chk_fail
1153; LINUX-I386: .cfi_endproc
1154
1155; LINUX-X64-LABEL: test8a:
1156; LINUX-X64-NOT: callq __stack_chk_fail
1157; LINUX-X64: .cfi_endproc
1158
1159; LINUX-KERNEL-X64-LABEL: test8a:
1160; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1161; LINUX-KERNEL-X64: .cfi_endproc
1162
1163; DARWIN-X64-LABEL: test8a:
1164; DARWIN-X64-NOT: callq ___stack_chk_fail
1165; DARWIN-X64: .cfi_endproc
1166
1167; MSVC-I386-LABEL: test8a:
1168; MSVC-I386-NOT: calll @__security_check_cookie@4
1169; MSVC-I386: retl
1170
1171; MINGW-X64-LABEL: test8a:
1172; MINGW-X64-NOT: callq __stack_chk_fail
1173; MINGW-X64: .seh_endproc
1174
1175  %b = alloca i32, align 4
1176  call void @funcall(i32* %b)
1177  ret void
1178}
1179
1180; test8b:  Passing addr-of to function call
1181;          ssp attribute
1182; Requires no protector.
1183; Function Attrs: ssp
1184define void @test8b() #0 {
1185entry:
1186; LINUX-I386-LABEL: test8b:
1187; LINUX-I386-NOT: calll __stack_chk_fail
1188; LINUX-I386: .cfi_endproc
1189
1190; LINUX-X64-LABEL: test8b:
1191; LINUX-X64-NOT: callq __stack_chk_fail
1192; LINUX-X64: .cfi_endproc
1193
1194; LINUX-KERNEL-X64-LABEL: test8b:
1195; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1196; LINUX-KERNEL-X64: .cfi_endproc
1197
1198; DARWIN-X64-LABEL: test8b:
1199; DARWIN-X64-NOT: callq ___stack_chk_fail
1200; DARWIN-X64: .cfi_endproc
1201
1202; MSVC-I386-LABEL: test8b:
1203; MSVC-I386-NOT: calll @__security_check_cookie@4
1204; MSVC-I386: retl
1205
1206; MINGW-X64-LABEL: test8b:
1207; MINGW-X64-NOT: callq __stack_chk_fail
1208; MINGW-X64: .seh_endproc
1209
1210  %b = alloca i32, align 4
1211  call void @funcall(i32* %b)
1212  ret void
1213}
1214
1215; test8c:  Passing addr-of to function call
1216;          sspstrong attribute
1217; Requires protector.
1218; Function Attrs: sspstrong
1219define void @test8c() #1 {
1220entry:
1221; LINUX-I386-LABEL: test8c:
1222; LINUX-I386: mov{{l|q}} %gs:
1223; LINUX-I386: calll __stack_chk_fail
1224
1225; LINUX-X64-LABEL: test8c:
1226; LINUX-X64: mov{{l|q}} %fs:
1227; LINUX-X64: callq __stack_chk_fail
1228
1229; LINUX-KERNEL-X64-LABEL: test8c:
1230; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1231; LINUX-KERNEL-X64: callq __stack_chk_fail
1232
1233; DARWIN-X64-LABEL: test8c:
1234; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1235; DARWIN-X64: callq ___stack_chk_fail
1236
1237; MSVC-I386-LABEL: test8c:
1238; MSVC-I386: movl ___security_cookie,
1239; MSVC-I386: calll @__security_check_cookie@4
1240
1241; MINGW-X64-LABEL: test8c:
1242; MINGW-X64: mov{{l|q}} __stack_chk_guard
1243; MINGW-X64: callq __stack_chk_fail
1244
1245  %b = alloca i32, align 4
1246  call void @funcall(i32* %b)
1247  ret void
1248}
1249
1250; test8d:  Passing addr-of to function call
1251;          sspreq attribute
1252; Requires protector.
1253; Function Attrs: sspreq
1254define void @test8d() #2 {
1255entry:
1256; LINUX-I386-LABEL: test8d:
1257; LINUX-I386: mov{{l|q}} %gs:
1258; LINUX-I386: calll __stack_chk_fail
1259
1260; LINUX-X64-LABEL: test8d:
1261; LINUX-X64: mov{{l|q}} %fs:
1262; LINUX-X64: callq __stack_chk_fail
1263
1264; LINUX-KERNEL-X64-LABEL: test8d:
1265; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1266; LINUX-KERNEL-X64: callq __stack_chk_fail
1267
1268; DARWIN-X64-LABEL: test8d:
1269; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1270; DARWIN-X64: callq ___stack_chk_fail
1271
1272; MSVC-I386-LABEL: test8d:
1273; MSVC-I386: movl ___security_cookie,
1274; MSVC-I386: calll @__security_check_cookie@4
1275
1276; MINGW-X64-LABEL: test8d:
1277; MINGW-X64: mov{{l|q}} __stack_chk_guard
1278; MINGW-X64: callq __stack_chk_fail
1279
1280  %b = alloca i32, align 4
1281  call void @funcall(i32* %b)
1282  ret void
1283}
1284
1285; test9a:  Addr-of in select instruction
1286;          no ssp attribute
1287; Requires no protector.
1288define void @test9a() {
1289entry:
1290; LINUX-I386-LABEL: test9a:
1291; LINUX-I386-NOT: calll __stack_chk_fail
1292; LINUX-I386: .cfi_endproc
1293
1294; LINUX-X64-LABEL: test9a:
1295; LINUX-X64-NOT: callq __stack_chk_fail
1296; LINUX-X64: .cfi_endproc
1297
1298; LINUX-KERNEL-X64-LABEL: test9a:
1299; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1300; LINUX-KERNEL-X64: .cfi_endproc
1301
1302; DARWIN-X64-LABEL: test9a:
1303; DARWIN-X64-NOT: callq ___stack_chk_fail
1304; DARWIN-X64: .cfi_endproc
1305
1306; MSVC-I386-LABEL: test9a:
1307; MSVC-I386-NOT: calll @__security_check_cookie@4
1308; MSVC-I386: retl
1309  %x = alloca double, align 8
1310  %call = call double @testi_aux()
1311  store double %call, double* %x, align 8
1312  %cmp2 = fcmp ogt double %call, 0.000000e+00
1313  %y.1 = select i1 %cmp2, double* %x, double* null
1314  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1315  ret void
1316}
1317
1318; test9b:  Addr-of in select instruction
1319;          ssp attribute
1320; Requires no protector.
1321; Function Attrs: ssp
1322define void @test9b() #0 {
1323entry:
1324; LINUX-I386-LABEL: test9b:
1325; LINUX-I386-NOT: calll __stack_chk_fail
1326; LINUX-I386: .cfi_endproc
1327
1328; LINUX-X64-LABEL: test9b:
1329; LINUX-X64-NOT: callq __stack_chk_fail
1330; LINUX-X64: .cfi_endproc
1331
1332; LINUX-KERNEL-X64-LABEL: test9b:
1333; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1334; LINUX-KERNEL-X64: .cfi_endproc
1335
1336; DARWIN-X64-LABEL: test9b:
1337; DARWIN-X64-NOT: callq ___stack_chk_fail
1338; DARWIN-X64: .cfi_endproc
1339
1340; MSVC-I386-LABEL: test9b:
1341; MSVC-I386-NOT: calll @__security_check_cookie@4
1342; MSVC-I386: retl
1343  %x = alloca double, align 8
1344  %call = call double @testi_aux()
1345  store double %call, double* %x, align 8
1346  %cmp2 = fcmp ogt double %call, 0.000000e+00
1347  %y.1 = select i1 %cmp2, double* %x, double* null
1348  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1349  ret void
1350}
1351
1352; test9c:  Addr-of in select instruction
1353;          sspstrong attribute
1354; Requires protector.
1355; Function Attrs: sspstrong
1356define void @test9c() #1 {
1357entry:
1358; LINUX-I386-LABEL: test9c:
1359; LINUX-I386: mov{{l|q}} %gs:
1360; LINUX-I386: calll __stack_chk_fail
1361
1362; LINUX-X64-LABEL: test9c:
1363; LINUX-X64: mov{{l|q}} %fs:
1364; LINUX-X64: callq __stack_chk_fail
1365
1366; LINUX-KERNEL-X64-LABEL: test9c:
1367; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1368; LINUX-KERNEL-X64: callq __stack_chk_fail
1369
1370; DARWIN-X64-LABEL: test9c:
1371; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1372; DARWIN-X64: callq ___stack_chk_fail
1373
1374; MSVC-I386-LABEL: test9c:
1375; MSVC-I386: movl ___security_cookie,
1376; MSVC-I386: calll @__security_check_cookie@4
1377  %x = alloca double, align 8
1378  %call = call double @testi_aux()
1379  store double %call, double* %x, align 8
1380  %cmp2 = fcmp ogt double %call, 0.000000e+00
1381  %y.1 = select i1 %cmp2, double* %x, double* null
1382  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1383  ret void
1384}
1385
1386; test9d:  Addr-of in select instruction
1387;          sspreq attribute
1388; Requires protector.
1389; Function Attrs: sspreq
1390define void @test9d() #2 {
1391entry:
1392; LINUX-I386-LABEL: test9d:
1393; LINUX-I386: mov{{l|q}} %gs:
1394; LINUX-I386: calll __stack_chk_fail
1395
1396; LINUX-X64-LABEL: test9d:
1397; LINUX-X64: mov{{l|q}} %fs:
1398; LINUX-X64: callq __stack_chk_fail
1399
1400; LINUX-KERNEL-X64-LABEL: test9d:
1401; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1402; LINUX-KERNEL-X64: callq __stack_chk_fail
1403
1404; DARWIN-X64-LABEL: test9d:
1405; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1406; DARWIN-X64: callq ___stack_chk_fail
1407
1408; MSVC-I386-LABEL: test9d:
1409; MSVC-I386: movl ___security_cookie,
1410; MSVC-I386: calll @__security_check_cookie@4
1411  %x = alloca double, align 8
1412  %call = call double @testi_aux()
1413  store double %call, double* %x, align 8
1414  %cmp2 = fcmp ogt double %call, 0.000000e+00
1415  %y.1 = select i1 %cmp2, double* %x, double* null
1416  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), double* %y.1)
1417  ret void
1418}
1419
1420; test10a: Addr-of in phi instruction
1421;          no ssp attribute
1422; Requires no protector.
1423define void @test10a() {
1424entry:
1425; LINUX-I386-LABEL: test10a:
1426; LINUX-I386-NOT: calll __stack_chk_fail
1427; LINUX-I386: .cfi_endproc
1428
1429; LINUX-X64-LABEL: test10a:
1430; LINUX-X64-NOT: callq __stack_chk_fail
1431; LINUX-X64: .cfi_endproc
1432
1433; LINUX-KERNEL-X64-LABEL: test10a:
1434; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1435; LINUX-KERNEL-X64: .cfi_endproc
1436
1437; DARWIN-X64-LABEL: test10a:
1438; DARWIN-X64-NOT: callq ___stack_chk_fail
1439; DARWIN-X64: .cfi_endproc
1440
1441; MSVC-I386-LABEL: test10a:
1442; MSVC-I386-NOT: calll @__security_check_cookie@4
1443; MSVC-I386: retl
1444  %x = alloca double, align 8
1445  %call = call double @testi_aux()
1446  store double %call, double* %x, align 8
1447  %cmp = fcmp ogt double %call, 3.140000e+00
1448  br i1 %cmp, label %if.then, label %if.else
1449
1450if.then:                                          ; preds = %entry
1451  %call1 = call double @testi_aux()
1452  store double %call1, double* %x, align 8
1453  br label %if.end4
1454
1455if.else:                                          ; preds = %entry
1456  %cmp2 = fcmp ogt double %call, 1.000000e+00
1457  br i1 %cmp2, label %if.then3, label %if.end4
1458
1459if.then3:                                         ; preds = %if.else
1460  br label %if.end4
1461
1462if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1463  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1464  %call5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1465  ret void
1466}
1467
1468; test10b: Addr-of in phi instruction
1469;          ssp attribute
1470; Requires no protector.
1471; Function Attrs: ssp
1472define void @test10b() #0 {
1473entry:
1474; LINUX-I386-LABEL: test10b:
1475; LINUX-I386-NOT: calll __stack_chk_fail
1476; LINUX-I386: .cfi_endproc
1477
1478; LINUX-X64-LABEL: test10b:
1479; LINUX-X64-NOT: callq __stack_chk_fail
1480; LINUX-X64: .cfi_endproc
1481
1482; LINUX-KERNEL-X64-LABEL: test10b:
1483; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1484; LINUX-KERNEL-X64: .cfi_endproc
1485
1486; DARWIN-X64-LABEL: test10b:
1487; DARWIN-X64-NOT: callq ___stack_chk_fail
1488; DARWIN-X64: .cfi_endproc
1489
1490; MSVC-I386-LABEL: test10b:
1491; MSVC-I386-NOT: calll @__security_check_cookie@4
1492; MSVC-I386: retl
1493  %x = alloca double, align 8
1494  %call = call double @testi_aux()
1495  store double %call, double* %x, align 8
1496  %cmp = fcmp ogt double %call, 3.140000e+00
1497  br i1 %cmp, label %if.then, label %if.else
1498
1499if.then:                                          ; preds = %entry
1500  %call1 = call double @testi_aux()
1501  store double %call1, double* %x, align 8
1502  br label %if.end4
1503
1504if.else:                                          ; preds = %entry
1505  %cmp2 = fcmp ogt double %call, 1.000000e+00
1506  br i1 %cmp2, label %if.then3, label %if.end4
1507
1508if.then3:                                         ; preds = %if.else
1509  br label %if.end4
1510
1511if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1512  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1513  %call5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1514  ret void
1515}
1516
1517; test10c: Addr-of in phi instruction
1518;          sspstrong attribute
1519; Requires protector.
1520; Function Attrs: sspstrong
1521define void @test10c() #1 {
1522entry:
1523; LINUX-I386-LABEL: test10c:
1524; LINUX-I386: mov{{l|q}} %gs:
1525; LINUX-I386: calll __stack_chk_fail
1526
1527; LINUX-X64-LABEL: test10c:
1528; LINUX-X64: mov{{l|q}} %fs:
1529; LINUX-X64: callq __stack_chk_fail
1530
1531; LINUX-KERNEL-X64-LABEL: test10c:
1532; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1533; LINUX-KERNEL-X64: callq __stack_chk_fail
1534
1535; DARWIN-X64-LABEL: test10c:
1536; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1537; DARWIN-X64: callq ___stack_chk_fail
1538
1539; MSVC-I386-LABEL: test10c:
1540; MSVC-I386: movl ___security_cookie,
1541; MSVC-I386: calll @__security_check_cookie@4
1542  %x = alloca double, align 8
1543  %call = call double @testi_aux()
1544  store double %call, double* %x, align 8
1545  %cmp = fcmp ogt double %call, 3.140000e+00
1546  br i1 %cmp, label %if.then, label %if.else
1547
1548if.then:                                          ; preds = %entry
1549  %call1 = call double @testi_aux()
1550  store double %call1, double* %x, align 8
1551  br label %if.end4
1552
1553if.else:                                          ; preds = %entry
1554  %cmp2 = fcmp ogt double %call, 1.000000e+00
1555  br i1 %cmp2, label %if.then3, label %if.end4
1556
1557if.then3:                                         ; preds = %if.else
1558  br label %if.end4
1559
1560if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1561  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1562  %call5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1563  ret void
1564}
1565
1566; test10d: Addr-of in phi instruction
1567;          sspreq attribute
1568; Requires protector.
1569; Function Attrs: sspreq
1570define void @test10d() #2 {
1571entry:
1572; LINUX-I386-LABEL: test10d:
1573; LINUX-I386: mov{{l|q}} %gs:
1574; LINUX-I386: calll __stack_chk_fail
1575
1576; LINUX-X64-LABEL: test10d:
1577; LINUX-X64: mov{{l|q}} %fs:
1578; LINUX-X64: callq __stack_chk_fail
1579
1580; LINUX-KERNEL-X64-LABEL: test10d:
1581; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1582; LINUX-KERNEL-X64: callq __stack_chk_fail
1583
1584; DARWIN-X64-LABEL: test10d:
1585; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1586; DARWIN-X64: callq ___stack_chk_fail
1587
1588; MSVC-I386-LABEL: test10d:
1589; MSVC-I386: movl ___security_cookie,
1590; MSVC-I386: calll @__security_check_cookie@4
1591  %x = alloca double, align 8
1592  %call = call double @testi_aux()
1593  store double %call, double* %x, align 8
1594  %cmp = fcmp ogt double %call, 3.140000e+00
1595  br i1 %cmp, label %if.then, label %if.else
1596
1597if.then:                                          ; preds = %entry
1598  %call1 = call double @testi_aux()
1599  store double %call1, double* %x, align 8
1600  br label %if.end4
1601
1602if.else:                                          ; preds = %entry
1603  %cmp2 = fcmp ogt double %call, 1.000000e+00
1604  br i1 %cmp2, label %if.then3, label %if.end4
1605
1606if.then3:                                         ; preds = %if.else
1607  br label %if.end4
1608
1609if.end4:                                          ; preds = %if.else, %if.then3, %if.then
1610  %y.0 = phi double* [ null, %if.then ], [ %x, %if.then3 ], [ null, %if.else ]
1611  %call5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), double* %y.0)
1612  ret void
1613}
1614
1615; test11a: Addr-of struct element. (GEP followed by store).
1616;          no ssp attribute
1617; Requires no protector.
1618define void @test11a() {
1619entry:
1620; LINUX-I386-LABEL: test11a:
1621; LINUX-I386-NOT: calll __stack_chk_fail
1622; LINUX-I386: .cfi_endproc
1623
1624; LINUX-X64-LABEL: test11a:
1625; LINUX-X64-NOT: callq __stack_chk_fail
1626; LINUX-X64: .cfi_endproc
1627
1628; LINUX-KERNEL-X64-LABEL: test11a:
1629; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1630; LINUX-KERNEL-X64: .cfi_endproc
1631
1632; DARWIN-X64-LABEL: test11a:
1633; DARWIN-X64-NOT: callq ___stack_chk_fail
1634; DARWIN-X64: .cfi_endproc
1635
1636; MSVC-I386-LABEL: test11a:
1637; MSVC-I386-NOT: calll @__security_check_cookie@4
1638; MSVC-I386: retl
1639  %c = alloca %struct.pair, align 4
1640  %b = alloca i32*, align 8
1641  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1642  store i32* %y, i32** %b, align 8
1643  %0 = load i32*, i32** %b, align 8
1644  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32* %0)
1645  ret void
1646}
1647
1648; test11b: Addr-of struct element. (GEP followed by store).
1649;          ssp attribute
1650; Requires no protector.
1651; Function Attrs: ssp
1652define void @test11b() #0 {
1653entry:
1654; LINUX-I386-LABEL: test11b:
1655; LINUX-I386-NOT: calll __stack_chk_fail
1656; LINUX-I386: .cfi_endproc
1657
1658; LINUX-X64-LABEL: test11b:
1659; LINUX-X64-NOT: callq __stack_chk_fail
1660; LINUX-X64: .cfi_endproc
1661
1662; LINUX-KERNEL-X64-LABEL: test11b:
1663; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1664; LINUX-KERNEL-X64: .cfi_endproc
1665
1666; DARWIN-X64-LABEL: test11b:
1667; DARWIN-X64-NOT: callq ___stack_chk_fail
1668; DARWIN-X64: .cfi_endproc
1669
1670; MSVC-I386-LABEL: test11b:
1671; MSVC-I386-NOT: calll @__security_check_cookie@4
1672; MSVC-I386: retl
1673  %c = alloca %struct.pair, align 4
1674  %b = alloca i32*, align 8
1675  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1676  store i32* %y, i32** %b, align 8
1677  %0 = load i32*, i32** %b, align 8
1678  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32* %0)
1679  ret void
1680}
1681
1682; test11c: Addr-of struct element. (GEP followed by store).
1683;          sspstrong attribute
1684; Requires protector.
1685; Function Attrs: sspstrong
1686define void @test11c() #1 {
1687entry:
1688; LINUX-I386-LABEL: test11c:
1689; LINUX-I386: mov{{l|q}} %gs:
1690; LINUX-I386: calll __stack_chk_fail
1691
1692; LINUX-X64-LABEL: test11c:
1693; LINUX-X64: mov{{l|q}} %fs:
1694; LINUX-X64: callq __stack_chk_fail
1695
1696; LINUX-KERNEL-X64-LABEL: test11c:
1697; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1698; LINUX-KERNEL-X64: callq __stack_chk_fail
1699
1700; DARWIN-X64-LABEL: test11c:
1701; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1702; DARWIN-X64: callq ___stack_chk_fail
1703
1704; MSVC-I386-LABEL: test11c:
1705; MSVC-I386: movl ___security_cookie,
1706; MSVC-I386: calll @__security_check_cookie@4
1707  %c = alloca %struct.pair, align 4
1708  %b = alloca i32*, align 8
1709  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1710  store i32* %y, i32** %b, align 8
1711  %0 = load i32*, i32** %b, align 8
1712  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32* %0)
1713  ret void
1714}
1715
1716; test11d: Addr-of struct element. (GEP followed by store).
1717;          sspreq attribute
1718; Requires protector.
1719; Function Attrs: sspreq
1720define void @test11d() #2 {
1721entry:
1722; LINUX-I386-LABEL: test11d:
1723; LINUX-I386: mov{{l|q}} %gs:
1724; LINUX-I386: calll __stack_chk_fail
1725
1726; LINUX-X64-LABEL: test11d:
1727; LINUX-X64: mov{{l|q}} %fs:
1728; LINUX-X64: callq __stack_chk_fail
1729
1730; LINUX-KERNEL-X64-LABEL: test11d:
1731; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1732; LINUX-KERNEL-X64: callq __stack_chk_fail
1733
1734; DARWIN-X64-LABEL: test11d:
1735; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1736; DARWIN-X64: callq ___stack_chk_fail
1737
1738; MSVC-I386-LABEL: test11d:
1739; MSVC-I386: movl ___security_cookie,
1740; MSVC-I386: calll @__security_check_cookie@4
1741  %c = alloca %struct.pair, align 4
1742  %b = alloca i32*, align 8
1743  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1744  store i32* %y, i32** %b, align 8
1745  %0 = load i32*, i32** %b, align 8
1746  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32* %0)
1747  ret void
1748}
1749
1750; test12a: Addr-of struct element, GEP followed by ptrtoint.
1751;          no ssp attribute
1752; Requires no protector.
1753define void @test12a() {
1754entry:
1755; LINUX-I386-LABEL: test12a:
1756; LINUX-I386-NOT: calll __stack_chk_fail
1757; LINUX-I386: .cfi_endproc
1758
1759; LINUX-X64-LABEL: test12a:
1760; LINUX-X64-NOT: callq __stack_chk_fail
1761; LINUX-X64: .cfi_endproc
1762
1763; LINUX-KERNEL-X64-LABEL: test12a:
1764; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1765; LINUX-KERNEL-X64: .cfi_endproc
1766
1767; DARWIN-X64-LABEL: test12a:
1768; DARWIN-X64-NOT: callq ___stack_chk_fail
1769; DARWIN-X64: .cfi_endproc
1770
1771; MSVC-I386-LABEL: test12a:
1772; MSVC-I386-NOT: calll @__security_check_cookie@4
1773; MSVC-I386: retl
1774  %c = alloca %struct.pair, align 4
1775  %b = alloca i32*, align 8
1776  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1777  %0 = ptrtoint i32* %y to i64
1778  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1779  ret void
1780}
1781
1782; test12b: Addr-of struct element, GEP followed by ptrtoint.
1783;          ssp attribute
1784; Requires no protector.
1785; Function Attrs: ssp
1786define void @test12b() #0 {
1787entry:
1788; LINUX-I386-LABEL: test12b:
1789; LINUX-I386-NOT: calll __stack_chk_fail
1790; LINUX-I386: .cfi_endproc
1791
1792; LINUX-X64-LABEL: test12b:
1793; LINUX-X64-NOT: callq __stack_chk_fail
1794; LINUX-X64: .cfi_endproc
1795
1796; LINUX-KERNEL-X64-LABEL: test12b:
1797; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1798; LINUX-KERNEL-X64: .cfi_endproc
1799
1800; DARWIN-X64-LABEL: test12b:
1801; DARWIN-X64-NOT: callq ___stack_chk_fail
1802; DARWIN-X64: .cfi_endproc
1803
1804; MSVC-I386-LABEL: test12b:
1805; MSVC-I386-NOT: calll @__security_check_cookie@4
1806; MSVC-I386: retl
1807  %c = alloca %struct.pair, align 4
1808  %b = alloca i32*, align 8
1809  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1810  %0 = ptrtoint i32* %y to i64
1811  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1812  ret void
1813}
1814
1815; test12c: Addr-of struct element, GEP followed by ptrtoint.
1816;          sspstrong attribute
1817; Function Attrs: sspstrong
1818define void @test12c() #1 {
1819entry:
1820; LINUX-I386-LABEL: test12c:
1821; LINUX-I386: mov{{l|q}} %gs:
1822; LINUX-I386: calll __stack_chk_fail
1823
1824; LINUX-X64-LABEL: test12c:
1825; LINUX-X64: mov{{l|q}} %fs:
1826; LINUX-X64: callq __stack_chk_fail
1827
1828; LINUX-KERNEL-X64-LABEL: test12c:
1829; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1830; LINUX-KERNEL-X64: callq __stack_chk_fail
1831
1832; DARWIN-X64-LABEL: test12c:
1833; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1834; DARWIN-X64: callq ___stack_chk_fail
1835
1836; MSVC-I386-LABEL: test12c:
1837; MSVC-I386: movl ___security_cookie,
1838; MSVC-I386: calll @__security_check_cookie@4
1839  %c = alloca %struct.pair, align 4
1840  %b = alloca i32*, align 8
1841  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1842  %0 = ptrtoint i32* %y to i64
1843  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1844  ret void
1845}
1846
1847; test12d: Addr-of struct element, GEP followed by ptrtoint.
1848;          sspreq attribute
1849; Requires protector.
1850; Function Attrs: sspreq
1851define void @test12d() #2 {
1852entry:
1853; LINUX-I386-LABEL: test12d:
1854; LINUX-I386: mov{{l|q}} %gs:
1855; LINUX-I386: calll __stack_chk_fail
1856
1857; LINUX-X64-LABEL: test12d:
1858; LINUX-X64: mov{{l|q}} %fs:
1859; LINUX-X64: callq __stack_chk_fail
1860
1861; LINUX-KERNEL-X64-LABEL: test12d:
1862; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1863; LINUX-KERNEL-X64: callq __stack_chk_fail
1864
1865; DARWIN-X64-LABEL: test12d:
1866; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1867; DARWIN-X64: callq ___stack_chk_fail
1868
1869; MSVC-I386-LABEL: test12d:
1870; MSVC-I386: movl ___security_cookie,
1871; MSVC-I386: calll @__security_check_cookie@4
1872  %c = alloca %struct.pair, align 4
1873  %b = alloca i32*, align 8
1874  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 1
1875  %0 = ptrtoint i32* %y to i64
1876  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %0)
1877  ret void
1878}
1879
1880; test13a: Addr-of struct element, GEP followed by callinst.
1881;          no ssp attribute
1882; Requires no protector.
1883define void @test13a() {
1884entry:
1885; LINUX-I386-LABEL: test13a:
1886; LINUX-I386-NOT: calll __stack_chk_fail
1887; LINUX-I386: .cfi_endproc
1888
1889; LINUX-X64-LABEL: test13a:
1890; LINUX-X64-NOT: callq __stack_chk_fail
1891; LINUX-X64: .cfi_endproc
1892
1893; LINUX-KERNEL-X64-LABEL: test13a:
1894; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1895; LINUX-KERNEL-X64: .cfi_endproc
1896
1897; DARWIN-X64-LABEL: test13a:
1898; DARWIN-X64-NOT: callq ___stack_chk_fail
1899; DARWIN-X64: .cfi_endproc
1900
1901; MSVC-I386-LABEL: test13a:
1902; MSVC-I386-NOT: calll @__security_check_cookie@4
1903; MSVC-I386: retl
1904  %c = alloca %struct.pair, align 4
1905  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
1906  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
1907  ret void
1908}
1909
1910; test13b: Addr-of struct element, GEP followed by callinst.
1911;          ssp attribute
1912; Requires no protector.
1913; Function Attrs: ssp
1914define void @test13b() #0 {
1915entry:
1916; LINUX-I386-LABEL: test13b:
1917; LINUX-I386-NOT: calll __stack_chk_fail
1918; LINUX-I386: .cfi_endproc
1919
1920; LINUX-X64-LABEL: test13b:
1921; LINUX-X64-NOT: callq __stack_chk_fail
1922; LINUX-X64: .cfi_endproc
1923
1924; LINUX-KERNEL-X64-LABEL: test13b:
1925; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
1926; LINUX-KERNEL-X64: .cfi_endproc
1927
1928; DARWIN-X64-LABEL: test13b:
1929; DARWIN-X64-NOT: callq ___stack_chk_fail
1930; DARWIN-X64: .cfi_endproc
1931
1932; MSVC-I386-LABEL: test13b:
1933; MSVC-I386-NOT: calll @__security_check_cookie@4
1934; MSVC-I386: retl
1935  %c = alloca %struct.pair, align 4
1936  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
1937  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
1938  ret void
1939}
1940
1941; test13c: Addr-of struct element, GEP followed by callinst.
1942;          sspstrong attribute
1943; Requires protector.
1944; Function Attrs: sspstrong
1945define void @test13c() #1 {
1946entry:
1947; LINUX-I386-LABEL: test13c:
1948; LINUX-I386: mov{{l|q}} %gs:
1949; LINUX-I386: calll __stack_chk_fail
1950
1951; LINUX-X64-LABEL: test13c:
1952; LINUX-X64: mov{{l|q}} %fs:
1953; LINUX-X64: callq __stack_chk_fail
1954
1955; LINUX-KERNEL-X64-LABEL: test13c:
1956; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1957; LINUX-KERNEL-X64: callq __stack_chk_fail
1958
1959; DARWIN-X64-LABEL: test13c:
1960; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1961; DARWIN-X64: callq ___stack_chk_fail
1962
1963; MSVC-I386-LABEL: test13c:
1964; MSVC-I386: movl ___security_cookie,
1965; MSVC-I386: calll @__security_check_cookie@4
1966  %c = alloca %struct.pair, align 4
1967  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
1968  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
1969  ret void
1970}
1971
1972; test13d: Addr-of struct element, GEP followed by callinst.
1973;          sspreq attribute
1974; Requires protector.
1975; Function Attrs: sspreq
1976define void @test13d() #2 {
1977entry:
1978; LINUX-I386-LABEL: test13d:
1979; LINUX-I386: mov{{l|q}} %gs:
1980; LINUX-I386: calll __stack_chk_fail
1981
1982; LINUX-X64-LABEL: test13d:
1983; LINUX-X64: mov{{l|q}} %fs:
1984; LINUX-X64: callq __stack_chk_fail
1985
1986; LINUX-KERNEL-X64-LABEL: test13d:
1987; LINUX-KERNEL-X64: mov{{l|q}} %gs:
1988; LINUX-KERNEL-X64: callq __stack_chk_fail
1989
1990; DARWIN-X64-LABEL: test13d:
1991; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
1992; DARWIN-X64: callq ___stack_chk_fail
1993
1994; MSVC-I386-LABEL: test13d:
1995; MSVC-I386: movl ___security_cookie,
1996; MSVC-I386: calll @__security_check_cookie@4
1997  %c = alloca %struct.pair, align 4
1998  %y = getelementptr inbounds %struct.pair, %struct.pair* %c, i64 0, i32 1
1999  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %y)
2000  ret void
2001}
2002
2003; test14a: Addr-of a local, optimized into a GEP (e.g., &a - 12)
2004;          no ssp attribute
2005; Requires no protector.
2006define void @test14a() {
2007entry:
2008; LINUX-I386-LABEL: test14a:
2009; LINUX-I386-NOT: calll __stack_chk_fail
2010; LINUX-I386: .cfi_endproc
2011
2012; LINUX-X64-LABEL: test14a:
2013; LINUX-X64-NOT: callq __stack_chk_fail
2014; LINUX-X64: .cfi_endproc
2015
2016; LINUX-KERNEL-X64-LABEL: test14a:
2017; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2018; LINUX-KERNEL-X64: .cfi_endproc
2019
2020; DARWIN-X64-LABEL: test14a:
2021; DARWIN-X64-NOT: callq ___stack_chk_fail
2022; DARWIN-X64: .cfi_endproc
2023
2024; MSVC-I386-LABEL: test14a:
2025; MSVC-I386-NOT: calll @__security_check_cookie@4
2026; MSVC-I386: retl
2027  %a = alloca i32, align 4
2028  %add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
2029  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
2030  ret void
2031}
2032
2033; test14b: Addr-of a local, optimized into a GEP (e.g., &a - 12)
2034;          ssp attribute
2035; Requires no protector.
2036; Function Attrs: ssp
2037define void @test14b() #0 {
2038entry:
2039; LINUX-I386-LABEL: test14b:
2040; LINUX-I386-NOT: calll __stack_chk_fail
2041; LINUX-I386: .cfi_endproc
2042
2043; LINUX-X64-LABEL: test14b:
2044; LINUX-X64-NOT: callq __stack_chk_fail
2045; LINUX-X64: .cfi_endproc
2046
2047; LINUX-KERNEL-X64-LABEL: test14b:
2048; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2049; LINUX-KERNEL-X64: .cfi_endproc
2050
2051; DARWIN-X64-LABEL: test14b:
2052; DARWIN-X64-NOT: callq ___stack_chk_fail
2053; DARWIN-X64: .cfi_endproc
2054
2055; MSVC-I386-LABEL: test14b:
2056; MSVC-I386-NOT: calll @__security_check_cookie@4
2057; MSVC-I386: retl
2058  %a = alloca i32, align 4
2059  %add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
2060  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
2061  ret void
2062}
2063
2064; test14c: Addr-of a local, optimized into a GEP (e.g., &a - 12)
2065;          sspstrong attribute
2066; Requires protector.
2067; Function Attrs: sspstrong
2068define void @test14c() #1 {
2069entry:
2070; LINUX-I386-LABEL: test14c:
2071; LINUX-I386: mov{{l|q}} %gs:
2072; LINUX-I386: calll __stack_chk_fail
2073
2074; LINUX-X64-LABEL: test14c:
2075; LINUX-X64: mov{{l|q}} %fs:
2076; LINUX-X64: callq __stack_chk_fail
2077
2078; LINUX-KERNEL-X64-LABEL: test14c:
2079; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2080; LINUX-KERNEL-X64: callq __stack_chk_fail
2081
2082; DARWIN-X64-LABEL: test14c:
2083; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2084; DARWIN-X64: callq ___stack_chk_fail
2085
2086; MSVC-I386-LABEL: test14c:
2087; MSVC-I386: movl ___security_cookie,
2088; MSVC-I386: calll @__security_check_cookie@4
2089  %a = alloca i32, align 4
2090  %add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
2091  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
2092  ret void
2093}
2094
2095; test14d: Addr-of a local, optimized into a GEP (e.g., &a - 12)
2096;          sspreq  attribute
2097; Requires protector.
2098; Function Attrs: sspreq
2099define void @test14d() #2 {
2100entry:
2101; LINUX-I386-LABEL: test14d:
2102; LINUX-I386: mov{{l|q}} %gs:
2103; LINUX-I386: calll __stack_chk_fail
2104
2105; LINUX-X64-LABEL: test14d:
2106; LINUX-X64: mov{{l|q}} %fs:
2107; LINUX-X64: callq __stack_chk_fail
2108
2109; LINUX-KERNEL-X64-LABEL: test14d:
2110; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2111; LINUX-KERNEL-X64: callq __stack_chk_fail
2112
2113; DARWIN-X64-LABEL: test14d:
2114; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2115; DARWIN-X64: callq ___stack_chk_fail
2116
2117; MSVC-I386-LABEL: test14d:
2118; MSVC-I386: movl ___security_cookie,
2119; MSVC-I386: calll @__security_check_cookie@4
2120  %a = alloca i32, align 4
2121  %add.ptr5 = getelementptr inbounds i32, i32* %a, i64 -12
2122  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32* %add.ptr5)
2123  ret void
2124}
2125
2126; test15a: Addr-of a local cast to a ptr of a different type
2127;           (e.g., int a; ... ; float *b = &a;)
2128;          no ssp attribute
2129; Requires no protector.
2130define void @test15a() {
2131entry:
2132; LINUX-I386-LABEL: test15a:
2133; LINUX-I386-NOT: calll __stack_chk_fail
2134; LINUX-I386: .cfi_endproc
2135
2136; LINUX-X64-LABEL: test15a:
2137; LINUX-X64-NOT: callq __stack_chk_fail
2138; LINUX-X64: .cfi_endproc
2139
2140; LINUX-KERNEL-X64-LABEL: test15a:
2141; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2142; LINUX-KERNEL-X64: .cfi_endproc
2143
2144; DARWIN-X64-LABEL: test15a:
2145; DARWIN-X64-NOT: callq ___stack_chk_fail
2146; DARWIN-X64: .cfi_endproc
2147
2148; MSVC-I386-LABEL: test15a:
2149; MSVC-I386-NOT: calll @__security_check_cookie@4
2150; MSVC-I386: retl
2151  %a = alloca i32, align 4
2152  %b = alloca float*, align 8
2153  store i32 0, i32* %a, align 4
2154  %0 = bitcast i32* %a to float*
2155  store float* %0, float** %b, align 8
2156  %1 = load float*, float** %b, align 8
2157  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), float* %1)
2158  ret void
2159}
2160
2161; test15b: Addr-of a local cast to a ptr of a different type
2162;           (e.g., int a; ... ; float *b = &a;)
2163;          ssp attribute
2164; Requires no protector.
2165; Function Attrs: ssp
2166define void @test15b() #0 {
2167entry:
2168; LINUX-I386-LABEL: test15b:
2169; LINUX-I386-NOT: calll __stack_chk_fail
2170; LINUX-I386: .cfi_endproc
2171
2172; LINUX-X64-LABEL: test15b:
2173; LINUX-X64-NOT: callq __stack_chk_fail
2174; LINUX-X64: .cfi_endproc
2175
2176; LINUX-KERNEL-X64-LABEL: test15b:
2177; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2178; LINUX-KERNEL-X64: .cfi_endproc
2179
2180; DARWIN-X64-LABEL: test15b:
2181; DARWIN-X64-NOT: callq ___stack_chk_fail
2182; DARWIN-X64: .cfi_endproc
2183
2184; MSVC-I386-LABEL: test15b:
2185; MSVC-I386-NOT: calll @__security_check_cookie@4
2186; MSVC-I386: retl
2187  %a = alloca i32, align 4
2188  %b = alloca float*, align 8
2189  store i32 0, i32* %a, align 4
2190  %0 = bitcast i32* %a to float*
2191  store float* %0, float** %b, align 8
2192  %1 = load float*, float** %b, align 8
2193  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), float* %1)
2194  ret void
2195}
2196
2197; test15c: Addr-of a local cast to a ptr of a different type
2198;           (e.g., int a; ... ; float *b = &a;)
2199;          sspstrong attribute
2200; Requires protector.
2201; Function Attrs: sspstrong
2202define void @test15c() #1 {
2203entry:
2204; LINUX-I386-LABEL: test15c:
2205; LINUX-I386: mov{{l|q}} %gs:
2206; LINUX-I386: calll __stack_chk_fail
2207
2208; LINUX-X64-LABEL: test15c:
2209; LINUX-X64: mov{{l|q}} %fs:
2210; LINUX-X64: callq __stack_chk_fail
2211
2212; LINUX-KERNEL-X64-LABEL: test15c:
2213; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2214; LINUX-KERNEL-X64: callq __stack_chk_fail
2215
2216; DARWIN-X64-LABEL: test15c:
2217; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2218; DARWIN-X64: callq ___stack_chk_fail
2219
2220; MSVC-I386-LABEL: test15c:
2221; MSVC-I386: movl ___security_cookie,
2222; MSVC-I386: calll @__security_check_cookie@4
2223  %a = alloca i32, align 4
2224  %b = alloca float*, align 8
2225  store i32 0, i32* %a, align 4
2226  %0 = bitcast i32* %a to float*
2227  store float* %0, float** %b, align 8
2228  %1 = load float*, float** %b, align 8
2229  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), float* %1)
2230  ret void
2231}
2232
2233; test15d: Addr-of a local cast to a ptr of a different type
2234;           (e.g., int a; ... ; float *b = &a;)
2235;          sspreq attribute
2236; Requires protector.
2237; Function Attrs: sspreq
2238define void @test15d() #2 {
2239entry:
2240; LINUX-I386-LABEL: test15d:
2241; LINUX-I386: mov{{l|q}} %gs:
2242; LINUX-I386: calll __stack_chk_fail
2243
2244; LINUX-X64-LABEL: test15d:
2245; LINUX-X64: mov{{l|q}} %fs:
2246; LINUX-X64: callq __stack_chk_fail
2247
2248; LINUX-KERNEL-X64-LABEL: test15d:
2249; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2250; LINUX-KERNEL-X64: callq __stack_chk_fail
2251
2252; DARWIN-X64-LABEL: test15d:
2253; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2254; DARWIN-X64: callq ___stack_chk_fail
2255
2256; MSVC-I386-LABEL: test15d:
2257; MSVC-I386: movl ___security_cookie,
2258; MSVC-I386: calll @__security_check_cookie@4
2259  %a = alloca i32, align 4
2260  %b = alloca float*, align 8
2261  store i32 0, i32* %a, align 4
2262  %0 = bitcast i32* %a to float*
2263  store float* %0, float** %b, align 8
2264  %1 = load float*, float** %b, align 8
2265  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), float* %1)
2266  ret void
2267}
2268
2269; test16a: Addr-of a local cast to a ptr of a different type (optimized)
2270;           (e.g., int a; ... ; float *b = &a;)
2271;          no ssp attribute
2272; Requires no protector.
2273define void @test16a() {
2274entry:
2275; LINUX-I386-LABEL: test16a:
2276; LINUX-I386-NOT: calll __stack_chk_fail
2277; LINUX-I386: .cfi_endproc
2278
2279; LINUX-X64-LABEL: test16a:
2280; LINUX-X64-NOT: callq __stack_chk_fail
2281; LINUX-X64: .cfi_endproc
2282
2283; LINUX-KERNEL-X64-LABEL: test16a:
2284; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2285; LINUX-KERNEL-X64: .cfi_endproc
2286
2287; DARWIN-X64-LABEL: test16a:
2288; DARWIN-X64-NOT: callq ___stack_chk_fail
2289; DARWIN-X64: .cfi_endproc
2290
2291; MSVC-I386-LABEL: test16a:
2292; MSVC-I386-NOT: calll @__security_check_cookie@4
2293; MSVC-I386: retl
2294  %a = alloca i32, align 4
2295  store i32 0, i32* %a, align 4
2296  %0 = bitcast i32* %a to float*
2297  call void @funfloat(float* %0)
2298  ret void
2299}
2300
2301; test16b: Addr-of a local cast to a ptr of a different type (optimized)
2302;           (e.g., int a; ... ; float *b = &a;)
2303;          ssp attribute
2304; Requires no protector.
2305; Function Attrs: ssp
2306define void @test16b() #0 {
2307entry:
2308; LINUX-I386-LABEL: test16b:
2309; LINUX-I386-NOT: calll __stack_chk_fail
2310; LINUX-I386: .cfi_endproc
2311
2312; LINUX-X64-LABEL: test16b:
2313; LINUX-X64-NOT: callq __stack_chk_fail
2314; LINUX-X64: .cfi_endproc
2315
2316; LINUX-KERNEL-X64-LABEL: test16b:
2317; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2318; LINUX-KERNEL-X64: .cfi_endproc
2319
2320; DARWIN-X64-LABEL: test16b:
2321; DARWIN-X64-NOT: callq ___stack_chk_fail
2322; DARWIN-X64: .cfi_endproc
2323
2324; MSVC-I386-LABEL: test16b:
2325; MSVC-I386-NOT: calll @__security_check_cookie@4
2326; MSVC-I386: retl
2327  %a = alloca i32, align 4
2328  store i32 0, i32* %a, align 4
2329  %0 = bitcast i32* %a to float*
2330  call void @funfloat(float* %0)
2331  ret void
2332}
2333
2334; test16c: Addr-of a local cast to a ptr of a different type (optimized)
2335;           (e.g., int a; ... ; float *b = &a;)
2336;          sspstrong attribute
2337; Requires protector.
2338; Function Attrs: sspstrong
2339define void @test16c() #1 {
2340entry:
2341; LINUX-I386-LABEL: test16c:
2342; LINUX-I386: mov{{l|q}} %gs:
2343; LINUX-I386: calll __stack_chk_fail
2344
2345; LINUX-X64-LABEL: test16c:
2346; LINUX-X64: mov{{l|q}} %fs:
2347; LINUX-X64: callq __stack_chk_fail
2348
2349; LINUX-KERNEL-X64-LABEL: test16c:
2350; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2351; LINUX-KERNEL-X64: callq __stack_chk_fail
2352
2353; DARWIN-X64-LABEL: test16c:
2354; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2355; DARWIN-X64: callq ___stack_chk_fail
2356
2357; MSVC-I386-LABEL: test16c:
2358; MSVC-I386: movl ___security_cookie,
2359; MSVC-I386: calll @__security_check_cookie@4
2360  %a = alloca i32, align 4
2361  store i32 0, i32* %a, align 4
2362  %0 = bitcast i32* %a to float*
2363  call void @funfloat(float* %0)
2364  ret void
2365}
2366
2367; test16d: Addr-of a local cast to a ptr of a different type (optimized)
2368;           (e.g., int a; ... ; float *b = &a;)
2369;          sspreq attribute
2370; Requires protector.
2371; Function Attrs: sspreq
2372define void @test16d() #2 {
2373entry:
2374; LINUX-I386-LABEL: test16d:
2375; LINUX-I386: mov{{l|q}} %gs:
2376; LINUX-I386: calll __stack_chk_fail
2377
2378; LINUX-X64-LABEL: test16d:
2379; LINUX-X64: mov{{l|q}} %fs:
2380; LINUX-X64: callq __stack_chk_fail
2381
2382; LINUX-KERNEL-X64-LABEL: test16d:
2383; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2384; LINUX-KERNEL-X64: callq __stack_chk_fail
2385
2386; DARWIN-X64-LABEL: test16d:
2387; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2388; DARWIN-X64: callq ___stack_chk_fail
2389
2390; MSVC-I386-LABEL: test16d:
2391; MSVC-I386: movl ___security_cookie,
2392; MSVC-I386: calll @__security_check_cookie@4
2393  %a = alloca i32, align 4
2394  store i32 0, i32* %a, align 4
2395  %0 = bitcast i32* %a to float*
2396  call void @funfloat(float* %0)
2397  ret void
2398}
2399
2400; test17a: Addr-of a vector nested in a struct
2401;          no ssp attribute
2402; Requires no protector.
2403define void @test17a() {
2404entry:
2405; LINUX-I386-LABEL: test17a:
2406; LINUX-I386-NOT: calll __stack_chk_fail
2407; LINUX-I386: .cfi_endproc
2408
2409; LINUX-X64-LABEL: test17a:
2410; LINUX-X64-NOT: callq __stack_chk_fail
2411; LINUX-X64: .cfi_endproc
2412
2413; LINUX-KERNEL-X64-LABEL: test17a:
2414; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2415; LINUX-KERNEL-X64: .cfi_endproc
2416
2417; DARWIN-X64-LABEL: test17a:
2418; DARWIN-X64-NOT: callq ___stack_chk_fail
2419; DARWIN-X64: .cfi_endproc
2420
2421; MSVC-I386-LABEL: test17a:
2422; MSVC-I386-NOT: calll @__security_check_cookie@4
2423; MSVC-I386: retl
2424  %c = alloca %struct.vec, align 16
2425  %y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
2426  %add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
2427  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2428  ret void
2429}
2430
2431; test17b: Addr-of a vector nested in a struct
2432;          ssp attribute
2433; Requires no protector.
2434; Function Attrs: ssp
2435define void @test17b() #0 {
2436entry:
2437; LINUX-I386-LABEL: test17b:
2438; LINUX-I386-NOT: calll __stack_chk_fail
2439; LINUX-I386: .cfi_endproc
2440
2441; LINUX-X64-LABEL: test17b:
2442; LINUX-X64-NOT: callq __stack_chk_fail
2443; LINUX-X64: .cfi_endproc
2444
2445; LINUX-KERNEL-X64-LABEL: test17b:
2446; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2447; LINUX-KERNEL-X64: .cfi_endproc
2448
2449; DARWIN-X64-LABEL: test17b:
2450; DARWIN-X64-NOT: callq ___stack_chk_fail
2451; DARWIN-X64: .cfi_endproc
2452
2453; MSVC-I386-LABEL: test17b:
2454; MSVC-I386-NOT: calll @__security_check_cookie@4
2455; MSVC-I386: retl
2456  %c = alloca %struct.vec, align 16
2457  %y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
2458  %add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
2459  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2460  ret void
2461}
2462
2463; test17c: Addr-of a vector nested in a struct
2464;          sspstrong attribute
2465; Requires protector.
2466; Function Attrs: sspstrong
2467define void @test17c() #1 {
2468entry:
2469; LINUX-I386-LABEL: test17c:
2470; LINUX-I386: mov{{l|q}} %gs:
2471; LINUX-I386: calll __stack_chk_fail
2472
2473; LINUX-X64-LABEL: test17c:
2474; LINUX-X64: mov{{l|q}} %fs:
2475; LINUX-X64: callq __stack_chk_fail
2476
2477; LINUX-KERNEL-X64-LABEL: test17c:
2478; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2479; LINUX-KERNEL-X64: callq __stack_chk_fail
2480
2481; DARWIN-X64-LABEL: test17c:
2482; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2483; DARWIN-X64: callq ___stack_chk_fail
2484
2485; MSVC-I386-LABEL: test17c:
2486; MSVC-I386: movl ___security_cookie,
2487; MSVC-I386: calll @__security_check_cookie@4
2488  %c = alloca %struct.vec, align 16
2489  %y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
2490  %add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
2491  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2492  ret void
2493}
2494
2495; test17d: Addr-of a vector nested in a struct
2496;          sspreq attribute
2497; Requires protector.
2498; Function Attrs: sspreq
2499define void @test17d() #2 {
2500entry:
2501; LINUX-I386-LABEL: test17d:
2502; LINUX-I386: mov{{l|q}} %gs:
2503; LINUX-I386: calll __stack_chk_fail
2504
2505; LINUX-X64-LABEL: test17d:
2506; LINUX-X64: mov{{l|q}} %fs:
2507; LINUX-X64: callq __stack_chk_fail
2508
2509; LINUX-KERNEL-X64-LABEL: test17d:
2510; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2511; LINUX-KERNEL-X64: callq __stack_chk_fail
2512
2513; DARWIN-X64-LABEL: test17d:
2514; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2515; DARWIN-X64: callq ___stack_chk_fail
2516
2517; MSVC-I386-LABEL: test17d:
2518; MSVC-I386: movl ___security_cookie,
2519; MSVC-I386: calll @__security_check_cookie@4
2520  %c = alloca %struct.vec, align 16
2521  %y = getelementptr inbounds %struct.vec, %struct.vec* %c, i64 0, i32 0
2522  %add.ptr = getelementptr inbounds <4 x i32>, <4 x i32>* %y, i64 -12
2523  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), <4 x i32>* %add.ptr)
2524  ret void
2525}
2526
2527; test18a: Addr-of a variable passed into an invoke instruction.
2528;          no ssp attribute
2529; Requires no protector.
2530define i32 @test18a() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2531entry:
2532; LINUX-I386-LABEL: test18a:
2533; LINUX-I386-NOT: calll __stack_chk_fail
2534; LINUX-I386: .cfi_endproc
2535
2536; LINUX-X64-LABEL: test18a:
2537; LINUX-X64-NOT: callq __stack_chk_fail
2538; LINUX-X64: .cfi_endproc
2539
2540; LINUX-KERNEL-X64-LABEL: test18a:
2541; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2542; LINUX-KERNEL-X64: .cfi_endproc
2543
2544; DARWIN-X64-LABEL: test18a:
2545; DARWIN-X64-NOT: callq ___stack_chk_fail
2546; DARWIN-X64: .cfi_endproc
2547
2548; MSVC-I386-LABEL: test18a:
2549; MSVC-I386-NOT: calll @__security_check_cookie@4
2550; MSVC-I386: retl
2551  %a = alloca i32, align 4
2552  %exn.slot = alloca i8*
2553  %ehselector.slot = alloca i32
2554  store i32 0, i32* %a, align 4
2555  invoke void @_Z3exceptPi(i32* %a)
2556          to label %invoke.cont unwind label %lpad
2557
2558invoke.cont:
2559  ret i32 0
2560
2561lpad:
2562  %0 = landingpad { i8*, i32 }
2563          catch i8* null
2564  ret i32 0
2565}
2566
2567; test18b: Addr-of a variable passed into an invoke instruction.
2568;          ssp attribute
2569; Requires no protector.
2570; Function Attrs: ssp
2571define i32 @test18b() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2572entry:
2573; LINUX-I386-LABEL: test18b:
2574; LINUX-I386-NOT: calll __stack_chk_fail
2575; LINUX-I386: .cfi_endproc
2576
2577; LINUX-X64-LABEL: test18b:
2578; LINUX-X64-NOT: callq __stack_chk_fail
2579; LINUX-X64: .cfi_endproc
2580
2581; LINUX-KERNEL-X64-LABEL: test18b:
2582; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2583; LINUX-KERNEL-X64: .cfi_endproc
2584
2585; DARWIN-X64-LABEL: test18b:
2586; DARWIN-X64-NOT: callq ___stack_chk_fail
2587; DARWIN-X64: .cfi_endproc
2588
2589; MSVC-I386-LABEL: test18b:
2590; MSVC-I386-NOT: calll @__security_check_cookie@4
2591; MSVC-I386: retl
2592  %a = alloca i32, align 4
2593  %exn.slot = alloca i8*
2594  %ehselector.slot = alloca i32
2595  store i32 0, i32* %a, align 4
2596  invoke void @_Z3exceptPi(i32* %a)
2597          to label %invoke.cont unwind label %lpad
2598
2599invoke.cont:
2600  ret i32 0
2601
2602lpad:
2603  %0 = landingpad { i8*, i32 }
2604          catch i8* null
2605  ret i32 0
2606}
2607
2608; test18c: Addr-of a variable passed into an invoke instruction.
2609;          sspstrong attribute
2610; Requires protector.
2611; Function Attrs: sspstrong
2612define i32 @test18c() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2613entry:
2614; LINUX-I386-LABEL: test18c:
2615; LINUX-I386: mov{{l|q}} %gs:
2616; LINUX-I386: calll __stack_chk_fail
2617
2618; LINUX-X64-LABEL: test18c:
2619; LINUX-X64: mov{{l|q}} %fs:
2620; LINUX-X64: callq __stack_chk_fail
2621
2622; LINUX-KERNEL-X64-LABEL: test18c:
2623; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2624; LINUX-KERNEL-X64: callq __stack_chk_fail
2625
2626; DARWIN-X64-LABEL: test18c:
2627; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2628; DARWIN-X64: callq ___stack_chk_fail
2629
2630; MSVC-I386-LABEL: test18c:
2631; MSVC-I386: movl ___security_cookie,
2632; MSVC-I386: calll @__security_check_cookie@4
2633  %a = alloca i32, align 4
2634  %exn.slot = alloca i8*
2635  %ehselector.slot = alloca i32
2636  store i32 0, i32* %a, align 4
2637  invoke void @_Z3exceptPi(i32* %a)
2638          to label %invoke.cont unwind label %lpad
2639
2640invoke.cont:
2641  ret i32 0
2642
2643lpad:
2644  %0 = landingpad { i8*, i32 }
2645          catch i8* null
2646  ret i32 0
2647}
2648
2649; test18d: Addr-of a variable passed into an invoke instruction.
2650;          sspreq attribute
2651; Requires protector.
2652; Function Attrs: sspreq
2653define i32 @test18d() #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2654entry:
2655; LINUX-I386-LABEL: test18d:
2656; LINUX-I386: mov{{l|q}} %gs:
2657; LINUX-I386: calll __stack_chk_fail
2658
2659; LINUX-X64-LABEL: test18d:
2660; LINUX-X64: mov{{l|q}} %fs:
2661; LINUX-X64: callq __stack_chk_fail
2662
2663; LINUX-KERNEL-X64-LABEL: test18d:
2664; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2665; LINUX-KERNEL-X64: callq __stack_chk_fail
2666
2667; DARWIN-X64-LABEL: test18d:
2668; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2669; DARWIN-X64: callq ___stack_chk_fail
2670
2671; MSVC-I386-LABEL: test18d:
2672; MSVC-I386: movl ___security_cookie,
2673; MSVC-I386: calll @__security_check_cookie@4
2674  %a = alloca i32, align 4
2675  %exn.slot = alloca i8*
2676  %ehselector.slot = alloca i32
2677  store i32 0, i32* %a, align 4
2678  invoke void @_Z3exceptPi(i32* %a)
2679          to label %invoke.cont unwind label %lpad
2680
2681invoke.cont:
2682  ret i32 0
2683
2684lpad:
2685  %0 = landingpad { i8*, i32 }
2686          catch i8* null
2687  ret i32 0
2688}
2689; test19a: Addr-of a struct element passed into an invoke instruction.
2690;           (GEP followed by an invoke)
2691;          no ssp attribute
2692; Requires no protector.
2693define i32 @test19a() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2694entry:
2695; LINUX-I386-LABEL: test19a:
2696; LINUX-I386-NOT: calll __stack_chk_fail
2697; LINUX-I386: .cfi_endproc
2698
2699; LINUX-X64-LABEL: test19a:
2700; LINUX-X64-NOT: callq __stack_chk_fail
2701; LINUX-X64: .cfi_endproc
2702
2703; LINUX-KERNEL-X64-LABEL: test19a:
2704; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2705; LINUX-KERNEL-X64: .cfi_endproc
2706
2707; DARWIN-X64-LABEL: test19a:
2708; DARWIN-X64-NOT: callq ___stack_chk_fail
2709; DARWIN-X64: .cfi_endproc
2710
2711; MSVC-I386-LABEL: test19a:
2712; MSVC-I386-NOT: calll @__security_check_cookie@4
2713; MSVC-I386: retl
2714  %c = alloca %struct.pair, align 4
2715  %exn.slot = alloca i8*
2716  %ehselector.slot = alloca i32
2717  %a = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2718  store i32 0, i32* %a, align 4
2719  %a1 = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2720  invoke void @_Z3exceptPi(i32* %a1)
2721          to label %invoke.cont unwind label %lpad
2722
2723invoke.cont:
2724  ret i32 0
2725
2726lpad:
2727  %0 = landingpad { i8*, i32 }
2728          catch i8* null
2729  ret i32 0
2730}
2731
2732; test19b: Addr-of a struct element passed into an invoke instruction.
2733;           (GEP followed by an invoke)
2734;          ssp attribute
2735; Requires no protector.
2736; Function Attrs: ssp
2737define i32 @test19b() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2738entry:
2739; LINUX-I386-LABEL: test19b:
2740; LINUX-I386-NOT: calll __stack_chk_fail
2741; LINUX-I386: .cfi_endproc
2742
2743; LINUX-X64-LABEL: test19b:
2744; LINUX-X64-NOT: callq __stack_chk_fail
2745; LINUX-X64: .cfi_endproc
2746
2747; LINUX-KERNEL-X64-LABEL: test19b:
2748; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2749; LINUX-KERNEL-X64: .cfi_endproc
2750
2751; DARWIN-X64-LABEL: test19b:
2752; DARWIN-X64-NOT: callq ___stack_chk_fail
2753; DARWIN-X64: .cfi_endproc
2754
2755; MSVC-I386-LABEL: test19b:
2756; MSVC-I386-NOT: calll @__security_check_cookie@4
2757; MSVC-I386: retl
2758  %c = alloca %struct.pair, align 4
2759  %exn.slot = alloca i8*
2760  %ehselector.slot = alloca i32
2761  %a = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2762  store i32 0, i32* %a, align 4
2763  %a1 = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2764  invoke void @_Z3exceptPi(i32* %a1)
2765          to label %invoke.cont unwind label %lpad
2766
2767invoke.cont:
2768  ret i32 0
2769
2770lpad:
2771  %0 = landingpad { i8*, i32 }
2772          catch i8* null
2773  ret i32 0
2774}
2775
2776; test19c: Addr-of a struct element passed into an invoke instruction.
2777;           (GEP followed by an invoke)
2778;          sspstrong attribute
2779; Requires protector.
2780; Function Attrs: sspstrong
2781define i32 @test19c() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2782entry:
2783; LINUX-I386-LABEL: test19c:
2784; LINUX-I386: mov{{l|q}} %gs:
2785; LINUX-I386: calll __stack_chk_fail
2786
2787; LINUX-X64-LABEL: test19c:
2788; LINUX-X64: mov{{l|q}} %fs:
2789; LINUX-X64: callq __stack_chk_fail
2790
2791; LINUX-KERNEL-X64-LABEL: test19c:
2792; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2793; LINUX-KERNEL-X64: callq __stack_chk_fail
2794
2795; DARWIN-X64-LABEL: test19c:
2796; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2797; DARWIN-X64: callq ___stack_chk_fail
2798
2799; MSVC-I386-LABEL: test19c:
2800; MSVC-I386: movl ___security_cookie,
2801; MSVC-I386: calll @__security_check_cookie@4
2802  %c = alloca %struct.pair, align 4
2803  %exn.slot = alloca i8*
2804  %ehselector.slot = alloca i32
2805  %a = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2806  store i32 0, i32* %a, align 4
2807  %a1 = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2808  invoke void @_Z3exceptPi(i32* %a1)
2809          to label %invoke.cont unwind label %lpad
2810
2811invoke.cont:
2812  ret i32 0
2813
2814lpad:
2815  %0 = landingpad { i8*, i32 }
2816          catch i8* null
2817  ret i32 0
2818}
2819
2820; test19d: Addr-of a struct element passed into an invoke instruction.
2821;           (GEP followed by an invoke)
2822;          sspreq attribute
2823; Requires protector.
2824; Function Attrs: sspreq
2825define i32 @test19d() #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
2826entry:
2827; LINUX-I386-LABEL: test19d:
2828; LINUX-I386: mov{{l|q}} %gs:
2829; LINUX-I386: calll __stack_chk_fail
2830; LINUX-I386-NOT: calll __stack_chk_fail
2831
2832; LINUX-X64-LABEL: test19d:
2833; LINUX-X64: mov{{l|q}} %fs:
2834; LINUX-X64: callq __stack_chk_fail
2835; LINUX-X64-NOT: callq __stack_chk_fail
2836
2837; LINUX-KERNEL-X64-LABEL: test19d:
2838; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2839; LINUX-KERNEL-X64: callq __stack_chk_fail
2840; LINUX-KERNEL-X64-NOT: callq ___stack_chk_fail
2841
2842; DARWIN-X64-LABEL: test19d:
2843; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2844; DARWIN-X64: callq ___stack_chk_fail
2845; DARWIN-X64-NOT: callq ___stack_chk_fail
2846
2847; MSVC-I386-LABEL: test19d:
2848; MSVC-I386: movl ___security_cookie,
2849; MSVC-I386: calll @__security_check_cookie@4
2850
2851; MINGW-X64-LABEL: test19d:
2852; MINGW-X64: mov{{l|q}} __stack_chk_guard
2853; MINGW-X64: callq __stack_chk_fail
2854
2855  %c = alloca %struct.pair, align 4
2856  %exn.slot = alloca i8*
2857  %ehselector.slot = alloca i32
2858  %a = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2859  store i32 0, i32* %a, align 4
2860  %a1 = getelementptr inbounds %struct.pair, %struct.pair* %c, i32 0, i32 0
2861  invoke void @_Z3exceptPi(i32* %a1)
2862          to label %invoke.cont unwind label %lpad
2863
2864invoke.cont:
2865  ret i32 0
2866
2867lpad:
2868  %0 = landingpad { i8*, i32 }
2869          catch i8* null
2870  ret i32 0
2871}
2872
2873; test20a: Addr-of a pointer
2874;          no ssp attribute
2875; Requires no protector.
2876define void @test20a() {
2877entry:
2878; LINUX-I386-LABEL: test20a:
2879; LINUX-I386-NOT: calll __stack_chk_fail
2880; LINUX-I386: .cfi_endproc
2881
2882; LINUX-X64-LABEL: test20a:
2883; LINUX-X64-NOT: callq __stack_chk_fail
2884; LINUX-X64: .cfi_endproc
2885
2886; LINUX-KERNEL-X64-LABEL: test20a:
2887; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2888; LINUX-KERNEL-X64: .cfi_endproc
2889
2890; DARWIN-X64-LABEL: test20a:
2891; DARWIN-X64-NOT: callq ___stack_chk_fail
2892; DARWIN-X64: .cfi_endproc
2893
2894; MSVC-I386-LABEL: test20a:
2895; MSVC-I386-NOT: calll @__security_check_cookie@4
2896; MSVC-I386: retl
2897  %a = alloca i32*, align 8
2898  %b = alloca i32**, align 8
2899  %call = call i32* @getp()
2900  store i32* %call, i32** %a, align 8
2901  store i32** %a, i32*** %b, align 8
2902  %0 = load i32**, i32*** %b, align 8
2903  call void @funcall2(i32** %0)
2904  ret void
2905}
2906
2907; test20b: Addr-of a pointer
2908;          ssp attribute
2909; Requires no protector.
2910; Function Attrs: ssp
2911define void @test20b() #0 {
2912entry:
2913; LINUX-I386-LABEL: test20b:
2914; LINUX-I386-NOT: calll __stack_chk_fail
2915; LINUX-I386: .cfi_endproc
2916
2917; LINUX-X64-LABEL: test20b:
2918; LINUX-X64-NOT: callq __stack_chk_fail
2919; LINUX-X64: .cfi_endproc
2920
2921; LINUX-KERNEL-X64-LABEL: test20b:
2922; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
2923; LINUX-KERNEL-X64: .cfi_endproc
2924
2925; DARWIN-X64-LABEL: test20b:
2926; DARWIN-X64-NOT: callq ___stack_chk_fail
2927; DARWIN-X64: .cfi_endproc
2928
2929; MSVC-I386-LABEL: test20b:
2930; MSVC-I386-NOT: calll @__security_check_cookie@4
2931; MSVC-I386: retl
2932  %a = alloca i32*, align 8
2933  %b = alloca i32**, align 8
2934  %call = call i32* @getp()
2935  store i32* %call, i32** %a, align 8
2936  store i32** %a, i32*** %b, align 8
2937  %0 = load i32**, i32*** %b, align 8
2938  call void @funcall2(i32** %0)
2939  ret void
2940}
2941
2942; test20c: Addr-of a pointer
2943;          sspstrong attribute
2944; Requires protector.
2945; Function Attrs: sspstrong
2946define void @test20c() #1 {
2947entry:
2948; LINUX-I386-LABEL: test20c:
2949; LINUX-I386: mov{{l|q}} %gs:
2950; LINUX-I386: calll __stack_chk_fail
2951
2952; LINUX-X64-LABEL: test20c:
2953; LINUX-X64: mov{{l|q}} %fs:
2954; LINUX-X64: callq __stack_chk_fail
2955
2956; LINUX-KERNEL-X64-LABEL: test20c:
2957; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2958; LINUX-KERNEL-X64: callq __stack_chk_fail
2959
2960; DARWIN-X64-LABEL: test20c:
2961; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2962; DARWIN-X64: callq ___stack_chk_fail
2963
2964; MSVC-I386-LABEL: test20c:
2965; MSVC-I386: movl ___security_cookie,
2966; MSVC-I386: calll @__security_check_cookie@4
2967  %a = alloca i32*, align 8
2968  %b = alloca i32**, align 8
2969  %call = call i32* @getp()
2970  store i32* %call, i32** %a, align 8
2971  store i32** %a, i32*** %b, align 8
2972  %0 = load i32**, i32*** %b, align 8
2973  call void @funcall2(i32** %0)
2974  ret void
2975}
2976
2977; test20d: Addr-of a pointer
2978;          sspreq attribute
2979; Requires protector.
2980; Function Attrs: sspreq
2981define void @test20d() #2 {
2982entry:
2983; LINUX-I386-LABEL: test20d:
2984; LINUX-I386: mov{{l|q}} %gs:
2985; LINUX-I386: calll __stack_chk_fail
2986
2987; LINUX-X64-LABEL: test20d:
2988; LINUX-X64: mov{{l|q}} %fs:
2989; LINUX-X64: callq __stack_chk_fail
2990
2991; LINUX-KERNEL-X64-LABEL: test20d:
2992; LINUX-KERNEL-X64: mov{{l|q}} %gs:
2993; LINUX-KERNEL-X64: callq __stack_chk_fail
2994
2995; DARWIN-X64-LABEL: test20d:
2996; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
2997; DARWIN-X64: callq ___stack_chk_fail
2998
2999; MSVC-I386-LABEL: test20d:
3000; MSVC-I386: movl ___security_cookie,
3001; MSVC-I386: calll @__security_check_cookie@4
3002  %a = alloca i32*, align 8
3003  %b = alloca i32**, align 8
3004  %call = call i32* @getp()
3005  store i32* %call, i32** %a, align 8
3006  store i32** %a, i32*** %b, align 8
3007  %0 = load i32**, i32*** %b, align 8
3008  call void @funcall2(i32** %0)
3009  ret void
3010}
3011
3012; test21a: Addr-of a casted pointer
3013;          no ssp attribute
3014; Requires no protector.
3015define void @test21a() {
3016entry:
3017; LINUX-I386-LABEL: test21a:
3018; LINUX-I386-NOT: calll __stack_chk_fail
3019; LINUX-I386: .cfi_endproc
3020
3021; LINUX-X64-LABEL: test21a:
3022; LINUX-X64-NOT: callq __stack_chk_fail
3023; LINUX-X64: .cfi_endproc
3024
3025; LINUX-KERNEL-X64-LABEL: test21a:
3026; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3027; LINUX-KERNEL-X64: .cfi_endproc
3028
3029; DARWIN-X64-LABEL: test21a:
3030; DARWIN-X64-NOT: callq ___stack_chk_fail
3031; DARWIN-X64: .cfi_endproc
3032
3033; MSVC-I386-LABEL: test21a:
3034; MSVC-I386-NOT: calll @__security_check_cookie@4
3035; MSVC-I386: retl
3036  %a = alloca i32*, align 8
3037  %b = alloca float**, align 8
3038  %call = call i32* @getp()
3039  store i32* %call, i32** %a, align 8
3040  %0 = bitcast i32** %a to float**
3041  store float** %0, float*** %b, align 8
3042  %1 = load float**, float*** %b, align 8
3043  call void @funfloat2(float** %1)
3044  ret void
3045}
3046
3047; test21b: Addr-of a casted pointer
3048;          ssp attribute
3049; Requires no protector.
3050; Function Attrs: ssp
3051define void @test21b() #0 {
3052entry:
3053; LINUX-I386-LABEL: test21b:
3054; LINUX-I386-NOT: calll __stack_chk_fail
3055; LINUX-I386: .cfi_endproc
3056
3057; LINUX-X64-LABEL: test21b:
3058; LINUX-X64-NOT: callq __stack_chk_fail
3059; LINUX-X64: .cfi_endproc
3060
3061; LINUX-KERNEL-X64-LABEL: test21b:
3062; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3063; LINUX-KERNEL-X64: .cfi_endproc
3064
3065; DARWIN-X64-LABEL: test21b:
3066; DARWIN-X64-NOT: callq ___stack_chk_fail
3067; DARWIN-X64: .cfi_endproc
3068
3069; MSVC-I386-LABEL: test21b:
3070; MSVC-I386-NOT: calll @__security_check_cookie@4
3071; MSVC-I386: retl
3072  %a = alloca i32*, align 8
3073  %b = alloca float**, align 8
3074  %call = call i32* @getp()
3075  store i32* %call, i32** %a, align 8
3076  %0 = bitcast i32** %a to float**
3077  store float** %0, float*** %b, align 8
3078  %1 = load float**, float*** %b, align 8
3079  call void @funfloat2(float** %1)
3080  ret void
3081}
3082
3083; test21c: Addr-of a casted pointer
3084;          sspstrong attribute
3085; Requires protector.
3086; Function Attrs: sspstrong
3087define void @test21c() #1 {
3088entry:
3089; LINUX-I386-LABEL: test21c:
3090; LINUX-I386: mov{{l|q}} %gs:
3091; LINUX-I386: calll __stack_chk_fail
3092
3093; LINUX-X64-LABEL: test21c:
3094; LINUX-X64: mov{{l|q}} %fs:
3095; LINUX-X64: callq __stack_chk_fail
3096
3097; LINUX-KERNEL-X64-LABEL: test21c:
3098; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3099; LINUX-KERNEL-X64: callq __stack_chk_fail
3100
3101; DARWIN-X64-LABEL: test21c:
3102; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3103; DARWIN-X64: callq ___stack_chk_fail
3104
3105; MSVC-I386-LABEL: test21c:
3106; MSVC-I386: movl ___security_cookie,
3107; MSVC-I386: calll @__security_check_cookie@4
3108  %a = alloca i32*, align 8
3109  %b = alloca float**, align 8
3110  %call = call i32* @getp()
3111  store i32* %call, i32** %a, align 8
3112  %0 = bitcast i32** %a to float**
3113  store float** %0, float*** %b, align 8
3114  %1 = load float**, float*** %b, align 8
3115  call void @funfloat2(float** %1)
3116  ret void
3117}
3118
3119; test21d: Addr-of a casted pointer
3120;          sspreq attribute
3121; Requires protector.
3122; Function Attrs: sspreq
3123define void @test21d() #2 {
3124entry:
3125; LINUX-I386-LABEL: test21d:
3126; LINUX-I386: mov{{l|q}} %gs:
3127; LINUX-I386: calll __stack_chk_fail
3128
3129; LINUX-X64-LABEL: test21d:
3130; LINUX-X64: mov{{l|q}} %fs:
3131; LINUX-X64: callq __stack_chk_fail
3132
3133; LINUX-KERNEL-X64-LABEL: test21d:
3134; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3135; LINUX-KERNEL-X64: callq __stack_chk_fail
3136
3137; DARWIN-X64-LABEL: test21d:
3138; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3139; DARWIN-X64: callq ___stack_chk_fail
3140
3141; MSVC-I386-LABEL: test21d:
3142; MSVC-I386: movl ___security_cookie,
3143; MSVC-I386: calll @__security_check_cookie@4
3144  %a = alloca i32*, align 8
3145  %b = alloca float**, align 8
3146  %call = call i32* @getp()
3147  store i32* %call, i32** %a, align 8
3148  %0 = bitcast i32** %a to float**
3149  store float** %0, float*** %b, align 8
3150  %1 = load float**, float*** %b, align 8
3151  call void @funfloat2(float** %1)
3152  ret void
3153}
3154
3155; test22a: [2 x i8] in a class
3156;          no ssp attribute
3157; Requires no protector.
3158define signext i8 @test22a() {
3159entry:
3160; LINUX-I386-LABEL: test22a:
3161; LINUX-I386-NOT: calll __stack_chk_fail
3162; LINUX-I386: .cfi_endproc
3163
3164; LINUX-X64-LABEL: test22a:
3165; LINUX-X64-NOT: callq __stack_chk_fail
3166; LINUX-X64: .cfi_endproc
3167
3168; LINUX-KERNEL-X64-LABEL: test22a:
3169; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3170; LINUX-KERNEL-X64: .cfi_endproc
3171
3172; DARWIN-X64-LABEL: test22a:
3173; DARWIN-X64-NOT: callq ___stack_chk_fail
3174; DARWIN-X64: .cfi_endproc
3175
3176; MSVC-I386-LABEL: test22a:
3177; MSVC-I386-NOT: calll @__security_check_cookie@4
3178; MSVC-I386: retl
3179  %a = alloca %class.A, align 1
3180  %array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
3181  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3182  %0 = load i8, i8* %arrayidx, align 1
3183  ret i8 %0
3184}
3185
3186; test22b: [2 x i8] in a class
3187;          ssp attribute
3188; Requires no protector.
3189; Function Attrs: ssp
3190define signext i8 @test22b() #0 {
3191entry:
3192; LINUX-I386-LABEL: test22b:
3193; LINUX-I386-NOT: calll __stack_chk_fail
3194; LINUX-I386: .cfi_endproc
3195
3196; LINUX-X64-LABEL: test22b:
3197; LINUX-X64-NOT: callq __stack_chk_fail
3198; LINUX-X64: .cfi_endproc
3199
3200; LINUX-KERNEL-X64-LABEL: test22b:
3201; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3202; LINUX-KERNEL-X64: .cfi_endproc
3203
3204; DARWIN-X64-LABEL: test22b:
3205; DARWIN-X64-NOT: callq ___stack_chk_fail
3206; DARWIN-X64: .cfi_endproc
3207
3208; MSVC-I386-LABEL: test22b:
3209; MSVC-I386-NOT: calll @__security_check_cookie@4
3210; MSVC-I386: retl
3211  %a = alloca %class.A, align 1
3212  %array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
3213  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3214  %0 = load i8, i8* %arrayidx, align 1
3215  ret i8 %0
3216}
3217
3218; test22c: [2 x i8] in a class
3219;          sspstrong attribute
3220; Requires protector.
3221; Function Attrs: sspstrong
3222define signext i8 @test22c() #1 {
3223entry:
3224; LINUX-I386-LABEL: test22c:
3225; LINUX-I386: mov{{l|q}} %gs:
3226; LINUX-I386: calll __stack_chk_fail
3227
3228; LINUX-X64-LABEL: test22c:
3229; LINUX-X64: mov{{l|q}} %fs:
3230; LINUX-X64: callq __stack_chk_fail
3231
3232; LINUX-KERNEL-X64-LABEL: test22c:
3233; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3234; LINUX-KERNEL-X64: callq __stack_chk_fail
3235
3236; DARWIN-X64-LABEL: test22c:
3237; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3238; DARWIN-X64: callq ___stack_chk_fail
3239
3240; MSVC-I386-LABEL: test22c:
3241; MSVC-I386: movl ___security_cookie,
3242; MSVC-I386: calll @__security_check_cookie@4
3243  %a = alloca %class.A, align 1
3244  %array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
3245  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3246  %0 = load i8, i8* %arrayidx, align 1
3247  ret i8 %0
3248}
3249
3250; test22d: [2 x i8] in a class
3251;          sspreq attribute
3252; Requires protector.
3253; Function Attrs: sspreq
3254define signext i8 @test22d() #2 {
3255entry:
3256; LINUX-I386-LABEL: test22d:
3257; LINUX-I386: mov{{l|q}} %gs:
3258; LINUX-I386: calll __stack_chk_fail
3259
3260; LINUX-X64-LABEL: test22d:
3261; LINUX-X64: mov{{l|q}} %fs:
3262; LINUX-X64: callq __stack_chk_fail
3263
3264; LINUX-KERNEL-X64-LABEL: test22d:
3265; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3266; LINUX-KERNEL-X64: callq __stack_chk_fail
3267
3268; DARWIN-X64-LABEL: test22d:
3269; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3270; DARWIN-X64: callq ___stack_chk_fail
3271
3272; MSVC-I386-LABEL: test22d:
3273; MSVC-I386: movl ___security_cookie,
3274; MSVC-I386: calll @__security_check_cookie@4
3275  %a = alloca %class.A, align 1
3276  %array = getelementptr inbounds %class.A, %class.A* %a, i32 0, i32 0
3277  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3278  %0 = load i8, i8* %arrayidx, align 1
3279  ret i8 %0
3280}
3281
3282; test23a: [2 x i8] nested in several layers of structs and unions
3283;          no ssp attribute
3284; Requires no protector.
3285define signext i8 @test23a() {
3286entry:
3287; LINUX-I386-LABEL: test23a:
3288; LINUX-I386-NOT: calll __stack_chk_fail
3289; LINUX-I386: .cfi_endproc
3290
3291; LINUX-X64-LABEL: test23a:
3292; LINUX-X64-NOT: callq __stack_chk_fail
3293; LINUX-X64: .cfi_endproc
3294
3295; LINUX-KERNEL-X64-LABEL: test23a:
3296; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3297; LINUX-KERNEL-X64: .cfi_endproc
3298
3299; DARWIN-X64-LABEL: test23a:
3300; DARWIN-X64-NOT: callq ___stack_chk_fail
3301; DARWIN-X64: .cfi_endproc
3302
3303; MSVC-I386-LABEL: test23a:
3304; MSVC-I386-NOT: calll @__security_check_cookie@4
3305; MSVC-I386: retl
3306  %x = alloca %struct.deep, align 1
3307  %b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
3308  %c = bitcast %union.anon* %b to %struct.anon*
3309  %d = getelementptr inbounds %struct.anon, %struct.anon* %c, i32 0, i32 0
3310  %e = getelementptr inbounds %struct.anon.0, %struct.anon.0* %d, i32 0, i32 0
3311  %array = bitcast %union.anon.1* %e to [2 x i8]*
3312  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3313  %0 = load i8, i8* %arrayidx, align 1
3314  ret i8 %0
3315}
3316
3317; test23b: [2 x i8] nested in several layers of structs and unions
3318;          ssp attribute
3319; Requires no protector.
3320; Function Attrs: ssp
3321define signext i8 @test23b() #0 {
3322entry:
3323; LINUX-I386-LABEL: test23b:
3324; LINUX-I386-NOT: calll __stack_chk_fail
3325; LINUX-I386: .cfi_endproc
3326
3327; LINUX-X64-LABEL: test23b:
3328; LINUX-X64-NOT: callq __stack_chk_fail
3329; LINUX-X64: .cfi_endproc
3330
3331; LINUX-KERNEL-X64-LABEL: test23b:
3332; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3333; LINUX-KERNEL-X64: .cfi_endproc
3334
3335; DARWIN-X64-LABEL: test23b:
3336; DARWIN-X64-NOT: callq ___stack_chk_fail
3337; DARWIN-X64: .cfi_endproc
3338
3339; MSVC-I386-LABEL: test23b:
3340; MSVC-I386-NOT: calll @__security_check_cookie@4
3341; MSVC-I386: retl
3342  %x = alloca %struct.deep, align 1
3343  %b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
3344  %c = bitcast %union.anon* %b to %struct.anon*
3345  %d = getelementptr inbounds %struct.anon, %struct.anon* %c, i32 0, i32 0
3346  %e = getelementptr inbounds %struct.anon.0, %struct.anon.0* %d, i32 0, i32 0
3347  %array = bitcast %union.anon.1* %e to [2 x i8]*
3348  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3349  %0 = load i8, i8* %arrayidx, align 1
3350  ret i8 %0
3351}
3352
3353; test23c: [2 x i8] nested in several layers of structs and unions
3354;          sspstrong attribute
3355; Requires protector.
3356; Function Attrs: sspstrong
3357define signext i8 @test23c() #1 {
3358entry:
3359; LINUX-I386-LABEL: test23c:
3360; LINUX-I386: mov{{l|q}} %gs:
3361; LINUX-I386: calll __stack_chk_fail
3362
3363; LINUX-X64-LABEL: test23c:
3364; LINUX-X64: mov{{l|q}} %fs:
3365; LINUX-X64: callq __stack_chk_fail
3366
3367; LINUX-KERNEL-X64-LABEL: test23c:
3368; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3369; LINUX-KERNEL-X64: callq __stack_chk_fail
3370
3371; DARWIN-X64-LABEL: test23c:
3372; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3373; DARWIN-X64: callq ___stack_chk_fail
3374
3375; MSVC-I386-LABEL: test23c:
3376; MSVC-I386: movl ___security_cookie,
3377; MSVC-I386: calll @__security_check_cookie@4
3378  %x = alloca %struct.deep, align 1
3379  %b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
3380  %c = bitcast %union.anon* %b to %struct.anon*
3381  %d = getelementptr inbounds %struct.anon, %struct.anon* %c, i32 0, i32 0
3382  %e = getelementptr inbounds %struct.anon.0, %struct.anon.0* %d, i32 0, i32 0
3383  %array = bitcast %union.anon.1* %e to [2 x i8]*
3384  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3385  %0 = load i8, i8* %arrayidx, align 1
3386  ret i8 %0
3387}
3388
3389; test23d: [2 x i8] nested in several layers of structs and unions
3390;          sspreq attribute
3391; Requires protector.
3392; Function Attrs: sspreq
3393define signext i8 @test23d() #2 {
3394entry:
3395; LINUX-I386-LABEL: test23d:
3396; LINUX-I386: mov{{l|q}} %gs:
3397; LINUX-I386: calll __stack_chk_fail
3398
3399; LINUX-X64-LABEL: test23d:
3400; LINUX-X64: mov{{l|q}} %fs:
3401; LINUX-X64: callq __stack_chk_fail
3402
3403; LINUX-KERNEL-X64-LABEL: test23d:
3404; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3405; LINUX-KERNEL-X64: callq __stack_chk_fail
3406
3407; DARWIN-X64-LABEL: test23d:
3408; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3409; DARWIN-X64: callq ___stack_chk_fail
3410
3411; MSVC-I386-LABEL: test23d:
3412; MSVC-I386: movl ___security_cookie,
3413; MSVC-I386: calll @__security_check_cookie@4
3414  %x = alloca %struct.deep, align 1
3415  %b = getelementptr inbounds %struct.deep, %struct.deep* %x, i32 0, i32 0
3416  %c = bitcast %union.anon* %b to %struct.anon*
3417  %d = getelementptr inbounds %struct.anon, %struct.anon* %c, i32 0, i32 0
3418  %e = getelementptr inbounds %struct.anon.0, %struct.anon.0* %d, i32 0, i32 0
3419  %array = bitcast %union.anon.1* %e to [2 x i8]*
3420  %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %array, i32 0, i64 0
3421  %0 = load i8, i8* %arrayidx, align 1
3422  ret i8 %0
3423}
3424
3425; test24a: Variable sized alloca
3426;          no ssp attribute
3427; Requires no protector.
3428define void @test24a(i32 %n) {
3429entry:
3430; LINUX-I386-LABEL: test24a:
3431; LINUX-I386-NOT: calll __stack_chk_fail
3432; LINUX-I386: .cfi_endproc
3433
3434; LINUX-X64-LABEL: test24a:
3435; LINUX-X64-NOT: callq __stack_chk_fail
3436; LINUX-X64: .cfi_endproc
3437
3438; LINUX-KERNEL-X64-LABEL: test24a:
3439; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3440; LINUX-KERNEL-X64: .cfi_endproc
3441
3442; DARWIN-X64-LABEL: test24a:
3443; DARWIN-X64-NOT: callq ___stack_chk_fail
3444; DARWIN-X64: .cfi_endproc
3445
3446; MSVC-I386-LABEL: test24a:
3447; MSVC-I386-NOT: calll @__security_check_cookie@4
3448; MSVC-I386: retl
3449  %n.addr = alloca i32, align 4
3450  %a = alloca i32*, align 8
3451  store i32 %n, i32* %n.addr, align 4
3452  %0 = load i32, i32* %n.addr, align 4
3453  %conv = sext i32 %0 to i64
3454  %1 = alloca i8, i64 %conv
3455  %2 = bitcast i8* %1 to i32*
3456  store i32* %2, i32** %a, align 8
3457  ret void
3458}
3459
3460; test24b: Variable sized alloca
3461;          ssp attribute
3462; Requires protector.
3463; Function Attrs: ssp
3464define void @test24b(i32 %n) #0 {
3465entry:
3466; LINUX-I386-LABEL: test24b:
3467; LINUX-I386: mov{{l|q}} %gs:
3468; LINUX-I386: calll __stack_chk_fail
3469
3470; LINUX-X64-LABEL: test24b:
3471; LINUX-X64: mov{{l|q}} %fs:
3472; LINUX-X64: callq __stack_chk_fail
3473
3474; LINUX-KERNEL-X64-LABEL: test24b:
3475; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3476; LINUX-KERNEL-X64: callq __stack_chk_fail
3477
3478; DARWIN-X64-LABEL: test24b:
3479; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3480; DARWIN-X64: callq ___stack_chk_fail
3481
3482; MSVC-I386-LABEL: test24b:
3483; MSVC-I386: movl ___security_cookie,
3484; MSVC-I386: calll @__security_check_cookie@4
3485  %n.addr = alloca i32, align 4
3486  %a = alloca i32*, align 8
3487  store i32 %n, i32* %n.addr, align 4
3488  %0 = load i32, i32* %n.addr, align 4
3489  %conv = sext i32 %0 to i64
3490  %1 = alloca i8, i64 %conv
3491  %2 = bitcast i8* %1 to i32*
3492  store i32* %2, i32** %a, align 8
3493  ret void
3494}
3495
3496; test24c: Variable sized alloca
3497;          sspstrong attribute
3498; Requires protector.
3499; Function Attrs: sspstrong
3500define void @test24c(i32 %n) #1 {
3501entry:
3502; LINUX-I386-LABEL: test24c:
3503; LINUX-I386: mov{{l|q}} %gs:
3504; LINUX-I386: calll __stack_chk_fail
3505
3506; LINUX-X64-LABEL: test24c:
3507; LINUX-X64: mov{{l|q}} %fs:
3508; LINUX-X64: callq __stack_chk_fail
3509
3510; LINUX-KERNEL-X64-LABEL: test24c:
3511; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3512; LINUX-KERNEL-X64: callq __stack_chk_fail
3513
3514; DARWIN-X64-LABEL: test24c:
3515; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3516; DARWIN-X64: callq ___stack_chk_fail
3517
3518; MSVC-I386-LABEL: test24c:
3519; MSVC-I386: movl ___security_cookie,
3520; MSVC-I386: calll @__security_check_cookie@4
3521  %n.addr = alloca i32, align 4
3522  %a = alloca i32*, align 8
3523  store i32 %n, i32* %n.addr, align 4
3524  %0 = load i32, i32* %n.addr, align 4
3525  %conv = sext i32 %0 to i64
3526  %1 = alloca i8, i64 %conv
3527  %2 = bitcast i8* %1 to i32*
3528  store i32* %2, i32** %a, align 8
3529  ret void
3530}
3531
3532; test24d: Variable sized alloca
3533;          sspreq attribute
3534; Requires protector.
3535; Function Attrs: sspreq
3536define void @test24d(i32 %n) #2 {
3537entry:
3538; LINUX-I386-LABEL: test24d:
3539; LINUX-I386: mov{{l|q}} %gs:
3540; LINUX-I386: calll __stack_chk_fail
3541
3542; LINUX-X64-LABEL: test24d:
3543; LINUX-X64: mov{{l|q}} %fs:
3544; LINUX-X64: callq __stack_chk_fail
3545
3546; LINUX-KERNEL-X64-LABEL: test24d:
3547; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3548; LINUX-KERNEL-X64: callq __stack_chk_fail
3549
3550; DARWIN-X64-LABEL: test24d:
3551; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3552; DARWIN-X64: callq ___stack_chk_fail
3553
3554; MSVC-I386-LABEL: test24d:
3555; MSVC-I386: movl ___security_cookie,
3556; MSVC-I386: calll @__security_check_cookie@4
3557  %n.addr = alloca i32, align 4
3558  %a = alloca i32*, align 8
3559  store i32 %n, i32* %n.addr, align 4
3560  %0 = load i32, i32* %n.addr, align 4
3561  %conv = sext i32 %0 to i64
3562  %1 = alloca i8, i64 %conv
3563  %2 = bitcast i8* %1 to i32*
3564  store i32* %2, i32** %a, align 8
3565  ret void
3566}
3567
3568; test25a: array of [4 x i32]
3569;          no ssp attribute
3570; Requires no protector.
3571define i32 @test25a() {
3572entry:
3573; LINUX-I386-LABEL: test25a:
3574; LINUX-I386-NOT: calll __stack_chk_fail
3575; LINUX-I386: .cfi_endproc
3576
3577; LINUX-X64-LABEL: test25a:
3578; LINUX-X64-NOT: callq __stack_chk_fail
3579; LINUX-X64: .cfi_endproc
3580
3581; LINUX-KERNEL-X64-LABEL: test25a:
3582; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3583; LINUX-KERNEL-X64: .cfi_endproc
3584
3585; DARWIN-X64-LABEL: test25a:
3586; DARWIN-X64-NOT: callq ___stack_chk_fail
3587; DARWIN-X64: .cfi_endproc
3588
3589; MSVC-I386-LABEL: test25a:
3590; MSVC-I386-NOT: calll @__security_check_cookie@4
3591; MSVC-I386: retl
3592  %a = alloca [4 x i32], align 16
3593  %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
3594  %0 = load i32, i32* %arrayidx, align 4
3595  ret i32 %0
3596}
3597
3598; test25b: array of [4 x i32]
3599;          ssp attribute
3600; Requires no protector, except for Darwin which _does_ require a protector.
3601; Function Attrs: ssp
3602define i32 @test25b() #0 {
3603entry:
3604; LINUX-I386-LABEL: test25b:
3605; LINUX-I386-NOT: calll __stack_chk_fail
3606; LINUX-I386: .cfi_endproc
3607
3608; LINUX-X64-LABEL: test25b:
3609; LINUX-X64-NOT: callq __stack_chk_fail
3610; LINUX-X64: .cfi_endproc
3611
3612; LINUX-KERNEL-X64-LABEL: test25b:
3613; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3614; LINUX-KERNEL-X64: .cfi_endproc
3615
3616; DARWIN-X64-LABEL: test25b:
3617; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3618; DARWIN-X64: callq ___stack_chk_fail
3619
3620; MSVC-I386-LABEL: test25b:
3621; MSVC-I386-NOT: calll @__security_check_cookie@4
3622; MSVC-I386: retl
3623
3624; MINGW-X64-LABEL: test25b:
3625; MINGW-X64-NOT: callq __stack_chk_fail
3626; MINGW-X64: .seh_endproc
3627
3628  %a = alloca [4 x i32], align 16
3629  %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
3630  %0 = load i32, i32* %arrayidx, align 4
3631  ret i32 %0
3632}
3633
3634; test25c: array of [4 x i32]
3635;          sspstrong attribute
3636; Requires protector.
3637; Function Attrs: sspstrong
3638define i32 @test25c() #1 {
3639entry:
3640; LINUX-I386-LABEL: test25c:
3641; LINUX-I386: mov{{l|q}} %gs:
3642; LINUX-I386: calll __stack_chk_fail
3643
3644; LINUX-X64-LABEL: test25c:
3645; LINUX-X64: mov{{l|q}} %fs:
3646; LINUX-X64: callq __stack_chk_fail
3647
3648; LINUX-KERNEL-X64-LABEL: test25c:
3649; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3650; LINUX-KERNEL-X64: callq __stack_chk_fail
3651
3652; DARWIN-X64-LABEL: test25c:
3653; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3654; DARWIN-X64: callq ___stack_chk_fail
3655
3656; MSVC-I386-LABEL: test25c:
3657; MSVC-I386: movl ___security_cookie,
3658; MSVC-I386: calll @__security_check_cookie@4
3659  %a = alloca [4 x i32], align 16
3660  %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
3661  %0 = load i32, i32* %arrayidx, align 4
3662  ret i32 %0
3663}
3664
3665; test25d: array of [4 x i32]
3666;          sspreq attribute
3667; Requires protector.
3668; Function Attrs: sspreq
3669define i32 @test25d() #2 {
3670entry:
3671; LINUX-I386-LABEL: test25d:
3672; LINUX-I386: mov{{l|q}} %gs:
3673; LINUX-I386: calll __stack_chk_fail
3674
3675; LINUX-X64-LABEL: test25d:
3676; LINUX-X64: mov{{l|q}} %fs:
3677; LINUX-X64: callq __stack_chk_fail
3678
3679; LINUX-KERNEL-X64-LABEL: test25d:
3680; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3681; LINUX-KERNEL-X64: callq __stack_chk_fail
3682
3683; DARWIN-X64-LABEL: test25d:
3684; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3685; DARWIN-X64: callq ___stack_chk_fail
3686
3687; MSVC-I386-LABEL: test25d:
3688; MSVC-I386: movl ___security_cookie,
3689; MSVC-I386: calll @__security_check_cookie@4
3690  %a = alloca [4 x i32], align 16
3691  %arrayidx = getelementptr inbounds [4 x i32], [4 x i32]* %a, i32 0, i64 0
3692  %0 = load i32, i32* %arrayidx, align 4
3693  ret i32 %0
3694}
3695
3696; test26: Nested structure, no arrays, no address-of expressions.
3697;         Verify that the resulting gep-of-gep does not incorrectly trigger
3698;         a stack protector.
3699;         ssptrong attribute
3700; Requires no protector.
3701; Function Attrs: sspstrong
3702define void @test26() #1 {
3703entry:
3704; LINUX-I386-LABEL: test26:
3705; LINUX-I386-NOT: calll __stack_chk_fail
3706; LINUX-I386: .cfi_endproc
3707
3708; LINUX-X64-LABEL: test26:
3709; LINUX-X64-NOT: callq __stack_chk_fail
3710; LINUX-X64: .cfi_endproc
3711
3712; LINUX-KERNEL-X64-LABEL: test26:
3713; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3714; LINUX-KERNEL-X64: .cfi_endproc
3715
3716; DARWIN-X64-LABEL: test26:
3717; DARWIN-X64-NOT: callq ___stack_chk_fail
3718; DARWIN-X64: .cfi_endproc
3719
3720; MSVC-I386-LABEL: test26:
3721; MSVC-I386-NOT: calll @__security_check_cookie@4
3722; MSVC-I386: retl
3723  %c = alloca %struct.nest, align 4
3724  %b = getelementptr inbounds %struct.nest, %struct.nest* %c, i32 0, i32 1
3725  %_a = getelementptr inbounds %struct.pair, %struct.pair* %b, i32 0, i32 0
3726  %0 = load i32, i32* %_a, align 4
3727  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0)
3728  ret void
3729}
3730
3731; test27: Address-of a structure taken in a function with a loop where
3732;         the alloca is an incoming value to a PHI node and a use of that PHI
3733;         node is also an incoming value.
3734;         Verify that the address-of analysis does not get stuck in infinite
3735;         recursion when chasing the alloca through the PHI nodes.
3736; Requires protector.
3737; Function Attrs: sspstrong
3738define i32 @test27(i32 %arg) #1 {
3739bb:
3740; LINUX-I386-LABEL: test27:
3741; LINUX-I386: mov{{l|q}} %gs:
3742; LINUX-I386: calll __stack_chk_fail
3743
3744; LINUX-X64-LABEL: test27:
3745; LINUX-X64: mov{{l|q}} %fs:
3746; LINUX-X64: callq __stack_chk_fail
3747
3748; LINUX-KERNEL-X64-LABEL: test27:
3749; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3750; LINUX-KERNEL-X64: callq __stack_chk_fail
3751
3752; DARWIN-X64-LABEL: test27:
3753; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3754; DARWIN-X64: callq ___stack_chk_fail
3755
3756; MSVC-I386-LABEL: test27:
3757; MSVC-I386: movl ___security_cookie,
3758; MSVC-I386: calll @__security_check_cookie@4
3759  %tmp = alloca %struct.small*, align 8
3760  %tmp1 = call i32 (...) @dummy(%struct.small** %tmp)
3761  %tmp2 = load %struct.small*, %struct.small** %tmp, align 8
3762  %tmp3 = ptrtoint %struct.small* %tmp2 to i64
3763  %tmp4 = trunc i64 %tmp3 to i32
3764  %tmp5 = icmp sgt i32 %tmp4, 0
3765  br i1 %tmp5, label %bb6, label %bb21
3766
3767bb6:                                              ; preds = %bb17, %bb
3768  %tmp7 = phi %struct.small* [ %tmp19, %bb17 ], [ %tmp2, %bb ]
3769  %tmp8 = phi i64 [ %tmp20, %bb17 ], [ 1, %bb ]
3770  %tmp9 = phi i32 [ %tmp14, %bb17 ], [ %tmp1, %bb ]
3771  %tmp10 = getelementptr inbounds %struct.small, %struct.small* %tmp7, i64 0, i32 0
3772  %tmp11 = load i8, i8* %tmp10, align 1
3773  %tmp12 = icmp eq i8 %tmp11, 1
3774  %tmp13 = add nsw i32 %tmp9, 8
3775  %tmp14 = select i1 %tmp12, i32 %tmp13, i32 %tmp9
3776  %tmp15 = trunc i64 %tmp8 to i32
3777  %tmp16 = icmp eq i32 %tmp15, %tmp4
3778  br i1 %tmp16, label %bb21, label %bb17
3779
3780bb17:                                             ; preds = %bb6
3781  %tmp18 = getelementptr inbounds %struct.small*, %struct.small** %tmp, i64 %tmp8
3782  %tmp19 = load %struct.small*, %struct.small** %tmp18, align 8
3783  %tmp20 = add i64 %tmp8, 1
3784  br label %bb6
3785
3786bb21:                                             ; preds = %bb6, %bb
3787  %tmp22 = phi i32 [ %tmp1, %bb ], [ %tmp14, %bb6 ]
3788  %tmp23 = call i32 (...) @dummy(i32 %tmp22)
3789  ret i32 undef
3790}
3791
3792; test28a: An array of [32 x i8] and a requested ssp-buffer-size of 33.
3793; Requires no protector.
3794; Function Attrs: ssp stack-protector-buffer-size=33
3795define i32 @test28a() #3 {
3796entry:
3797; LINUX-I386-LABEL: test28a:
3798; LINUX-I386-NOT: calll __stack_chk_fail
3799; LINUX-I386: .cfi_endproc
3800
3801; LINUX-X64-LABEL: test28a:
3802; LINUX-X64-NOT: callq __stack_chk_fail
3803; LINUX-X64: .cfi_endproc
3804
3805; LINUX-KERNEL-X64-LABEL: test28a:
3806; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3807; LINUX-KERNEL-X64: .cfi_endproc
3808
3809; DARWIN-X64-LABEL: test28a:
3810; DARWIN-X64-NOT: callq ___stack_chk_fail
3811; DARWIN-X64: .cfi_endproc
3812
3813; MSVC-I386-LABEL: test28a:
3814; MSVC-I386-NOT: calll @__security_check_cookie@4
3815; MSVC-I386: retl
3816  %test = alloca [32 x i8], align 16
3817  %arraydecay = getelementptr inbounds [32 x i8], [32 x i8]* %test, i32 0, i32 0
3818  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
3819  ret i32 %call
3820}
3821
3822; test28b: An array of [33 x i8] and a requested ssp-buffer-size of 33.
3823; Requires protector.
3824; Function Attrs: ssp stack-protector-buffer-size=33
3825define i32 @test28b() #3 {
3826entry:
3827; LINUX-I386-LABEL: test28b:
3828; LINUX-I386: mov{{l|q}} %gs:
3829; LINUX-I386: calll __stack_chk_fail
3830
3831; LINUX-X64-LABEL: test28b:
3832; LINUX-X64: mov{{l|q}} %fs:
3833; LINUX-X64: callq __stack_chk_fail
3834
3835; LINUX-KERNEL-X64-LABEL: test28b:
3836; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3837; LINUX-KERNEL-X64: callq __stack_chk_fail
3838
3839; DARWIN-X64-LABEL: test28b:
3840; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3841; DARWIN-X64: callq ___stack_chk_fail
3842
3843; MSVC-I386-LABEL: test28b:
3844; MSVC-I386: movl ___security_cookie,
3845; MSVC-I386: calll @__security_check_cookie@4
3846  %test = alloca [33 x i8], align 16
3847  %arraydecay = getelementptr inbounds [33 x i8], [33 x i8]* %test, i32 0, i32 0
3848  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
3849  ret i32 %call
3850}
3851
3852; test29a: An array of [4 x i8] and a requested ssp-buffer-size of 5.
3853; Requires no protector.
3854; Function Attrs: ssp stack-protector-buffer-size=5
3855define i32 @test29a() #4 {
3856entry:
3857; LINUX-I386-LABEL: test29a:
3858; LINUX-I386-NOT: calll __stack_chk_fail
3859; LINUX-I386: .cfi_endproc
3860
3861; LINUX-X64-LABEL: test29a:
3862; LINUX-X64-NOT: callq __stack_chk_fail
3863; LINUX-X64: .cfi_endproc
3864
3865; LINUX-KERNEL-X64-LABEL: test29a:
3866; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3867; LINUX-KERNEL-X64: .cfi_endproc
3868
3869; DARWIN-X64-LABEL: test29a:
3870; DARWIN-X64-NOT: callq ___stack_chk_fail
3871; DARWIN-X64: .cfi_endproc
3872
3873; MSVC-I386-LABEL: test29a:
3874; MSVC-I386-NOT: calll @__security_check_cookie@4
3875; MSVC-I386: retl
3876  %test = alloca [4 x i8], align 1
3877  %arraydecay = getelementptr inbounds [4 x i8], [4 x i8]* %test, i32 0, i32 0
3878  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
3879  ret i32 %call
3880}
3881
3882; test29b: An array of [5 x i8] and a requested ssp-buffer-size of 5.
3883; Requires protector.
3884; Function Attrs: ssp stack-protector-buffer-size=5
3885define i32 @test29b() #4 {
3886entry:
3887; LINUX-I386-LABEL: test29b:
3888; LINUX-I386: mov{{l|q}} %gs:
3889; LINUX-I386: calll __stack_chk_fail
3890
3891; LINUX-X64-LABEL: test29b:
3892; LINUX-X64: mov{{l|q}} %fs:
3893; LINUX-X64: callq __stack_chk_fail
3894
3895; LINUX-KERNEL-X64-LABEL: test29b:
3896; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3897; LINUX-KERNEL-X64: callq __stack_chk_fail
3898
3899; DARWIN-X64-LABEL: test29b:
3900; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3901; DARWIN-X64: callq ___stack_chk_fail
3902
3903; MSVC-I386-LABEL: test29b:
3904; MSVC-I386: movl ___security_cookie,
3905; MSVC-I386: calll @__security_check_cookie@4
3906  %test = alloca [5 x i8], align 1
3907  %arraydecay = getelementptr inbounds [5 x i8], [5 x i8]* %test, i32 0, i32 0
3908  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %arraydecay)
3909  ret i32 %call
3910}
3911
3912; test30a: An structure containing an i32 and an array of [5 x i8].
3913;          Requested ssp-buffer-size of 6.
3914; Requires no protector.
3915; Function Attrs: ssp stack-protector-buffer-size=6
3916define i32 @test30a() #5 {
3917entry:
3918; LINUX-I386-LABEL: test30a:
3919; LINUX-I386-NOT: calll __stack_chk_fail
3920; LINUX-I386: .cfi_endproc
3921
3922; LINUX-X64-LABEL: test30a:
3923; LINUX-X64-NOT: callq __stack_chk_fail
3924; LINUX-X64: .cfi_endproc
3925
3926; LINUX-KERNEL-X64-LABEL: test30a:
3927; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
3928; LINUX-KERNEL-X64: .cfi_endproc
3929
3930; DARWIN-X64-LABEL: test30a:
3931; DARWIN-X64-NOT: callq ___stack_chk_fail
3932; DARWIN-X64: .cfi_endproc
3933
3934; MSVC-I386-LABEL: test30a:
3935; MSVC-I386-NOT: calll @__security_check_cookie@4
3936; MSVC-I386: retl
3937  %test = alloca %struct.small_char, align 4
3938  %test.coerce = alloca { i64, i8 }
3939  %0 = bitcast { i64, i8 }* %test.coerce to i8*
3940  %1 = bitcast %struct.small_char* %test to i8*
3941  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 12, i1 false)
3942  %2 = getelementptr { i64, i8 }, { i64, i8 }* %test.coerce, i32 0, i32 0
3943  %3 = load i64, i64* %2, align 1
3944  %4 = getelementptr { i64, i8 }, { i64, i8 }* %test.coerce, i32 0, i32 1
3945  %5 = load i8, i8* %4, align 1
3946  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %3, i8 %5)
3947  ret i32 %call
3948}
3949
3950; test30b: An structure containing an i32 and an array of [5 x i8].
3951;          Requested ssp-buffer-size of 5.
3952; Requires protector.
3953; Function Attrs: ssp stack-protector-buffer-size=5
3954define i32 @test30b() #4 {
3955entry:
3956; LINUX-I386-LABEL: test30b:
3957; LINUX-I386: mov{{l|q}} %gs:
3958; LINUX-I386: calll __stack_chk_fail
3959
3960; LINUX-X64-LABEL: test30b:
3961; LINUX-X64: mov{{l|q}} %fs:
3962; LINUX-X64: callq __stack_chk_fail
3963
3964; LINUX-KERNEL-X64-LABEL: test30b:
3965; LINUX-KERNEL-X64: mov{{l|q}} %gs:
3966; LINUX-KERNEL-X64: callq __stack_chk_fail
3967
3968; DARWIN-X64-LABEL: test30b:
3969; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
3970; DARWIN-X64: callq ___stack_chk_fail
3971
3972; MSVC-I386-LABEL: test30b:
3973; MSVC-I386: movl ___security_cookie,
3974; MSVC-I386: calll @__security_check_cookie@4
3975  %test = alloca %struct.small_char, align 4
3976  %test.coerce = alloca { i64, i8 }
3977  %0 = bitcast { i64, i8 }* %test.coerce to i8*
3978  %1 = bitcast %struct.small_char* %test to i8*
3979  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 12, i1 false)
3980  %2 = getelementptr { i64, i8 }, { i64, i8 }* %test.coerce, i32 0, i32 0
3981  %3 = load i64, i64* %2, align 1
3982  %4 = getelementptr { i64, i8 }, { i64, i8 }* %test.coerce, i32 0, i32 1
3983  %5 = load i8, i8* %4, align 1
3984  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 %3, i8 %5)
3985  ret i32 %call
3986}
3987
3988; test31a: An alloca of size 5.
3989;          Requested ssp-buffer-size of 6.
3990; Requires no protector.
3991; Function Attrs: ssp stack-protector-buffer-size=6
3992define i32 @test31a() #5 {
3993entry:
3994; LINUX-I386-LABEL: test31a:
3995; LINUX-I386-NOT: calll __stack_chk_fail
3996; LINUX-I386: .cfi_endproc
3997
3998; LINUX-X64-LABEL: test31a:
3999; LINUX-X64-NOT: callq __stack_chk_fail
4000; LINUX-X64: .cfi_endproc
4001
4002; LINUX-KERNEL-X64-LABEL: test31a:
4003; LINUX-KERNEL-X64-NOT: callq __stack_chk_fail
4004; LINUX-KERNEL-X64: .cfi_endproc
4005
4006; DARWIN-X64-LABEL: test31a:
4007; DARWIN-X64-NOT: callq ___stack_chk_fail
4008; DARWIN-X64: .cfi_endproc
4009
4010; MSVC-I386-LABEL: test31a:
4011; MSVC-I386-NOT: calll @__security_check_cookie@4
4012; MSVC-I386: retl
4013  %test = alloca i8*, align 8
4014  %0 = alloca i8, i64 4
4015  store i8* %0, i8** %test, align 8
4016  %1 = load i8*, i8** %test, align 8
4017  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %1)
4018  ret i32 %call
4019}
4020
4021; test31b: An alloca of size 5.
4022;          Requested ssp-buffer-size of 5.
4023; Requires protector.
4024define i32 @test31b() #4 {
4025entry:
4026; LINUX-I386-LABEL: test31b:
4027; LINUX-I386: mov{{l|q}} %gs:
4028; LINUX-I386: calll __stack_chk_fail
4029
4030; LINUX-X64-LABEL: test31b:
4031; LINUX-X64: mov{{l|q}} %fs:
4032; LINUX-X64: callq __stack_chk_fail
4033
4034; LINUX-KERNEL-X64-LABEL: test31b:
4035; LINUX-KERNEL-X64: mov{{l|q}} %gs:
4036; LINUX-KERNEL-X64: callq __stack_chk_fail
4037
4038; DARWIN-X64-LABEL: test31b:
4039; DARWIN-X64: mov{{l|q}} ___stack_chk_guard
4040; DARWIN-X64: callq ___stack_chk_fail
4041
4042; MSVC-I386-LABEL: test31b:
4043; MSVC-I386: movl ___security_cookie,
4044; MSVC-I386: calll @__security_check_cookie@4
4045  %test = alloca i8*, align 8
4046  %0 = alloca i8, i64 5
4047  store i8* %0, i8** %test, align 8
4048  %1 = load i8*, i8** %test, align 8
4049  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %1)
4050  ret i32 %call
4051}
4052
4053define void @__stack_chk_fail() #1 !dbg !6 {
4054entry:
4055  ret void
4056}
4057
4058define void @test32() #1 !dbg !7 {
4059entry:
4060; LINUX-I386-LABEL: test32:
4061; LINUX-I386:       .loc 1 4 2 prologue_end
4062; LINUX-I386:       .loc 1 0 0
4063; LINUX-I386-NEXT:  calll __stack_chk_fail
4064
4065; LINUX-X64-LABEL: test32:
4066; LINUX-X64:       .loc 1 4 2 prologue_end
4067; LINUX-X64:       .loc 1 0 0
4068; LINUX-X64-NEXT:  callq __stack_chk_fail
4069
4070; LINUX-KERNEL-X64-LABEL: test32:
4071; LINUX-KERNEL-X64:       .loc 1 4 2 prologue_end
4072; LINUX-KERNEL-X64:       .loc 1 0 0
4073; LINUX-KERNEL-X64-NEXT:  callq __stack_chk_fail
4074
4075; OPENBSD-AMD64-LABEL: test32:
4076; OPENBSD-AMD64:       .loc 1 4 2 prologue_end
4077; OPENBSD-AMD64:       .loc 1 0 0
4078; OPENBSD-AMD64-NEXT:  movl
4079; OPENBSD-AMD64-NEXT:  callq __stack_smash_handler
4080  %0 = alloca [5 x i8], align 1
4081  ret void, !dbg !9
4082}
4083
4084declare double @testi_aux()
4085declare i8* @strcpy(i8*, i8*)
4086declare i32 @printf(i8*, ...)
4087declare void @funcall(i32*)
4088declare void @funcall2(i32**)
4089declare void @funfloat(float*)
4090declare void @funfloat2(float**)
4091declare void @_Z3exceptPi(i32*)
4092declare i32 @__gxx_personality_v0(...)
4093declare i32* @getp()
4094declare i32 @dummy(...)
4095declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1)
4096
4097attributes #0 = { ssp }
4098attributes #1 = { sspstrong }
4099attributes #2 = { sspreq }
4100attributes #3 = { ssp "stack-protector-buffer-size"="33" }
4101attributes #4 = { ssp "stack-protector-buffer-size"="5" }
4102attributes #5 = { ssp "stack-protector-buffer-size"="6" }
4103
4104!llvm.dbg.cu = !{!0}
4105!llvm.module.flags = !{!3, !4}
4106!llvm.ident = !{!5}
4107
4108!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug)
4109!1 = !DIFile(filename: "test.c", directory: "/tmp")
4110!2 = !{}
4111!3 = !{i32 2, !"Dwarf Version", i32 4}
4112!4 = !{i32 2, !"Debug Info Version", i32 3}
4113!5 = !{!"clang version x.y.z"}
4114!6 = distinct !DISubprogram(name: "__stack_chk_fail", scope: !1, type: !8, unit: !0)
4115!7 = distinct !DISubprogram(name: "test32", scope: !1, type: !8, unit: !0)
4116!8 = !DISubroutineType(types: !2)
4117!9 = !DILocation(line: 4, column: 2, scope: !7)
4118