1 ; Test basic address sanitizer instrumentation.
3 ; RUN: opt < %s -hwasan -hwasan-recover=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT
4 ; RUN: opt < %s -hwasan -hwasan-recover=1 -S | FileCheck %s --check-prefixes=CHECK,RECOVER
6 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
7 target triple = "aarch64--linux-android"
9 define i8 @test_load8(i8* %a) sanitize_hwaddress {
10 ; CHECK-LABEL: @test_load8(
11 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
12 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
13 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
14 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
15 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
16 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
17 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
18 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
19 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
21 ; ABORT: call void asm sideeffect "hlt #256", "{x0}"(i64 %[[A]])
23 ; RECOVER: call void asm sideeffect "hlt #288", "{x0}"(i64 %[[A]])
26 ; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4
27 ; CHECK: ret i8 %[[G]]
30 %b = load i8, i8* %a, align 4
34 define i16 @test_load16(i16* %a) sanitize_hwaddress {
35 ; CHECK-LABEL: @test_load16(
36 ; CHECK: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
37 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
38 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
39 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
40 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
41 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
42 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
43 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
44 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
46 ; ABORT: call void asm sideeffect "hlt #257", "{x0}"(i64 %[[A]])
48 ; RECOVER: call void asm sideeffect "hlt #289", "{x0}"(i64 %[[A]])
51 ; CHECK: %[[G:[^ ]*]] = load i16, i16* %a, align 4
52 ; CHECK: ret i16 %[[G]]
55 %b = load i16, i16* %a, align 4
59 define i32 @test_load32(i32* %a) sanitize_hwaddress {
60 ; CHECK-LABEL: @test_load32(
61 ; CHECK: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
62 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
63 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
64 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
65 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
66 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
67 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
68 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
69 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
71 ; ABORT: call void asm sideeffect "hlt #258", "{x0}"(i64 %[[A]])
73 ; RECOVER: call void asm sideeffect "hlt #290", "{x0}"(i64 %[[A]])
76 ; CHECK: %[[G:[^ ]*]] = load i32, i32* %a, align 4
77 ; CHECK: ret i32 %[[G]]
80 %b = load i32, i32* %a, align 4
84 define i64 @test_load64(i64* %a) sanitize_hwaddress {
85 ; CHECK-LABEL: @test_load64(
86 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
87 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
88 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
89 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
90 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
91 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
92 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
93 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
94 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
96 ; ABORT: call void asm sideeffect "hlt #259", "{x0}"(i64 %[[A]])
98 ; RECOVER: call void asm sideeffect "hlt #291", "{x0}"(i64 %[[A]])
101 ; CHECK: %[[G:[^ ]*]] = load i64, i64* %a, align 8
102 ; CHECK: ret i64 %[[G]]
105 %b = load i64, i64* %a, align 8
109 define i128 @test_load128(i128* %a) sanitize_hwaddress {
110 ; CHECK-LABEL: @test_load128(
111 ; CHECK: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
112 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
113 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
114 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
115 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
116 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
117 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
118 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
119 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
121 ; ABORT: call void asm sideeffect "hlt #260", "{x0}"(i64 %[[A]])
123 ; RECOVER: call void asm sideeffect "hlt #292", "{x0}"(i64 %[[A]])
126 ; CHECK: %[[G:[^ ]*]] = load i128, i128* %a, align 16
127 ; CHECK: ret i128 %[[G]]
130 %b = load i128, i128* %a, align 16
134 define i40 @test_load40(i40* %a) sanitize_hwaddress {
135 ; CHECK-LABEL: @test_load40(
136 ; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
137 ; ABORT: call void @__hwasan_load(i64 %[[A]], i64 5)
138 ; RECOVER: call void @__hwasan_load_noabort(i64 %[[A]], i64 5)
139 ; CHECK: %[[B:[^ ]*]] = load i40, i40* %a
140 ; CHECK: ret i40 %[[B]]
143 %b = load i40, i40* %a, align 4
147 define void @test_store8(i8* %a, i8 %b) sanitize_hwaddress {
148 ; CHECK-LABEL: @test_store8(
149 ; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
150 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
151 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
152 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
153 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
154 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
155 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
156 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
157 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
159 ; ABORT: call void asm sideeffect "hlt #272", "{x0}"(i64 %[[A]])
161 ; RECOVER: call void asm sideeffect "hlt #304", "{x0}"(i64 %[[A]])
164 ; CHECK: store i8 %b, i8* %a, align 4
168 store i8 %b, i8* %a, align 4
172 define void @test_store16(i16* %a, i16 %b) sanitize_hwaddress {
173 ; CHECK-LABEL: @test_store16(
174 ; CHECK: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
175 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
176 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
177 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
178 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
179 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
180 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
181 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
182 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
184 ; ABORT: call void asm sideeffect "hlt #273", "{x0}"(i64 %[[A]])
186 ; RECOVER: call void asm sideeffect "hlt #305", "{x0}"(i64 %[[A]])
189 ; CHECK: store i16 %b, i16* %a, align 4
193 store i16 %b, i16* %a, align 4
197 define void @test_store32(i32* %a, i32 %b) sanitize_hwaddress {
198 ; CHECK-LABEL: @test_store32(
199 ; CHECK: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
200 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
201 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
202 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
203 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
204 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
205 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
206 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
207 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
209 ; ABORT: call void asm sideeffect "hlt #274", "{x0}"(i64 %[[A]])
211 ; RECOVER: call void asm sideeffect "hlt #306", "{x0}"(i64 %[[A]])
214 ; CHECK: store i32 %b, i32* %a, align 4
218 store i32 %b, i32* %a, align 4
222 define void @test_store64(i64* %a, i64 %b) sanitize_hwaddress {
223 ; CHECK-LABEL: @test_store64(
224 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
225 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
226 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
227 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
228 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
229 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
230 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
231 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
232 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
234 ; ABORT: call void asm sideeffect "hlt #275", "{x0}"(i64 %[[A]])
236 ; RECOVER: call void asm sideeffect "hlt #307", "{x0}"(i64 %[[A]])
239 ; CHECK: store i64 %b, i64* %a, align 8
243 store i64 %b, i64* %a, align 8
247 define void @test_store128(i128* %a, i128 %b) sanitize_hwaddress {
248 ; CHECK-LABEL: @test_store128(
249 ; CHECK: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
250 ; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
251 ; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
252 ; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
253 ; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
254 ; CHECK: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
255 ; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
256 ; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
257 ; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
259 ; ABORT: call void asm sideeffect "hlt #276", "{x0}"(i64 %[[A]])
261 ; RECOVER: call void asm sideeffect "hlt #308", "{x0}"(i64 %[[A]])
264 ; CHECK: store i128 %b, i128* %a, align 16
268 store i128 %b, i128* %a, align 16
272 define void @test_store40(i40* %a, i40 %b) sanitize_hwaddress {
273 ; CHECK-LABEL: @test_store40(
274 ; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
275 ; ABORT: call void @__hwasan_store(i64 %[[A]], i64 5)
276 ; RECOVER: call void @__hwasan_store_noabort(i64 %[[A]], i64 5)
277 ; CHECK: store i40 %b, i40* %a
281 store i40 %b, i40* %a, align 4
285 define void @test_store_unaligned(i64* %a, i64 %b) sanitize_hwaddress {
286 ; CHECK-LABEL: @test_store_unaligned(
287 ; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
288 ; ABORT: call void @__hwasan_store(i64 %[[A]], i64 8)
289 ; RECOVER: call void @__hwasan_store_noabort(i64 %[[A]], i64 8)
290 ; CHECK: store i64 %b, i64* %a, align 4
294 store i64 %b, i64* %a, align 4
298 define i8 @test_load_noattr(i8* %a) {
299 ; CHECK-LABEL: @test_load_noattr(
301 ; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
302 ; CHECK-NEXT: ret i8 %[[B]]
305 %b = load i8, i8* %a, align 4
309 define i8 @test_load_notmyattr(i8* %a) sanitize_address {
310 ; CHECK-LABEL: @test_load_notmyattr(
312 ; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
313 ; CHECK-NEXT: ret i8 %[[B]]
316 %b = load i8, i8* %a, align 4
320 define i8 @test_load_addrspace(i8 addrspace(256)* %a) sanitize_hwaddress {
321 ; CHECK-LABEL: @test_load_addrspace(
323 ; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8 addrspace(256)* %a
324 ; CHECK-NEXT: ret i8 %[[B]]
327 %b = load i8, i8 addrspace(256)* %a, align 4
331 ; CHECK: declare void @__hwasan_init()
333 ; CHECK: define internal void @hwasan.module_ctor() {
334 ; CHECK-NEXT: call void @__hwasan_init()
335 ; CHECK-NEXT: ret void