1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=never -S | FileCheck %s --check-prefixes=CHECK,NEVER
3; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=runtime -S | FileCheck %s --check-prefixes=CHECK,RUNTIME
4; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=always -S | FileCheck %s --check-prefixes=CHECK,ALWAYS
5target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128"
6target triple = "x86_64-unknown-linux-gnu"
7
8declare void @Foo(i8*)
9
10define void @Empty() uwtable sanitize_address {
11; CHECK-LABEL: @Empty(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    ret void
14;
15entry:
16  ret void
17}
18
19define void @Simple() uwtable sanitize_address {
20; NEVER-LABEL: @Simple(
21; NEVER-NEXT:  entry:
22; NEVER-NEXT:    [[MYALLOCA:%.*]] = alloca i8, i64 64, align 32
23; NEVER-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[MYALLOCA]] to i64
24; NEVER-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], 32
25; NEVER-NEXT:    [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to i8*
26; NEVER-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[TMP0]] to i64*
27; NEVER-NEXT:    store i64 1102416563, i64* [[TMP3]], align 8
28; NEVER-NEXT:    [[TMP4:%.*]] = add i64 [[TMP0]], 8
29; NEVER-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to i64*
30; NEVER-NEXT:    store i64 ptrtoint ([11 x i8]* @___asan_gen_ to i64), i64* [[TMP5]], align 8
31; NEVER-NEXT:    [[TMP6:%.*]] = add i64 [[TMP0]], 16
32; NEVER-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to i64*
33; NEVER-NEXT:    store i64 ptrtoint (void ()* @Simple to i64), i64* [[TMP7]], align 8
34; NEVER-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP0]], 3
35; NEVER-NEXT:    [[TMP9:%.*]] = add i64 [[TMP8]], 2147450880
36; NEVER-NEXT:    [[TMP10:%.*]] = add i64 [[TMP9]], 0
37; NEVER-NEXT:    [[TMP11:%.*]] = inttoptr i64 [[TMP10]] to i64*
38; NEVER-NEXT:    store i64 -868083113472691727, i64* [[TMP11]], align 1
39; NEVER-NEXT:    call void @Foo(i8* [[TMP2]])
40; NEVER-NEXT:    store i64 1172321806, i64* [[TMP3]], align 8
41; NEVER-NEXT:    [[TMP12:%.*]] = add i64 [[TMP9]], 0
42; NEVER-NEXT:    [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to i64*
43; NEVER-NEXT:    store i64 0, i64* [[TMP13]], align 1
44; NEVER-NEXT:    ret void
45;
46; RUNTIME-LABEL: @Simple(
47; RUNTIME-NEXT:  entry:
48; RUNTIME-NEXT:    [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8
49; RUNTIME-NEXT:    [[TMP0:%.*]] = load i32, i32* @__asan_option_detect_stack_use_after_return, align 4
50; RUNTIME-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[TMP0]], 0
51; RUNTIME-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
52; RUNTIME:       2:
53; RUNTIME-NEXT:    [[TMP3:%.*]] = call i64 @__asan_stack_malloc_0(i64 64)
54; RUNTIME-NEXT:    br label [[TMP4]]
55; RUNTIME:       4:
56; RUNTIME-NEXT:    [[TMP5:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[TMP2]] ]
57; RUNTIME-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 0
58; RUNTIME-NEXT:    br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP9:%.*]]
59; RUNTIME:       7:
60; RUNTIME-NEXT:    [[MYALLOCA:%.*]] = alloca i8, i64 64, align 32
61; RUNTIME-NEXT:    [[TMP8:%.*]] = ptrtoint i8* [[MYALLOCA]] to i64
62; RUNTIME-NEXT:    br label [[TMP9]]
63; RUNTIME:       9:
64; RUNTIME-NEXT:    [[TMP10:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP8]], [[TMP7]] ]
65; RUNTIME-NEXT:    store i64 [[TMP10]], i64* [[ASAN_LOCAL_STACK_BASE]], align 8
66; RUNTIME-NEXT:    [[TMP11:%.*]] = add i64 [[TMP10]], 32
67; RUNTIME-NEXT:    [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to i8*
68; RUNTIME-NEXT:    [[TMP13:%.*]] = inttoptr i64 [[TMP10]] to i64*
69; RUNTIME-NEXT:    store i64 1102416563, i64* [[TMP13]], align 8
70; RUNTIME-NEXT:    [[TMP14:%.*]] = add i64 [[TMP10]], 8
71; RUNTIME-NEXT:    [[TMP15:%.*]] = inttoptr i64 [[TMP14]] to i64*
72; RUNTIME-NEXT:    store i64 ptrtoint ([11 x i8]* @___asan_gen_ to i64), i64* [[TMP15]], align 8
73; RUNTIME-NEXT:    [[TMP16:%.*]] = add i64 [[TMP10]], 16
74; RUNTIME-NEXT:    [[TMP17:%.*]] = inttoptr i64 [[TMP16]] to i64*
75; RUNTIME-NEXT:    store i64 ptrtoint (void ()* @Simple to i64), i64* [[TMP17]], align 8
76; RUNTIME-NEXT:    [[TMP18:%.*]] = lshr i64 [[TMP10]], 3
77; RUNTIME-NEXT:    [[TMP19:%.*]] = add i64 [[TMP18]], 2147450880
78; RUNTIME-NEXT:    [[TMP20:%.*]] = add i64 [[TMP19]], 0
79; RUNTIME-NEXT:    [[TMP21:%.*]] = inttoptr i64 [[TMP20]] to i64*
80; RUNTIME-NEXT:    store i64 -868083113472691727, i64* [[TMP21]], align 1
81; RUNTIME-NEXT:    call void @Foo(i8* [[TMP12]])
82; RUNTIME-NEXT:    store i64 1172321806, i64* [[TMP13]], align 8
83; RUNTIME-NEXT:    [[TMP22:%.*]] = icmp ne i64 [[TMP5]], 0
84; RUNTIME-NEXT:    br i1 [[TMP22]], label [[TMP23:%.*]], label [[TMP30:%.*]]
85; RUNTIME:       23:
86; RUNTIME-NEXT:    [[TMP24:%.*]] = add i64 [[TMP19]], 0
87; RUNTIME-NEXT:    [[TMP25:%.*]] = inttoptr i64 [[TMP24]] to i64*
88; RUNTIME-NEXT:    store i64 -723401728380766731, i64* [[TMP25]], align 1
89; RUNTIME-NEXT:    [[TMP26:%.*]] = add i64 [[TMP5]], 56
90; RUNTIME-NEXT:    [[TMP27:%.*]] = inttoptr i64 [[TMP26]] to i64*
91; RUNTIME-NEXT:    [[TMP28:%.*]] = load i64, i64* [[TMP27]], align 8
92; RUNTIME-NEXT:    [[TMP29:%.*]] = inttoptr i64 [[TMP28]] to i8*
93; RUNTIME-NEXT:    store i8 0, i8* [[TMP29]], align 1
94; RUNTIME-NEXT:    br label [[TMP33:%.*]]
95; RUNTIME:       30:
96; RUNTIME-NEXT:    [[TMP31:%.*]] = add i64 [[TMP19]], 0
97; RUNTIME-NEXT:    [[TMP32:%.*]] = inttoptr i64 [[TMP31]] to i64*
98; RUNTIME-NEXT:    store i64 0, i64* [[TMP32]], align 1
99; RUNTIME-NEXT:    br label [[TMP33]]
100; RUNTIME:       33:
101; RUNTIME-NEXT:    ret void
102;
103; ALWAYS-LABEL: @Simple(
104; ALWAYS-NEXT:  entry:
105; ALWAYS-NEXT:    [[ASAN_LOCAL_STACK_BASE:%.*]] = alloca i64, align 8
106; ALWAYS-NEXT:    [[TMP0:%.*]] = call i64 @__asan_stack_malloc_always_0(i64 64)
107; ALWAYS-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 0
108; ALWAYS-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
109; ALWAYS:       2:
110; ALWAYS-NEXT:    [[MYALLOCA:%.*]] = alloca i8, i64 64, align 32
111; ALWAYS-NEXT:    [[TMP3:%.*]] = ptrtoint i8* [[MYALLOCA]] to i64
112; ALWAYS-NEXT:    br label [[TMP4]]
113; ALWAYS:       4:
114; ALWAYS-NEXT:    [[TMP5:%.*]] = phi i64 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP3]], [[TMP2]] ]
115; ALWAYS-NEXT:    store i64 [[TMP5]], i64* [[ASAN_LOCAL_STACK_BASE]], align 8
116; ALWAYS-NEXT:    [[TMP6:%.*]] = add i64 [[TMP5]], 32
117; ALWAYS-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to i8*
118; ALWAYS-NEXT:    [[TMP8:%.*]] = inttoptr i64 [[TMP5]] to i64*
119; ALWAYS-NEXT:    store i64 1102416563, i64* [[TMP8]], align 8
120; ALWAYS-NEXT:    [[TMP9:%.*]] = add i64 [[TMP5]], 8
121; ALWAYS-NEXT:    [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to i64*
122; ALWAYS-NEXT:    store i64 ptrtoint ([11 x i8]* @___asan_gen_ to i64), i64* [[TMP10]], align 8
123; ALWAYS-NEXT:    [[TMP11:%.*]] = add i64 [[TMP5]], 16
124; ALWAYS-NEXT:    [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to i64*
125; ALWAYS-NEXT:    store i64 ptrtoint (void ()* @Simple to i64), i64* [[TMP12]], align 8
126; ALWAYS-NEXT:    [[TMP13:%.*]] = lshr i64 [[TMP5]], 3
127; ALWAYS-NEXT:    [[TMP14:%.*]] = add i64 [[TMP13]], 2147450880
128; ALWAYS-NEXT:    [[TMP15:%.*]] = add i64 [[TMP14]], 0
129; ALWAYS-NEXT:    [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to i64*
130; ALWAYS-NEXT:    store i64 -868083113472691727, i64* [[TMP16]], align 1
131; ALWAYS-NEXT:    call void @Foo(i8* [[TMP7]])
132; ALWAYS-NEXT:    store i64 1172321806, i64* [[TMP8]], align 8
133; ALWAYS-NEXT:    [[TMP17:%.*]] = icmp ne i64 [[TMP0]], 0
134; ALWAYS-NEXT:    br i1 [[TMP17]], label [[TMP18:%.*]], label [[TMP25:%.*]]
135; ALWAYS:       18:
136; ALWAYS-NEXT:    [[TMP19:%.*]] = add i64 [[TMP14]], 0
137; ALWAYS-NEXT:    [[TMP20:%.*]] = inttoptr i64 [[TMP19]] to i64*
138; ALWAYS-NEXT:    store i64 -723401728380766731, i64* [[TMP20]], align 1
139; ALWAYS-NEXT:    [[TMP21:%.*]] = add i64 [[TMP0]], 56
140; ALWAYS-NEXT:    [[TMP22:%.*]] = inttoptr i64 [[TMP21]] to i64*
141; ALWAYS-NEXT:    [[TMP23:%.*]] = load i64, i64* [[TMP22]], align 8
142; ALWAYS-NEXT:    [[TMP24:%.*]] = inttoptr i64 [[TMP23]] to i8*
143; ALWAYS-NEXT:    store i8 0, i8* [[TMP24]], align 1
144; ALWAYS-NEXT:    br label [[TMP28:%.*]]
145; ALWAYS:       25:
146; ALWAYS-NEXT:    [[TMP26:%.*]] = add i64 [[TMP14]], 0
147; ALWAYS-NEXT:    [[TMP27:%.*]] = inttoptr i64 [[TMP26]] to i64*
148; ALWAYS-NEXT:    store i64 0, i64* [[TMP27]], align 1
149; ALWAYS-NEXT:    br label [[TMP28]]
150; ALWAYS:       28:
151; ALWAYS-NEXT:    ret void
152;
153entry:
154  %x = alloca i8, align 16
155  call void @Foo(i8* %x)
156  ret void
157}
158
159define void @Huge() uwtable sanitize_address {
160; CHECK-LABEL: @Huge(
161; CHECK-NEXT:  entry:
162; CHECK-NEXT:    [[MYALLOCA:%.*]] = alloca i8, i64 100288, align 32
163; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[MYALLOCA]] to i64
164; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[TMP0]], 32
165; CHECK-NEXT:    [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to [100000 x i8]*
166; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[TMP0]] to i64*
167; CHECK-NEXT:    store i64 1102416563, i64* [[TMP3]], align 8
168; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[TMP0]], 8
169; CHECK-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to i64*
170; CHECK-NEXT:    store i64 ptrtoint ([16 x i8]* @___asan_gen_.1 to i64), i64* [[TMP5]], align 8
171; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[TMP0]], 16
172; CHECK-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to i64*
173; CHECK-NEXT:    store i64 ptrtoint (void ()* @Huge to i64), i64* [[TMP7]], align 8
174; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP0]], 3
175; CHECK-NEXT:    [[TMP9:%.*]] = add i64 [[TMP8]], 2147450880
176; CHECK-NEXT:    [[TMP10:%.*]] = add i64 [[TMP9]], 0
177; CHECK-NEXT:    [[TMP11:%.*]] = inttoptr i64 [[TMP10]] to i32*
178; CHECK-NEXT:    store i32 -235802127, i32* [[TMP11]], align 1
179; CHECK-NEXT:    [[TMP12:%.*]] = add i64 [[TMP9]], 12504
180; CHECK-NEXT:    [[TMP13:%.*]] = inttoptr i64 [[TMP12]] to i64*
181; CHECK-NEXT:    store i64 -868082074056920077, i64* [[TMP13]], align 1
182; CHECK-NEXT:    [[TMP14:%.*]] = add i64 [[TMP9]], 12512
183; CHECK-NEXT:    [[TMP15:%.*]] = inttoptr i64 [[TMP14]] to i64*
184; CHECK-NEXT:    store i64 -868082074056920077, i64* [[TMP15]], align 1
185; CHECK-NEXT:    [[TMP16:%.*]] = add i64 [[TMP9]], 12520
186; CHECK-NEXT:    [[TMP17:%.*]] = inttoptr i64 [[TMP16]] to i64*
187; CHECK-NEXT:    store i64 -868082074056920077, i64* [[TMP17]], align 1
188; CHECK-NEXT:    [[TMP18:%.*]] = add i64 [[TMP9]], 12528
189; CHECK-NEXT:    [[TMP19:%.*]] = inttoptr i64 [[TMP18]] to i64*
190; CHECK-NEXT:    store i64 -868082074056920077, i64* [[TMP19]], align 1
191; CHECK-NEXT:    [[XX:%.*]] = getelementptr inbounds [100000 x i8], [100000 x i8]* [[TMP2]], i64 0, i64 0
192; CHECK-NEXT:    call void @Foo(i8* [[XX]])
193; CHECK-NEXT:    store i64 1172321806, i64* [[TMP3]], align 8
194; CHECK-NEXT:    [[TMP20:%.*]] = add i64 [[TMP9]], 0
195; CHECK-NEXT:    [[TMP21:%.*]] = inttoptr i64 [[TMP20]] to i32*
196; CHECK-NEXT:    store i32 0, i32* [[TMP21]], align 1
197; CHECK-NEXT:    [[TMP22:%.*]] = add i64 [[TMP9]], 12504
198; CHECK-NEXT:    [[TMP23:%.*]] = inttoptr i64 [[TMP22]] to i64*
199; CHECK-NEXT:    store i64 0, i64* [[TMP23]], align 1
200; CHECK-NEXT:    [[TMP24:%.*]] = add i64 [[TMP9]], 12512
201; CHECK-NEXT:    [[TMP25:%.*]] = inttoptr i64 [[TMP24]] to i64*
202; CHECK-NEXT:    store i64 0, i64* [[TMP25]], align 1
203; CHECK-NEXT:    [[TMP26:%.*]] = add i64 [[TMP9]], 12520
204; CHECK-NEXT:    [[TMP27:%.*]] = inttoptr i64 [[TMP26]] to i64*
205; CHECK-NEXT:    store i64 0, i64* [[TMP27]], align 1
206; CHECK-NEXT:    [[TMP28:%.*]] = add i64 [[TMP9]], 12528
207; CHECK-NEXT:    [[TMP29:%.*]] = inttoptr i64 [[TMP28]] to i64*
208; CHECK-NEXT:    store i64 0, i64* [[TMP29]], align 1
209; CHECK-NEXT:    ret void
210;
211entry:
212  %x = alloca [100000 x i8], align 16
213  %xx = getelementptr inbounds [100000 x i8], [100000 x i8]* %x, i64 0, i64 0
214  call void @Foo(i8* %xx)
215  ret void
216}
217