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