xref: /llvm-project/llvm/test/Instrumentation/HWAddressSanitizer/X86/basic.ll (revision bb637396db8705c39ff9800ac0ae5697a746d333)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; Test basic address sanitizer instrumentation.
3; Generic code is covered by ../basic.ll, only the x86_64 specific code is
4; tested here.
5;
6; RUN: opt < %s -passes=hwasan -S | FileCheck %s
7; RUN: opt < %s -passes=hwasan -hwasan-inline-fast-path-checks=0 -S | FileCheck %s --check-prefixes=NOFASTPATH
8; RUN: opt < %s -passes=hwasan -hwasan-inline-fast-path-checks=1 -S | FileCheck %s --check-prefixes=FASTPATH
9; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -S | FileCheck %s  --check-prefixes=ABORT
10; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -S | FileCheck %s  --check-prefixes=RECOVER
11; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-instrument-with-calls=0 -S | FileCheck %s  --check-prefixes=ABORT-INLINE
12; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-instrument-with-calls=0 -S | FileCheck %s  --check-prefixes=RECOVER-INLINE
13
14target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
15target triple = "x86_64-unknown-linux-gnu"
16
17define i8 @test_load8(ptr %a) sanitize_hwaddress {
18; CHECK-LABEL: define i8 @test_load8
19; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
20; CHECK-NEXT:  entry:
21; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
22; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
23; CHECK-NEXT:    call void @__hwasan_load1(i64 [[TMP0]])
24; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
25; CHECK-NEXT:    ret i8 [[B]]
26;
27; NOFASTPATH-LABEL: define i8 @test_load8
28; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
29; NOFASTPATH-NEXT:  entry:
30; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
31; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
32; NOFASTPATH-NEXT:    call void @__hwasan_load1(i64 [[TMP0]])
33; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
34; NOFASTPATH-NEXT:    ret i8 [[B]]
35;
36; FASTPATH-LABEL: define i8 @test_load8
37; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
38; FASTPATH-NEXT:  entry:
39; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
40; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
41; FASTPATH-NEXT:    call void @__hwasan_load1(i64 [[TMP0]])
42; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
43; FASTPATH-NEXT:    ret i8 [[B]]
44;
45; ABORT-LABEL: define i8 @test_load8
46; ABORT-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
47; ABORT-NEXT:  entry:
48; ABORT-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
49; ABORT-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
50; ABORT-NEXT:    call void @__hwasan_load1(i64 [[TMP0]])
51; ABORT-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
52; ABORT-NEXT:    ret i8 [[B]]
53;
54; RECOVER-LABEL: define i8 @test_load8
55; RECOVER-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
56; RECOVER-NEXT:  entry:
57; RECOVER-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
58; RECOVER-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
59; RECOVER-NEXT:    call void @__hwasan_load1_noabort(i64 [[TMP0]])
60; RECOVER-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
61; RECOVER-NEXT:    ret i8 [[B]]
62;
63; ABORT-INLINE-LABEL: define i8 @test_load8
64; ABORT-INLINE-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
65; ABORT-INLINE-NEXT:  entry:
66; ABORT-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
67; ABORT-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
68; ABORT-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
69; ABORT-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
70; ABORT-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
71; ABORT-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
72; ABORT-INLINE-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 57
73; ABORT-INLINE-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
74; ABORT-INLINE-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], -9079256848778919937
75; ABORT-INLINE-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
76; ABORT-INLINE-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
77; ABORT-INLINE-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
78; ABORT-INLINE-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
79; ABORT-INLINE-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP26:%.*]], !prof [[PROF1:![0-9]+]]
80; ABORT-INLINE:       12:
81; ABORT-INLINE-NEXT:    [[TMP13:%.*]] = icmp ugt i8 [[TMP10]], 15
82; ABORT-INLINE-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]], !prof [[PROF1]]
83; ABORT-INLINE:       14:
84; ABORT-INLINE-NEXT:    call void asm sideeffect "int3\0Anopl 64([[RAX:%.*]])", "{rdi}"(i64 [[TMP4]])
85; ABORT-INLINE-NEXT:    unreachable
86; ABORT-INLINE:       15:
87; ABORT-INLINE-NEXT:    [[TMP16:%.*]] = and i64 [[TMP4]], 15
88; ABORT-INLINE-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i8
89; ABORT-INLINE-NEXT:    [[TMP18:%.*]] = add i8 [[TMP17]], 0
90; ABORT-INLINE-NEXT:    [[TMP19:%.*]] = icmp uge i8 [[TMP18]], [[TMP10]]
91; ABORT-INLINE-NEXT:    br i1 [[TMP19]], label [[TMP14]], label [[TMP20:%.*]], !prof [[PROF1]]
92; ABORT-INLINE:       20:
93; ABORT-INLINE-NEXT:    [[TMP21:%.*]] = or i64 [[TMP7]], 15
94; ABORT-INLINE-NEXT:    [[TMP22:%.*]] = inttoptr i64 [[TMP21]] to ptr
95; ABORT-INLINE-NEXT:    [[TMP23:%.*]] = load i8, ptr [[TMP22]], align 1
96; ABORT-INLINE-NEXT:    [[TMP24:%.*]] = icmp ne i8 [[TMP6]], [[TMP23]]
97; ABORT-INLINE-NEXT:    br i1 [[TMP24]], label [[TMP14]], label [[TMP25:%.*]], !prof [[PROF1]]
98; ABORT-INLINE:       25:
99; ABORT-INLINE-NEXT:    br label [[TMP26]]
100; ABORT-INLINE:       26:
101; ABORT-INLINE-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
102; ABORT-INLINE-NEXT:    ret i8 [[B]]
103;
104; RECOVER-INLINE-LABEL: define i8 @test_load8
105; RECOVER-INLINE-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
106; RECOVER-INLINE-NEXT:  entry:
107; RECOVER-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
108; RECOVER-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
109; RECOVER-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
110; RECOVER-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
111; RECOVER-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
112; RECOVER-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
113; RECOVER-INLINE-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 57
114; RECOVER-INLINE-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
115; RECOVER-INLINE-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], -9079256848778919937
116; RECOVER-INLINE-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
117; RECOVER-INLINE-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
118; RECOVER-INLINE-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
119; RECOVER-INLINE-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
120; RECOVER-INLINE-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP26:%.*]], !prof [[PROF1:![0-9]+]]
121; RECOVER-INLINE:       12:
122; RECOVER-INLINE-NEXT:    [[TMP13:%.*]] = icmp ugt i8 [[TMP10]], 15
123; RECOVER-INLINE-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]], !prof [[PROF1]]
124; RECOVER-INLINE:       14:
125; RECOVER-INLINE-NEXT:    call void asm sideeffect "int3\0Anopl 96([[RAX:%.*]])", "{rdi}"(i64 [[TMP4]])
126; RECOVER-INLINE-NEXT:    br label [[TMP25:%.*]]
127; RECOVER-INLINE:       15:
128; RECOVER-INLINE-NEXT:    [[TMP16:%.*]] = and i64 [[TMP4]], 15
129; RECOVER-INLINE-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i8
130; RECOVER-INLINE-NEXT:    [[TMP18:%.*]] = add i8 [[TMP17]], 0
131; RECOVER-INLINE-NEXT:    [[TMP19:%.*]] = icmp uge i8 [[TMP18]], [[TMP10]]
132; RECOVER-INLINE-NEXT:    br i1 [[TMP19]], label [[TMP14]], label [[TMP20:%.*]], !prof [[PROF1]]
133; RECOVER-INLINE:       20:
134; RECOVER-INLINE-NEXT:    [[TMP21:%.*]] = or i64 [[TMP7]], 15
135; RECOVER-INLINE-NEXT:    [[TMP22:%.*]] = inttoptr i64 [[TMP21]] to ptr
136; RECOVER-INLINE-NEXT:    [[TMP23:%.*]] = load i8, ptr [[TMP22]], align 1
137; RECOVER-INLINE-NEXT:    [[TMP24:%.*]] = icmp ne i8 [[TMP6]], [[TMP23]]
138; RECOVER-INLINE-NEXT:    br i1 [[TMP24]], label [[TMP14]], label [[TMP25]], !prof [[PROF1]]
139; RECOVER-INLINE:       25:
140; RECOVER-INLINE-NEXT:    br label [[TMP26]]
141; RECOVER-INLINE:       26:
142; RECOVER-INLINE-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
143; RECOVER-INLINE-NEXT:    ret i8 [[B]]
144;
145entry:
146  %b = load i8, ptr %a, align 4
147  ret i8 %b
148}
149
150define i40 @test_load40(ptr %a) sanitize_hwaddress {
151; CHECK-LABEL: define i40 @test_load40
152; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
153; CHECK-NEXT:  entry:
154; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
155; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
156; CHECK-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
157; CHECK-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
158; CHECK-NEXT:    ret i40 [[B]]
159;
160; NOFASTPATH-LABEL: define i40 @test_load40
161; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
162; NOFASTPATH-NEXT:  entry:
163; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
164; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
165; NOFASTPATH-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
166; NOFASTPATH-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
167; NOFASTPATH-NEXT:    ret i40 [[B]]
168;
169; FASTPATH-LABEL: define i40 @test_load40
170; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
171; FASTPATH-NEXT:  entry:
172; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
173; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
174; FASTPATH-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
175; FASTPATH-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
176; FASTPATH-NEXT:    ret i40 [[B]]
177;
178; ABORT-LABEL: define i40 @test_load40
179; ABORT-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
180; ABORT-NEXT:  entry:
181; ABORT-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
182; ABORT-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
183; ABORT-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
184; ABORT-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
185; ABORT-NEXT:    ret i40 [[B]]
186;
187; RECOVER-LABEL: define i40 @test_load40
188; RECOVER-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
189; RECOVER-NEXT:  entry:
190; RECOVER-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
191; RECOVER-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
192; RECOVER-NEXT:    call void @__hwasan_loadN_noabort(i64 [[TMP0]], i64 5)
193; RECOVER-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
194; RECOVER-NEXT:    ret i40 [[B]]
195;
196; ABORT-INLINE-LABEL: define i40 @test_load40
197; ABORT-INLINE-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
198; ABORT-INLINE-NEXT:  entry:
199; ABORT-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
200; ABORT-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
201; ABORT-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
202; ABORT-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
203; ABORT-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
204; ABORT-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
205; ABORT-INLINE-NEXT:    call void @__hwasan_loadN(i64 [[TMP4]], i64 5)
206; ABORT-INLINE-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
207; ABORT-INLINE-NEXT:    ret i40 [[B]]
208;
209; RECOVER-INLINE-LABEL: define i40 @test_load40
210; RECOVER-INLINE-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
211; RECOVER-INLINE-NEXT:  entry:
212; RECOVER-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
213; RECOVER-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
214; RECOVER-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
215; RECOVER-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
216; RECOVER-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
217; RECOVER-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
218; RECOVER-INLINE-NEXT:    call void @__hwasan_loadN_noabort(i64 [[TMP4]], i64 5)
219; RECOVER-INLINE-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
220; RECOVER-INLINE-NEXT:    ret i40 [[B]]
221;
222entry:
223  %b = load i40, ptr %a, align 4
224  ret i40 %b
225}
226
227define void @test_store8(ptr %a, i8 %b) sanitize_hwaddress {
228; CHECK-LABEL: define void @test_store8
229; CHECK-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
230; CHECK-NEXT:  entry:
231; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
232; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
233; CHECK-NEXT:    call void @__hwasan_store1(i64 [[TMP0]])
234; CHECK-NEXT:    store i8 [[B]], ptr [[A]], align 4
235; CHECK-NEXT:    ret void
236;
237; NOFASTPATH-LABEL: define void @test_store8
238; NOFASTPATH-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
239; NOFASTPATH-NEXT:  entry:
240; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
241; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
242; NOFASTPATH-NEXT:    call void @__hwasan_store1(i64 [[TMP0]])
243; NOFASTPATH-NEXT:    store i8 [[B]], ptr [[A]], align 4
244; NOFASTPATH-NEXT:    ret void
245;
246; FASTPATH-LABEL: define void @test_store8
247; FASTPATH-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
248; FASTPATH-NEXT:  entry:
249; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
250; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
251; FASTPATH-NEXT:    call void @__hwasan_store1(i64 [[TMP0]])
252; FASTPATH-NEXT:    store i8 [[B]], ptr [[A]], align 4
253; FASTPATH-NEXT:    ret void
254;
255; ABORT-LABEL: define void @test_store8
256; ABORT-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
257; ABORT-NEXT:  entry:
258; ABORT-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
259; ABORT-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
260; ABORT-NEXT:    call void @__hwasan_store1(i64 [[TMP0]])
261; ABORT-NEXT:    store i8 [[B]], ptr [[A]], align 4
262; ABORT-NEXT:    ret void
263;
264; RECOVER-LABEL: define void @test_store8
265; RECOVER-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
266; RECOVER-NEXT:  entry:
267; RECOVER-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
268; RECOVER-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
269; RECOVER-NEXT:    call void @__hwasan_store1_noabort(i64 [[TMP0]])
270; RECOVER-NEXT:    store i8 [[B]], ptr [[A]], align 4
271; RECOVER-NEXT:    ret void
272;
273; ABORT-INLINE-LABEL: define void @test_store8
274; ABORT-INLINE-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
275; ABORT-INLINE-NEXT:  entry:
276; ABORT-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
277; ABORT-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
278; ABORT-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
279; ABORT-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
280; ABORT-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
281; ABORT-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
282; ABORT-INLINE-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 57
283; ABORT-INLINE-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
284; ABORT-INLINE-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], -9079256848778919937
285; ABORT-INLINE-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
286; ABORT-INLINE-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
287; ABORT-INLINE-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
288; ABORT-INLINE-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
289; ABORT-INLINE-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP26:%.*]], !prof [[PROF1]]
290; ABORT-INLINE:       12:
291; ABORT-INLINE-NEXT:    [[TMP13:%.*]] = icmp ugt i8 [[TMP10]], 15
292; ABORT-INLINE-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]], !prof [[PROF1]]
293; ABORT-INLINE:       14:
294; ABORT-INLINE-NEXT:    call void asm sideeffect "int3\0Anopl 80([[RAX:%.*]])", "{rdi}"(i64 [[TMP4]])
295; ABORT-INLINE-NEXT:    unreachable
296; ABORT-INLINE:       15:
297; ABORT-INLINE-NEXT:    [[TMP16:%.*]] = and i64 [[TMP4]], 15
298; ABORT-INLINE-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i8
299; ABORT-INLINE-NEXT:    [[TMP18:%.*]] = add i8 [[TMP17]], 0
300; ABORT-INLINE-NEXT:    [[TMP19:%.*]] = icmp uge i8 [[TMP18]], [[TMP10]]
301; ABORT-INLINE-NEXT:    br i1 [[TMP19]], label [[TMP14]], label [[TMP20:%.*]], !prof [[PROF1]]
302; ABORT-INLINE:       20:
303; ABORT-INLINE-NEXT:    [[TMP21:%.*]] = or i64 [[TMP7]], 15
304; ABORT-INLINE-NEXT:    [[TMP22:%.*]] = inttoptr i64 [[TMP21]] to ptr
305; ABORT-INLINE-NEXT:    [[TMP23:%.*]] = load i8, ptr [[TMP22]], align 1
306; ABORT-INLINE-NEXT:    [[TMP24:%.*]] = icmp ne i8 [[TMP6]], [[TMP23]]
307; ABORT-INLINE-NEXT:    br i1 [[TMP24]], label [[TMP14]], label [[TMP25:%.*]], !prof [[PROF1]]
308; ABORT-INLINE:       25:
309; ABORT-INLINE-NEXT:    br label [[TMP26]]
310; ABORT-INLINE:       26:
311; ABORT-INLINE-NEXT:    store i8 [[B]], ptr [[A]], align 4
312; ABORT-INLINE-NEXT:    ret void
313;
314; RECOVER-INLINE-LABEL: define void @test_store8
315; RECOVER-INLINE-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
316; RECOVER-INLINE-NEXT:  entry:
317; RECOVER-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
318; RECOVER-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
319; RECOVER-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
320; RECOVER-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
321; RECOVER-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
322; RECOVER-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
323; RECOVER-INLINE-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 57
324; RECOVER-INLINE-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
325; RECOVER-INLINE-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], -9079256848778919937
326; RECOVER-INLINE-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
327; RECOVER-INLINE-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
328; RECOVER-INLINE-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
329; RECOVER-INLINE-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
330; RECOVER-INLINE-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP26:%.*]], !prof [[PROF1]]
331; RECOVER-INLINE:       12:
332; RECOVER-INLINE-NEXT:    [[TMP13:%.*]] = icmp ugt i8 [[TMP10]], 15
333; RECOVER-INLINE-NEXT:    br i1 [[TMP13]], label [[TMP14:%.*]], label [[TMP15:%.*]], !prof [[PROF1]]
334; RECOVER-INLINE:       14:
335; RECOVER-INLINE-NEXT:    call void asm sideeffect "int3\0Anopl 112([[RAX:%.*]])", "{rdi}"(i64 [[TMP4]])
336; RECOVER-INLINE-NEXT:    br label [[TMP25:%.*]]
337; RECOVER-INLINE:       15:
338; RECOVER-INLINE-NEXT:    [[TMP16:%.*]] = and i64 [[TMP4]], 15
339; RECOVER-INLINE-NEXT:    [[TMP17:%.*]] = trunc i64 [[TMP16]] to i8
340; RECOVER-INLINE-NEXT:    [[TMP18:%.*]] = add i8 [[TMP17]], 0
341; RECOVER-INLINE-NEXT:    [[TMP19:%.*]] = icmp uge i8 [[TMP18]], [[TMP10]]
342; RECOVER-INLINE-NEXT:    br i1 [[TMP19]], label [[TMP14]], label [[TMP20:%.*]], !prof [[PROF1]]
343; RECOVER-INLINE:       20:
344; RECOVER-INLINE-NEXT:    [[TMP21:%.*]] = or i64 [[TMP7]], 15
345; RECOVER-INLINE-NEXT:    [[TMP22:%.*]] = inttoptr i64 [[TMP21]] to ptr
346; RECOVER-INLINE-NEXT:    [[TMP23:%.*]] = load i8, ptr [[TMP22]], align 1
347; RECOVER-INLINE-NEXT:    [[TMP24:%.*]] = icmp ne i8 [[TMP6]], [[TMP23]]
348; RECOVER-INLINE-NEXT:    br i1 [[TMP24]], label [[TMP14]], label [[TMP25]], !prof [[PROF1]]
349; RECOVER-INLINE:       25:
350; RECOVER-INLINE-NEXT:    br label [[TMP26]]
351; RECOVER-INLINE:       26:
352; RECOVER-INLINE-NEXT:    store i8 [[B]], ptr [[A]], align 4
353; RECOVER-INLINE-NEXT:    ret void
354;
355entry:
356  store i8 %b, ptr %a, align 4
357  ret void
358}
359
360define void @test_store40(ptr %a, i40 %b) sanitize_hwaddress {
361; CHECK-LABEL: define void @test_store40
362; CHECK-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
363; CHECK-NEXT:  entry:
364; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
365; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
366; CHECK-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
367; CHECK-NEXT:    store i40 [[B]], ptr [[A]], align 4
368; CHECK-NEXT:    ret void
369;
370; NOFASTPATH-LABEL: define void @test_store40
371; NOFASTPATH-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
372; NOFASTPATH-NEXT:  entry:
373; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
374; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
375; NOFASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
376; NOFASTPATH-NEXT:    store i40 [[B]], ptr [[A]], align 4
377; NOFASTPATH-NEXT:    ret void
378;
379; FASTPATH-LABEL: define void @test_store40
380; FASTPATH-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
381; FASTPATH-NEXT:  entry:
382; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
383; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
384; FASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
385; FASTPATH-NEXT:    store i40 [[B]], ptr [[A]], align 4
386; FASTPATH-NEXT:    ret void
387;
388; ABORT-LABEL: define void @test_store40
389; ABORT-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
390; ABORT-NEXT:  entry:
391; ABORT-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
392; ABORT-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
393; ABORT-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
394; ABORT-NEXT:    store i40 [[B]], ptr [[A]], align 4
395; ABORT-NEXT:    ret void
396;
397; RECOVER-LABEL: define void @test_store40
398; RECOVER-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
399; RECOVER-NEXT:  entry:
400; RECOVER-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
401; RECOVER-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
402; RECOVER-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 5)
403; RECOVER-NEXT:    store i40 [[B]], ptr [[A]], align 4
404; RECOVER-NEXT:    ret void
405;
406; ABORT-INLINE-LABEL: define void @test_store40
407; ABORT-INLINE-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
408; ABORT-INLINE-NEXT:  entry:
409; ABORT-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
410; ABORT-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
411; ABORT-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
412; ABORT-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
413; ABORT-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
414; ABORT-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
415; ABORT-INLINE-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 5)
416; ABORT-INLINE-NEXT:    store i40 [[B]], ptr [[A]], align 4
417; ABORT-INLINE-NEXT:    ret void
418;
419; RECOVER-INLINE-LABEL: define void @test_store40
420; RECOVER-INLINE-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
421; RECOVER-INLINE-NEXT:  entry:
422; RECOVER-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
423; RECOVER-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
424; RECOVER-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
425; RECOVER-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
426; RECOVER-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
427; RECOVER-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
428; RECOVER-INLINE-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP4]], i64 5)
429; RECOVER-INLINE-NEXT:    store i40 [[B]], ptr [[A]], align 4
430; RECOVER-INLINE-NEXT:    ret void
431;
432entry:
433  store i40 %b, ptr %a, align 4
434  ret void
435}
436
437define void @test_store_unaligned(ptr %a, i64 %b) sanitize_hwaddress {
438; CHECK-LABEL: define void @test_store_unaligned
439; CHECK-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
440; CHECK-NEXT:  entry:
441; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
442; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
443; CHECK-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
444; CHECK-NEXT:    store i64 [[B]], ptr [[A]], align 4
445; CHECK-NEXT:    ret void
446;
447; NOFASTPATH-LABEL: define void @test_store_unaligned
448; NOFASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
449; NOFASTPATH-NEXT:  entry:
450; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
451; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
452; NOFASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
453; NOFASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 4
454; NOFASTPATH-NEXT:    ret void
455;
456; FASTPATH-LABEL: define void @test_store_unaligned
457; FASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
458; FASTPATH-NEXT:  entry:
459; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
460; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
461; FASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
462; FASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 4
463; FASTPATH-NEXT:    ret void
464;
465; ABORT-LABEL: define void @test_store_unaligned
466; ABORT-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
467; ABORT-NEXT:  entry:
468; ABORT-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
469; ABORT-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
470; ABORT-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
471; ABORT-NEXT:    store i64 [[B]], ptr [[A]], align 4
472; ABORT-NEXT:    ret void
473;
474; RECOVER-LABEL: define void @test_store_unaligned
475; RECOVER-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
476; RECOVER-NEXT:  entry:
477; RECOVER-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
478; RECOVER-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
479; RECOVER-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 8)
480; RECOVER-NEXT:    store i64 [[B]], ptr [[A]], align 4
481; RECOVER-NEXT:    ret void
482;
483; ABORT-INLINE-LABEL: define void @test_store_unaligned
484; ABORT-INLINE-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
485; ABORT-INLINE-NEXT:  entry:
486; ABORT-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
487; ABORT-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
488; ABORT-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
489; ABORT-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
490; ABORT-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
491; ABORT-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
492; ABORT-INLINE-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 8)
493; ABORT-INLINE-NEXT:    store i64 [[B]], ptr [[A]], align 4
494; ABORT-INLINE-NEXT:    ret void
495;
496; RECOVER-INLINE-LABEL: define void @test_store_unaligned
497; RECOVER-INLINE-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
498; RECOVER-INLINE-NEXT:  entry:
499; RECOVER-INLINE-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
500; RECOVER-INLINE-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], -9079256848778919937
501; RECOVER-INLINE-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
502; RECOVER-INLINE-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
503; RECOVER-INLINE-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
504; RECOVER-INLINE-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
505; RECOVER-INLINE-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP4]], i64 8)
506; RECOVER-INLINE-NEXT:    store i64 [[B]], ptr [[A]], align 4
507; RECOVER-INLINE-NEXT:    ret void
508;
509entry:
510  store i64 %b, ptr %a, align 4
511  ret void
512}
513