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