1; Test basic address sanitizer instrumentation.
2;
3; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT
4; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-with-ifunc=1 -hwasan-with-tls=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-DYNAMIC-SHADOW
5; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT
6; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,RECOVER-ZERO-BASED-SHADOW
7
8; CHECK: @llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @hwasan.module_ctor to i8*)]
9; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @hwasan.module_ctor, i8* bitcast (void ()* @hwasan.module_ctor to i8*) }]
10
11target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
12target triple = "aarch64--linux-android10000"
13
14define i8 @test_load8(i8* %a) sanitize_hwaddress {
15; CHECK-LABEL: @test_load8(
16; RECOVER: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
17; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
18; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
19; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
20; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
21; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
22; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
23; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
24; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
25; RECOVER: br i1 %[[F]], label %[[MISMATCH:[0-9]*]], label %[[CONT:[0-9]*]], !prof {{.*}}
26
27; RECOVER: [[MISMATCH]]:
28; RECOVER: %[[NOTSHORT:[^ ]*]] = icmp ugt i8 %[[MEMTAG]], 15
29; RECOVER: br i1 %[[NOTSHORT]], label %[[FAIL:[0-9]*]], label %[[SHORT:[0-9]*]], !prof {{.*}}
30
31; RECOVER: [[FAIL]]:
32; RECOVER: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]])
33; RECOVER: br label
34
35; RECOVER: [[SHORT]]:
36; RECOVER: %[[LOWBITS:[^ ]*]] = and i64 %[[A]], 15
37; RECOVER: %[[LOWBITS_I8:[^ ]*]] = trunc i64 %[[LOWBITS]] to i8
38; RECOVER: %[[LAST:[^ ]*]] = add i8 %[[LOWBITS_I8]], 0
39; RECOVER: %[[OOB:[^ ]*]] = icmp uge i8 %[[LAST]], %[[MEMTAG]]
40; RECOVER: br i1 %[[OOB]], label %[[FAIL]], label %[[INBOUNDS:[0-9]*]], !prof {{.*}}
41
42; RECOVER: [[INBOUNDS]]:
43; RECOVER: %[[EOG_ADDR:[^ ]*]] = or i64 %[[C]], 15
44; RECOVER: %[[EOG_PTR:[^ ]*]] = inttoptr i64 %[[EOG_ADDR]] to i8*
45; RECOVER: %[[EOGTAG:[^ ]*]] = load i8, i8* %[[EOG_PTR]]
46; RECOVER: %[[EOG_MISMATCH:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[EOGTAG]]
47; RECOVER: br i1 %[[EOG_MISMATCH]], label %[[FAIL]], label %[[CONT1:[0-9]*]], !prof {{.*}}
48
49; RECOVER: [[CONT1]]:
50; RECOVER: br label %[[CONT]]
51
52; RECOVER: [[CONT]]:
53
54; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %a, i32 0)
55
56; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4
57; CHECK: ret i8 %[[G]]
58
59entry:
60  %b = load i8, i8* %a, align 4
61  ret i8 %b
62}
63
64define i16 @test_load16(i16* %a) sanitize_hwaddress {
65; CHECK-LABEL: @test_load16(
66; RECOVER: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
67; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
68; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
69; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
70; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
71; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
72; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
73; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
74; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
75; RECOVER: br i1 %[[F]], label %[[MISMATCH:[0-9]*]], label %[[CONT:[0-9]*]], !prof {{.*}}
76
77; RECOVER: [[MISMATCH]]:
78; RECOVER: %[[NOTSHORT:[^ ]*]] = icmp ugt i8 %[[MEMTAG]], 15
79; RECOVER: br i1 %[[NOTSHORT]], label %[[FAIL:[0-9]*]], label %[[SHORT:[0-9]*]], !prof {{.*}}
80
81; RECOVER: [[FAIL]]:
82; RECOVER: call void asm sideeffect "brk #2337", "{x0}"(i64 %[[A]])
83; RECOVER: br label
84
85; RECOVER: [[SHORT]]:
86; RECOVER: %[[LOWBITS:[^ ]*]] = and i64 %[[A]], 15
87; RECOVER: %[[LOWBITS_I8:[^ ]*]] = trunc i64 %[[LOWBITS]] to i8
88; RECOVER: %[[LAST:[^ ]*]] = add i8 %[[LOWBITS_I8]], 1
89; RECOVER: %[[OOB:[^ ]*]] = icmp uge i8 %[[LAST]], %[[MEMTAG]]
90; RECOVER: br i1 %[[OOB]], label %[[FAIL]], label %[[INBOUNDS:[0-9]*]], !prof {{.*}}
91
92; RECOVER: [[INBOUNDS]]:
93; RECOVER: %[[EOG_ADDR:[^ ]*]] = or i64 %[[C]], 15
94; RECOVER: %[[EOG_PTR:[^ ]*]] = inttoptr i64 %[[EOG_ADDR]] to i8*
95; RECOVER: %[[EOGTAG:[^ ]*]] = load i8, i8* %[[EOG_PTR]]
96; RECOVER: %[[EOG_MISMATCH:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[EOGTAG]]
97; RECOVER: br i1 %[[EOG_MISMATCH]], label %[[FAIL]], label %[[CONT1:[0-9]*]], !prof {{.*}}
98
99; RECOVER: [[CONT1]]:
100; RECOVER: br label %[[CONT]]
101
102; RECOVER: [[CONT]]:
103
104; ABORT: %[[A:[^ ]*]] = bitcast i16* %a to i8*
105; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 1)
106
107; CHECK: %[[G:[^ ]*]] = load i16, i16* %a, align 4
108; CHECK: ret i16 %[[G]]
109
110entry:
111  %b = load i16, i16* %a, align 4
112  ret i16 %b
113}
114
115define i32 @test_load32(i32* %a) sanitize_hwaddress {
116; CHECK-LABEL: @test_load32(
117; RECOVER: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
118; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
119; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
120; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
121; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
122; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
123; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
124; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
125; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
126; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
127
128; RECOVER: call void asm sideeffect "brk #2338", "{x0}"(i64 %[[A]])
129; RECOVER: br label
130
131; ABORT: %[[A:[^ ]*]] = bitcast i32* %a to i8*
132; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 2)
133
134; CHECK: %[[G:[^ ]*]] = load i32, i32* %a, align 4
135; CHECK: ret i32 %[[G]]
136
137entry:
138  %b = load i32, i32* %a, align 4
139  ret i32 %b
140}
141
142define i64 @test_load64(i64* %a) sanitize_hwaddress {
143; CHECK-LABEL: @test_load64(
144; RECOVER: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
145; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
146; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
147; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
148; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
149; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
150; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
151; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
152; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
153; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
154
155; RECOVER: call void asm sideeffect "brk #2339", "{x0}"(i64 %[[A]])
156; RECOVER: br label
157
158; ABORT: %[[A:[^ ]*]] = bitcast i64* %a to i8*
159; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 3)
160
161; CHECK: %[[G:[^ ]*]] = load i64, i64* %a, align 8
162; CHECK: ret i64 %[[G]]
163
164entry:
165  %b = load i64, i64* %a, align 8
166  ret i64 %b
167}
168
169define i128 @test_load128(i128* %a) sanitize_hwaddress {
170; CHECK-LABEL: @test_load128(
171; RECOVER: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
172; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
173; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
174; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
175; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
176; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
177; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
178; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
179; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
180; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
181
182; RECOVER: call void asm sideeffect "brk #2340", "{x0}"(i64 %[[A]])
183; RECOVER: br label
184
185; ABORT: %[[A:[^ ]*]] = bitcast i128* %a to i8*
186; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 4)
187
188; CHECK: %[[G:[^ ]*]] = load i128, i128* %a, align 16
189; CHECK: ret i128 %[[G]]
190
191entry:
192  %b = load i128, i128* %a, align 16
193  ret i128 %b
194}
195
196define i40 @test_load40(i40* %a) sanitize_hwaddress {
197; CHECK-LABEL: @test_load40(
198; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
199; ABORT: call void @__hwasan_loadN(i64 %[[A]], i64 5)
200; RECOVER: call void @__hwasan_loadN_noabort(i64 %[[A]], i64 5)
201; CHECK: %[[B:[^ ]*]] = load i40, i40* %a
202; CHECK: ret i40 %[[B]]
203
204entry:
205  %b = load i40, i40* %a, align 4
206  ret i40 %b
207}
208
209define void @test_store8(i8* %a, i8 %b) sanitize_hwaddress {
210; CHECK-LABEL: @test_store8(
211; RECOVER: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
212; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
213; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
214; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
215; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
216; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
217; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
218; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
219; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
220; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
221
222; RECOVER: call void asm sideeffect "brk #2352", "{x0}"(i64 %[[A]])
223; RECOVER: br label
224
225; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %a, i32 16)
226
227; CHECK: store i8 %b, i8* %a, align 4
228; CHECK: ret void
229
230entry:
231  store i8 %b, i8* %a, align 4
232  ret void
233}
234
235define void @test_store16(i16* %a, i16 %b) sanitize_hwaddress {
236; CHECK-LABEL: @test_store16(
237; RECOVER: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
238; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
239; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
240; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
241; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
242; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
243; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
244; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
245; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
246; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
247
248; RECOVER: call void asm sideeffect "brk #2353", "{x0}"(i64 %[[A]])
249; RECOVER: br label
250
251; ABORT: %[[A:[^ ]*]] = bitcast i16* %a to i8*
252; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 17)
253
254; CHECK: store i16 %b, i16* %a, align 4
255; CHECK: ret void
256
257entry:
258  store i16 %b, i16* %a, align 4
259  ret void
260}
261
262define void @test_store32(i32* %a, i32 %b) sanitize_hwaddress {
263; CHECK-LABEL: @test_store32(
264; RECOVER: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
265; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
266; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
267; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
268; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
269; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
270; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
271; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
272; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
273; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
274
275; RECOVER: call void asm sideeffect "brk #2354", "{x0}"(i64 %[[A]])
276; RECOVER: br label
277
278; ABORT: %[[A:[^ ]*]] = bitcast i32* %a to i8*
279; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 18)
280
281; CHECK: store i32 %b, i32* %a, align 4
282; CHECK: ret void
283
284entry:
285  store i32 %b, i32* %a, align 4
286  ret void
287}
288
289define void @test_store64(i64* %a, i64 %b) sanitize_hwaddress {
290; CHECK-LABEL: @test_store64(
291; RECOVER: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
292; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
293; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
294; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
295; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
296; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
297; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
298; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
299; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
300; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
301
302; RECOVER: call void asm sideeffect "brk #2355", "{x0}"(i64 %[[A]])
303; RECOVER: br label
304
305; ABORT: %[[A:[^ ]*]] = bitcast i64* %a to i8*
306; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 19)
307
308; CHECK: store i64 %b, i64* %a, align 8
309; CHECK: ret void
310
311entry:
312  store i64 %b, i64* %a, align 8
313  ret void
314}
315
316define void @test_store128(i128* %a, i128 %b) sanitize_hwaddress {
317; CHECK-LABEL: @test_store128(
318; RECOVER: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
319; RECOVER: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
320; RECOVER: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
321; RECOVER: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
322; RECOVER: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
323; RECOVER-DYNAMIC-SHADOW: %[[E:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %4
324; RECOVER-ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
325; RECOVER: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
326; RECOVER: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
327; RECOVER: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
328
329; RECOVER: call void asm sideeffect "brk #2356", "{x0}"(i64 %[[A]])
330; RECOVER: br label
331
332; ABORT: %[[A:[^ ]*]] = bitcast i128* %a to i8*
333; ABORT: call void @llvm.hwasan.check.memaccess.shortgranules(i8* %.hwasan.shadow, i8* %[[A]], i32 20)
334
335; CHECK: store i128 %b, i128* %a, align 16
336; CHECK: ret void
337
338entry:
339  store i128 %b, i128* %a, align 16
340  ret void
341}
342
343define void @test_store40(i40* %a, i40 %b) sanitize_hwaddress {
344; CHECK-LABEL: @test_store40(
345; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
346; ABORT: call void @__hwasan_storeN(i64 %[[A]], i64 5)
347; RECOVER: call void @__hwasan_storeN_noabort(i64 %[[A]], i64 5)
348; CHECK: store i40 %b, i40* %a
349; CHECK: ret void
350
351entry:
352  store i40 %b, i40* %a, align 4
353  ret void
354}
355
356define void @test_store_unaligned(i64* %a, i64 %b) sanitize_hwaddress {
357; CHECK-LABEL: @test_store_unaligned(
358; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
359; ABORT: call void @__hwasan_storeN(i64 %[[A]], i64 8)
360; RECOVER: call void @__hwasan_storeN_noabort(i64 %[[A]], i64 8)
361; CHECK: store i64 %b, i64* %a, align 4
362; CHECK: ret void
363
364entry:
365  store i64 %b, i64* %a, align 4
366  ret void
367}
368
369define i8 @test_load_noattr(i8* %a) {
370; CHECK-LABEL: @test_load_noattr(
371; CHECK-NEXT: entry:
372; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
373; CHECK-NEXT: ret i8 %[[B]]
374
375entry:
376  %b = load i8, i8* %a, align 4
377  ret i8 %b
378}
379
380define i8 @test_load_notmyattr(i8* %a) sanitize_address {
381; CHECK-LABEL: @test_load_notmyattr(
382; CHECK-NEXT: entry:
383; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
384; CHECK-NEXT: ret i8 %[[B]]
385
386entry:
387  %b = load i8, i8* %a, align 4
388  ret i8 %b
389}
390
391define i8 @test_load_addrspace(i8 addrspace(256)* %a) sanitize_hwaddress {
392; CHECK-LABEL: @test_load_addrspace(
393; CHECK-NEXT: entry:
394; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8 addrspace(256)* %a
395; CHECK-NEXT: ret i8 %[[B]]
396
397entry:
398  %b = load i8, i8 addrspace(256)* %a, align 4
399  ret i8 %b
400}
401
402; CHECK: declare void @__hwasan_init()
403
404; CHECK:      define internal void @hwasan.module_ctor() #[[#ATTR:]] comdat {
405; CHECK-NEXT:   call void @__hwasan_init()
406; CHECK-NEXT:   ret void
407; CHECK-NEXT: }
408
409; CHECK:      attributes #[[#ATTR]] = { nounwind }
410