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