[Clang][CodeGen]`vtable`, `typeinfo` et al. are globals
[llvm-project.git] / llvm / test / Instrumentation / AddressSanitizer / basic.ll
blob068d6d18cd45ebab01f87be4be7ccbc9329f2d2e
1 ; Test basic address sanitizer instrumentation.
4 ; RUN: opt < %s -passes=asan -S | FileCheck --check-prefixes=CHECK,CHECK-S3 %s
5 ; RUN: opt < %s -passes=asan -asan-mapping-scale=5 -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s
7 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
8 target triple = "x86_64-unknown-linux-gnu"
9 ; CHECK: @llvm.used = appending global [1 x ptr] [ptr @asan.module_ctor]
10 ; CHECK: @llvm.global_ctors = {{.*}}{ i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }
12 define i32 @test_load(ptr %a) sanitize_address {
13 ; CHECK-LABEL: @test_load
14 ; CHECK-NOT: load
15 ; CHECK:   %[[LOAD_ADDR:[^ ]*]] = ptrtoint ptr %a to i64
16 ; CHECK-S3:   lshr i64 %[[LOAD_ADDR]], 3
17 ; CHECK-S5:   lshr i64 %[[LOAD_ADDR]], 5
18 ; CHECK:   {{or|add}}
19 ; CHECK:   %[[LOAD_SHADOW_PTR:[^ ]*]] = inttoptr
20 ; CHECK:   %[[LOAD_SHADOW:[^ ]*]] = load i8, ptr %[[LOAD_SHADOW_PTR]]
21 ; CHECK:   icmp ne i8
22 ; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}!prof ![[PROF:[0-9]+]]
24 ; First instrumentation block refines the shadow test.
25 ; CHECK-S3:   and i64 %[[LOAD_ADDR]], 7
26 ; CHECK-S5:   and i64 %[[LOAD_ADDR]], 31
27 ; CHECK:   add i64 %{{.*}}, 3
28 ; CHECK:   trunc i64 %{{.*}} to i8
29 ; CHECK:   icmp sge i8 %{{.*}}, %[[LOAD_SHADOW]]
30 ; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
32 ; The crash block reports the error.
33 ; CHECK:   call void @__asan_report_load4(i64 %[[LOAD_ADDR]])
34 ; CHECK:   unreachable
36 ; The actual load.
37 ; CHECK:   %tmp1 = load i32, ptr %a
38 ; CHECK:   ret i32 %tmp1
42 entry:
43   %tmp1 = load i32, ptr %a, align 4
44   ret i32 %tmp1
47 define void @test_store(ptr %a) sanitize_address {
48 ; CHECK-LABEL: @test_store
49 ; CHECK-NOT: store
50 ; CHECK:   %[[STORE_ADDR:[^ ]*]] = ptrtoint ptr %a to i64
51 ; CHECK-S3:   lshr i64 %[[STORE_ADDR]], 3
52 ; CHECK-S5:   lshr i64 %[[STORE_ADDR]], 5
53 ; CHECK:   {{or|add}}
54 ; CHECK:   %[[STORE_SHADOW_PTR:[^ ]*]] = inttoptr
55 ; CHECK:   %[[STORE_SHADOW:[^ ]*]] = load i8, ptr %[[STORE_SHADOW_PTR]]
56 ; CHECK:   icmp ne i8
57 ; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
59 ; First instrumentation block refines the shadow test.
60 ; CHECK-S3:   and i64 %[[STORE_ADDR]], 7
61 ; CHECK-S5:   and i64 %[[STORE_ADDR]], 31
62 ; CHECK:   add i64 %{{.*}}, 3
63 ; CHECK:   trunc i64 %{{.*}} to i8
64 ; CHECK:   icmp sge i8 %{{.*}}, %[[STORE_SHADOW]]
65 ; CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
67 ; The crash block reports the error.
68 ; CHECK:   call void @__asan_report_store4(i64 %[[STORE_ADDR]])
69 ; CHECK:   unreachable
71 ; The actual load.
72 ; CHECK:   store i32 42, ptr %a
73 ; CHECK:   ret void
76 entry:
77   store i32 42, ptr %a, align 4
78   ret void
81 ; Check that asan leaves just one alloca.
83 declare void @alloca_test_use(ptr)
84 define void @alloca_test() sanitize_address {
85 entry:
86   %x = alloca [10 x i8], align 1
87   %y = alloca [10 x i8], align 1
88   %z = alloca [10 x i8], align 1
89   call void @alloca_test_use(ptr %x)
90   call void @alloca_test_use(ptr %y)
91   call void @alloca_test_use(ptr %z)
92   ret void
95 ; CHECK-LABEL: define void @alloca_test()
96 ; CHECK: %asan_local_stack_base = alloca
97 ; CHECK: = alloca
98 ; CHECK-NOT: = alloca
99 ; CHECK: ret void
101 define void @LongDoubleTest(ptr nocapture %a) nounwind uwtable sanitize_address {
102 entry:
103     store x86_fp80 0xK3FFF8000000000000000, ptr %a, align 16
104     ret void
107 ; CHECK-LABEL: LongDoubleTest
108 ; CHECK: __asan_report_store_n
109 ; CHECK: __asan_report_store_n
110 ; CHECK: ret void
113 define void @i40test(ptr %a, ptr %b) nounwind uwtable sanitize_address {
114   entry:
115   %t = load i40, ptr %a
116   store i40 %t, ptr %b, align 8
117   ret void
120 ; CHECK-LABEL: i40test
121 ; CHECK: __asan_report_load_n{{.*}}, i64 5)
122 ; CHECK: __asan_report_load_n{{.*}}, i64 5)
123 ; CHECK: __asan_report_store_n{{.*}}, i64 5)
124 ; CHECK: __asan_report_store_n{{.*}}, i64 5)
125 ; CHECK: ret void
127 define void @i64test_align1(ptr %b) nounwind uwtable sanitize_address {
128   entry:
129   store i64 0, ptr %b, align 1
130   ret void
133 ; CHECK-LABEL: i64test_align1
134 ; CHECK: __asan_report_store_n{{.*}}, i64 8)
135 ; CHECK: __asan_report_store_n{{.*}}, i64 8)
136 ; CHECK: ret void
138 define void @i128test_align8(ptr %a) nounwind uwtable sanitize_address {
139 entry:
140   store i128 0, ptr %a, align 8
141   ret void
143 ; CHECK-LABEL: define {{[^@]+}}@i128test_align8(
144 ; CHECK-S3:      load i16, ptr %[[#]], align 1
145 ; CHECK-S3-NEXT: icmp ne i16 %[[#]], 0
146 ; CHECK-S5:      load i8, ptr %[[#]], align 1
147 ; CHECK-S5:      load i8, ptr %[[#]], align 1
149 define void @i128test_align16(ptr %a) nounwind uwtable sanitize_address {
150 entry:
151   store i128 0, ptr %a, align 16
152   ret void
154 ; CHECK-LABEL: define {{[^@]+}}@i128test_align16(
155 ; CHECK-S3:      load i16, ptr %[[#]], align 2
156 ; CHECK-S3-NEXT: icmp ne i16 %[[#]], 0
157 ; CHECK-S5:      load i8, ptr %[[#]], align 1
158 ; CHECK-S5-NEXT: icmp ne i8 %[[#]], 0
160 define void @i80test(ptr %a, ptr %b) nounwind uwtable sanitize_address {
161   entry:
162   %t = load i80, ptr %a
163   store i80 %t, ptr %b, align 8
164   ret void
167 ; CHECK-LABEL: i80test
168 ; CHECK: __asan_report_load_n{{.*}}, i64 10)
169 ; CHECK: __asan_report_load_n{{.*}}, i64 10)
170 ; CHECK: __asan_report_store_n{{.*}}, i64 10)
171 ; CHECK: __asan_report_store_n{{.*}}, i64 10)
172 ; CHECK: ret void
174 ; asan should not instrument functions with available_externally linkage.
175 define available_externally i32 @f_available_externally(ptr %a) sanitize_address  {
176 entry:
177   %tmp1 = load i32, ptr %a
178   ret i32 %tmp1
180 ; CHECK-LABEL: @f_available_externally
181 ; CHECK-NOT: __asan_report
182 ; CHECK: ret i32
185 ; CHECK-LABEL: @test_swifterror
186 ; CHECK-NOT: __asan_report_load
187 ; CHECK: ret void
188 define void @test_swifterror(ptr swifterror) sanitize_address {
189   %swifterror_ptr_value = load ptr, ptr %0
190   ret void
193 ; CHECK-LABEL: @test_swifterror_2
194 ; CHECK-NOT: __asan_report_store
195 ; CHECK: ret void
196 define void @test_swifterror_2(ptr swifterror) sanitize_address {
197   store ptr null, ptr %0
198   ret void
201 ; CHECK-LABEL: @test_swifterror_3
202 ; CHECK-NOT: __asan_report_store
203 ; CHECK: ret void
204 define void @test_swifterror_3() sanitize_address {
205   %swifterror_addr = alloca swifterror ptr
206   store ptr null, ptr %swifterror_addr
207   call void @test_swifterror_2(ptr swifterror %swifterror_addr)
208   ret void
211 ;; ctor/dtor have the nounwind attribute. See uwtable.ll, they additionally have
212 ;; the uwtable attribute with the module flag "uwtable".
213 ; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] {{(comdat )?}}{
214 ; CHECK: call void @__asan_init()
216 ; CHECK: attributes #[[#ATTR]] = { nounwind }
218 ; PROF
219 ; CHECK: ![[PROF]] = !{!"branch_weights", i32 1, i32 100000}