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
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
19 ; CHECK: %[[LOAD_SHADOW_PTR:[^ ]*]] = inttoptr
20 ; CHECK: %[[LOAD_SHADOW:[^ ]*]] = load i8, ptr %[[LOAD_SHADOW_PTR]]
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]])
37 ; CHECK: %tmp1 = load i32, ptr %a
38 ; CHECK: ret i32 %tmp1
43 %tmp1 = load i32, ptr %a, align 4
47 define void @test_store(ptr %a) sanitize_address {
48 ; CHECK-LABEL: @test_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
54 ; CHECK: %[[STORE_SHADOW_PTR:[^ ]*]] = inttoptr
55 ; CHECK: %[[STORE_SHADOW:[^ ]*]] = load i8, ptr %[[STORE_SHADOW_PTR]]
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]])
72 ; CHECK: store i32 42, ptr %a
77 store i32 42, ptr %a, align 4
81 ; Check that asan leaves just one alloca.
83 declare void @alloca_test_use(ptr)
84 define void @alloca_test() sanitize_address {
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)
95 ; CHECK-LABEL: define void @alloca_test()
96 ; CHECK: %asan_local_stack_base = alloca
101 define void @LongDoubleTest(ptr nocapture %a) nounwind uwtable sanitize_address {
103 store x86_fp80 0xK3FFF8000000000000000, ptr %a, align 16
107 ; CHECK-LABEL: LongDoubleTest
108 ; CHECK: __asan_report_store_n
109 ; CHECK: __asan_report_store_n
113 define void @i40test(ptr %a, ptr %b) nounwind uwtable sanitize_address {
115 %t = load i40, ptr %a
116 store i40 %t, ptr %b, align 8
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)
127 define void @i64test_align1(ptr %b) nounwind uwtable sanitize_address {
129 store i64 0, ptr %b, align 1
133 ; CHECK-LABEL: i64test_align1
134 ; CHECK: __asan_report_store_n{{.*}}, i64 8)
135 ; CHECK: __asan_report_store_n{{.*}}, i64 8)
138 define void @i128test_align8(ptr %a) nounwind uwtable sanitize_address {
140 store i128 0, ptr %a, align 8
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 {
151 store i128 0, ptr %a, align 16
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 {
162 %t = load i80, ptr %a
163 store i80 %t, ptr %b, align 8
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)
174 ; asan should not instrument functions with available_externally linkage.
175 define available_externally i32 @f_available_externally(ptr %a) sanitize_address {
177 %tmp1 = load i32, ptr %a
180 ; CHECK-LABEL: @f_available_externally
181 ; CHECK-NOT: __asan_report
185 ; CHECK-LABEL: @test_swifterror
186 ; CHECK-NOT: __asan_report_load
188 define void @test_swifterror(ptr swifterror) sanitize_address {
189 %swifterror_ptr_value = load ptr, ptr %0
193 ; CHECK-LABEL: @test_swifterror_2
194 ; CHECK-NOT: __asan_report_store
196 define void @test_swifterror_2(ptr swifterror) sanitize_address {
197 store ptr null, ptr %0
201 ; CHECK-LABEL: @test_swifterror_3
202 ; CHECK-NOT: __asan_report_store
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)
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 }
219 ; CHECK: ![[PROF]] = !{!"branch_weights", i32 1, i32 100000}