xref: /llvm-project/llvm/test/Instrumentation/HWAddressSanitizer/basic.ll (revision 0673642cab6b6a9eec20d4ea4ee6bc46db47e04c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; Test basic address sanitizer instrumentation.
3;
4; RUN: opt < %s -passes=hwasan -S | FileCheck %s
5; RUN: opt < %s -passes=hwasan -hwasan-inline-fast-path-checks=0 -S | FileCheck %s --check-prefixes=NOFASTPATH
6; RUN: opt < %s -passes=hwasan -hwasan-inline-fast-path-checks=1 -S | FileCheck %s --check-prefixes=FASTPATH
7; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-mapping-offset-dynamic=ifunc -S | FileCheck %s --check-prefixes=ABORT-DYNAMIC-SHADOW
8; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-mapping-offset-dynamic=ifunc -S | FileCheck %s --check-prefixes=RECOVER-DYNAMIC-SHADOW
9; RUN: opt < %s -passes=hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=ABORT-ZERO-BASED-SHADOW
10; RUN: opt < %s -passes=hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=RECOVER-ZERO-BASED-SHADOW
11
12
13target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
14target triple = "aarch64--linux-android10000"
15
16define i8 @test_load8(ptr %a) sanitize_hwaddress {
17; CHECK-LABEL: define i8 @test_load8
18; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
19; CHECK-NEXT:  entry:
20; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
21; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 0)
22; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
23; CHECK-NEXT:    ret i8 [[B]]
24;
25; NOFASTPATH-LABEL: define i8 @test_load8
26; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
27; NOFASTPATH-NEXT:  entry:
28; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
29; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 0)
30; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
31; NOFASTPATH-NEXT:    ret i8 [[B]]
32;
33; FASTPATH-LABEL: define i8 @test_load8
34; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
35; FASTPATH-NEXT:  entry:
36; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
37; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
38; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
39; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
40; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
41; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
42; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
43; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
44; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
45; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2:![0-9]+]]
46; FASTPATH:       8:
47; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 0)
48; FASTPATH-NEXT:    br label [[TMP9]]
49; FASTPATH:       9:
50; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
51; FASTPATH-NEXT:    ret i8 [[B]]
52;
53; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load8
54; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
55; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
56; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
57; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 0)
58; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
59; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
60;
61; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load8
62; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
63; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
64; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
65; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
66; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
67; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
68; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
69; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
70; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
71; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
72; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
73; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2:![0-9]+]]
74; RECOVER-DYNAMIC-SHADOW:       8:
75; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
76; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
77; RECOVER-DYNAMIC-SHADOW:       10:
78; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2336", "{x0}"(i64 [[TMP0]])
79; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
80; RECOVER-DYNAMIC-SHADOW:       11:
81; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
82; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
83; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
84; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
85; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
86; RECOVER-DYNAMIC-SHADOW:       16:
87; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
88; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
89; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
90; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
91; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
92; RECOVER-DYNAMIC-SHADOW:       21:
93; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
94; RECOVER-DYNAMIC-SHADOW:       22:
95; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
96; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
97;
98; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load8
99; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
100; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
101; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
102; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 0, i64 0)
103; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
104; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
105;
106; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load8
107; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
108; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
109; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
110; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
111; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
112; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
113; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
114; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
115; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
116; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
117; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
118; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2:![0-9]+]]
119; RECOVER-ZERO-BASED-SHADOW:       8:
120; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
121; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
122; RECOVER-ZERO-BASED-SHADOW:       10:
123; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2336", "{x0}"(i64 [[TMP0]])
124; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
125; RECOVER-ZERO-BASED-SHADOW:       11:
126; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
127; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
128; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
129; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
130; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
131; RECOVER-ZERO-BASED-SHADOW:       16:
132; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
133; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
134; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
135; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
136; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
137; RECOVER-ZERO-BASED-SHADOW:       21:
138; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
139; RECOVER-ZERO-BASED-SHADOW:       22:
140; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
141; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
142;
143entry:
144  %b = load i8, ptr %a, align 4
145  ret i8 %b
146}
147
148define i16 @test_load16(ptr %a) sanitize_hwaddress {
149; CHECK-LABEL: define i16 @test_load16
150; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
151; CHECK-NEXT:  entry:
152; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
153; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 1)
154; CHECK-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
155; CHECK-NEXT:    ret i16 [[B]]
156;
157; NOFASTPATH-LABEL: define i16 @test_load16
158; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
159; NOFASTPATH-NEXT:  entry:
160; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
161; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 1)
162; NOFASTPATH-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
163; NOFASTPATH-NEXT:    ret i16 [[B]]
164;
165; FASTPATH-LABEL: define i16 @test_load16
166; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
167; FASTPATH-NEXT:  entry:
168; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
169; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
170; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
171; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
172; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
173; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
174; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
175; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
176; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
177; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
178; FASTPATH:       8:
179; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 1)
180; FASTPATH-NEXT:    br label [[TMP9]]
181; FASTPATH:       9:
182; FASTPATH-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
183; FASTPATH-NEXT:    ret i16 [[B]]
184;
185; ABORT-DYNAMIC-SHADOW-LABEL: define i16 @test_load16
186; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
187; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
188; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
189; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 1)
190; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
191; ABORT-DYNAMIC-SHADOW-NEXT:    ret i16 [[B]]
192;
193; RECOVER-DYNAMIC-SHADOW-LABEL: define i16 @test_load16
194; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
195; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
196; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
197; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
198; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
199; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
200; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
201; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
202; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
203; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
204; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
205; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
206; RECOVER-DYNAMIC-SHADOW:       8:
207; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
208; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
209; RECOVER-DYNAMIC-SHADOW:       10:
210; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2337", "{x0}"(i64 [[TMP0]])
211; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
212; RECOVER-DYNAMIC-SHADOW:       11:
213; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
214; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
215; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
216; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
217; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
218; RECOVER-DYNAMIC-SHADOW:       16:
219; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
220; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
221; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
222; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
223; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
224; RECOVER-DYNAMIC-SHADOW:       21:
225; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
226; RECOVER-DYNAMIC-SHADOW:       22:
227; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
228; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i16 [[B]]
229;
230; ABORT-ZERO-BASED-SHADOW-LABEL: define i16 @test_load16
231; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
232; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
233; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
234; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 1, i64 0)
235; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
236; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i16 [[B]]
237;
238; RECOVER-ZERO-BASED-SHADOW-LABEL: define i16 @test_load16
239; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
240; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
241; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
242; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
243; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
244; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
245; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
246; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
247; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
248; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
249; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
250; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
251; RECOVER-ZERO-BASED-SHADOW:       8:
252; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
253; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
254; RECOVER-ZERO-BASED-SHADOW:       10:
255; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2337", "{x0}"(i64 [[TMP0]])
256; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
257; RECOVER-ZERO-BASED-SHADOW:       11:
258; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
259; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
260; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
261; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
262; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
263; RECOVER-ZERO-BASED-SHADOW:       16:
264; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
265; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
266; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
267; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
268; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
269; RECOVER-ZERO-BASED-SHADOW:       21:
270; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
271; RECOVER-ZERO-BASED-SHADOW:       22:
272; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
273; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i16 [[B]]
274;
275entry:
276  %b = load i16, ptr %a, align 4
277  ret i16 %b
278}
279
280define i32 @test_load32(ptr %a) sanitize_hwaddress {
281; CHECK-LABEL: define i32 @test_load32
282; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
283; CHECK-NEXT:  entry:
284; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
285; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 2)
286; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
287; CHECK-NEXT:    ret i32 [[B]]
288;
289; NOFASTPATH-LABEL: define i32 @test_load32
290; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
291; NOFASTPATH-NEXT:  entry:
292; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
293; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 2)
294; NOFASTPATH-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
295; NOFASTPATH-NEXT:    ret i32 [[B]]
296;
297; FASTPATH-LABEL: define i32 @test_load32
298; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
299; FASTPATH-NEXT:  entry:
300; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
301; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
302; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
303; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
304; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
305; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
306; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
307; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
308; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
309; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
310; FASTPATH:       8:
311; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 2)
312; FASTPATH-NEXT:    br label [[TMP9]]
313; FASTPATH:       9:
314; FASTPATH-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
315; FASTPATH-NEXT:    ret i32 [[B]]
316;
317; ABORT-DYNAMIC-SHADOW-LABEL: define i32 @test_load32
318; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
319; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
320; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
321; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 2)
322; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
323; ABORT-DYNAMIC-SHADOW-NEXT:    ret i32 [[B]]
324;
325; RECOVER-DYNAMIC-SHADOW-LABEL: define i32 @test_load32
326; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
327; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
328; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
329; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
330; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
331; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
332; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
333; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
334; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
335; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
336; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
337; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
338; RECOVER-DYNAMIC-SHADOW:       8:
339; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
340; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
341; RECOVER-DYNAMIC-SHADOW:       10:
342; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2338", "{x0}"(i64 [[TMP0]])
343; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
344; RECOVER-DYNAMIC-SHADOW:       11:
345; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
346; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
347; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
348; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
349; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
350; RECOVER-DYNAMIC-SHADOW:       16:
351; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
352; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
353; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
354; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
355; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
356; RECOVER-DYNAMIC-SHADOW:       21:
357; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
358; RECOVER-DYNAMIC-SHADOW:       22:
359; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
360; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i32 [[B]]
361;
362; ABORT-ZERO-BASED-SHADOW-LABEL: define i32 @test_load32
363; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
364; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
365; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
366; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 2, i64 0)
367; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
368; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i32 [[B]]
369;
370; RECOVER-ZERO-BASED-SHADOW-LABEL: define i32 @test_load32
371; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
372; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
373; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
374; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
375; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
376; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
377; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
378; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
379; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
380; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
381; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
382; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
383; RECOVER-ZERO-BASED-SHADOW:       8:
384; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
385; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
386; RECOVER-ZERO-BASED-SHADOW:       10:
387; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2338", "{x0}"(i64 [[TMP0]])
388; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
389; RECOVER-ZERO-BASED-SHADOW:       11:
390; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
391; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
392; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
393; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
394; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
395; RECOVER-ZERO-BASED-SHADOW:       16:
396; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
397; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
398; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
399; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
400; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
401; RECOVER-ZERO-BASED-SHADOW:       21:
402; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
403; RECOVER-ZERO-BASED-SHADOW:       22:
404; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
405; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i32 [[B]]
406;
407entry:
408  %b = load i32, ptr %a, align 4
409  ret i32 %b
410}
411
412define i64 @test_load64(ptr %a) sanitize_hwaddress {
413; CHECK-LABEL: define i64 @test_load64
414; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
415; CHECK-NEXT:  entry:
416; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
417; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 3)
418; CHECK-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
419; CHECK-NEXT:    ret i64 [[B]]
420;
421; NOFASTPATH-LABEL: define i64 @test_load64
422; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
423; NOFASTPATH-NEXT:  entry:
424; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
425; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 3)
426; NOFASTPATH-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
427; NOFASTPATH-NEXT:    ret i64 [[B]]
428;
429; FASTPATH-LABEL: define i64 @test_load64
430; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
431; FASTPATH-NEXT:  entry:
432; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
433; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
434; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
435; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
436; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
437; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
438; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
439; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
440; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
441; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
442; FASTPATH:       8:
443; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 3)
444; FASTPATH-NEXT:    br label [[TMP9]]
445; FASTPATH:       9:
446; FASTPATH-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
447; FASTPATH-NEXT:    ret i64 [[B]]
448;
449; ABORT-DYNAMIC-SHADOW-LABEL: define i64 @test_load64
450; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
451; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
452; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
453; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 3)
454; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
455; ABORT-DYNAMIC-SHADOW-NEXT:    ret i64 [[B]]
456;
457; RECOVER-DYNAMIC-SHADOW-LABEL: define i64 @test_load64
458; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
459; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
460; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
461; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
462; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
463; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
464; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
465; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
466; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
467; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
468; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
469; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
470; RECOVER-DYNAMIC-SHADOW:       8:
471; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
472; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
473; RECOVER-DYNAMIC-SHADOW:       10:
474; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2339", "{x0}"(i64 [[TMP0]])
475; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
476; RECOVER-DYNAMIC-SHADOW:       11:
477; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
478; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
479; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
480; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
481; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
482; RECOVER-DYNAMIC-SHADOW:       16:
483; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
484; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
485; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
486; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
487; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
488; RECOVER-DYNAMIC-SHADOW:       21:
489; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
490; RECOVER-DYNAMIC-SHADOW:       22:
491; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
492; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i64 [[B]]
493;
494; ABORT-ZERO-BASED-SHADOW-LABEL: define i64 @test_load64
495; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
496; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
497; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
498; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 3, i64 0)
499; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
500; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i64 [[B]]
501;
502; RECOVER-ZERO-BASED-SHADOW-LABEL: define i64 @test_load64
503; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
504; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
505; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
506; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
507; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
508; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
509; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
510; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
511; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
512; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
513; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
514; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
515; RECOVER-ZERO-BASED-SHADOW:       8:
516; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
517; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
518; RECOVER-ZERO-BASED-SHADOW:       10:
519; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2339", "{x0}"(i64 [[TMP0]])
520; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
521; RECOVER-ZERO-BASED-SHADOW:       11:
522; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
523; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
524; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
525; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
526; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
527; RECOVER-ZERO-BASED-SHADOW:       16:
528; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
529; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
530; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
531; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
532; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
533; RECOVER-ZERO-BASED-SHADOW:       21:
534; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
535; RECOVER-ZERO-BASED-SHADOW:       22:
536; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
537; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i64 [[B]]
538;
539entry:
540  %b = load i64, ptr %a, align 8
541  ret i64 %b
542}
543
544define i128 @test_load128(ptr %a) sanitize_hwaddress {
545; CHECK-LABEL: define i128 @test_load128
546; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
547; CHECK-NEXT:  entry:
548; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
549; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 4)
550; CHECK-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
551; CHECK-NEXT:    ret i128 [[B]]
552;
553; NOFASTPATH-LABEL: define i128 @test_load128
554; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
555; NOFASTPATH-NEXT:  entry:
556; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
557; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 4)
558; NOFASTPATH-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
559; NOFASTPATH-NEXT:    ret i128 [[B]]
560;
561; FASTPATH-LABEL: define i128 @test_load128
562; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
563; FASTPATH-NEXT:  entry:
564; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
565; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
566; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
567; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
568; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
569; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
570; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
571; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
572; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
573; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
574; FASTPATH:       8:
575; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 4)
576; FASTPATH-NEXT:    br label [[TMP9]]
577; FASTPATH:       9:
578; FASTPATH-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
579; FASTPATH-NEXT:    ret i128 [[B]]
580;
581; ABORT-DYNAMIC-SHADOW-LABEL: define i128 @test_load128
582; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
583; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
584; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
585; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 4)
586; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
587; ABORT-DYNAMIC-SHADOW-NEXT:    ret i128 [[B]]
588;
589; RECOVER-DYNAMIC-SHADOW-LABEL: define i128 @test_load128
590; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
591; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
592; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
593; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
594; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
595; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
596; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
597; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
598; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
599; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
600; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
601; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
602; RECOVER-DYNAMIC-SHADOW:       8:
603; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
604; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
605; RECOVER-DYNAMIC-SHADOW:       10:
606; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2340", "{x0}"(i64 [[TMP0]])
607; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
608; RECOVER-DYNAMIC-SHADOW:       11:
609; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
610; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
611; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
612; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
613; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
614; RECOVER-DYNAMIC-SHADOW:       16:
615; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
616; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
617; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
618; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
619; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
620; RECOVER-DYNAMIC-SHADOW:       21:
621; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
622; RECOVER-DYNAMIC-SHADOW:       22:
623; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
624; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i128 [[B]]
625;
626; ABORT-ZERO-BASED-SHADOW-LABEL: define i128 @test_load128
627; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
628; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
629; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
630; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 4, i64 0)
631; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
632; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i128 [[B]]
633;
634; RECOVER-ZERO-BASED-SHADOW-LABEL: define i128 @test_load128
635; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
636; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
637; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
638; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
639; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
640; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
641; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
642; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
643; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
644; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
645; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
646; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
647; RECOVER-ZERO-BASED-SHADOW:       8:
648; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
649; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
650; RECOVER-ZERO-BASED-SHADOW:       10:
651; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2340", "{x0}"(i64 [[TMP0]])
652; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
653; RECOVER-ZERO-BASED-SHADOW:       11:
654; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
655; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
656; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
657; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
658; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
659; RECOVER-ZERO-BASED-SHADOW:       16:
660; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
661; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
662; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
663; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
664; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
665; RECOVER-ZERO-BASED-SHADOW:       21:
666; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
667; RECOVER-ZERO-BASED-SHADOW:       22:
668; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
669; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i128 [[B]]
670;
671entry:
672  %b = load i128, ptr %a, align 16
673  ret i128 %b
674}
675
676define i40 @test_load40(ptr %a) sanitize_hwaddress {
677; CHECK-LABEL: define i40 @test_load40
678; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
679; CHECK-NEXT:  entry:
680; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
681; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
682; CHECK-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
683; CHECK-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
684; CHECK-NEXT:    ret i40 [[B]]
685;
686; NOFASTPATH-LABEL: define i40 @test_load40
687; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
688; NOFASTPATH-NEXT:  entry:
689; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
690; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
691; NOFASTPATH-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
692; NOFASTPATH-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
693; NOFASTPATH-NEXT:    ret i40 [[B]]
694;
695; FASTPATH-LABEL: define i40 @test_load40
696; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
697; FASTPATH-NEXT:  entry:
698; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
699; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
700; FASTPATH-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
701; FASTPATH-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
702; FASTPATH-NEXT:    ret i40 [[B]]
703;
704; ABORT-DYNAMIC-SHADOW-LABEL: define i40 @test_load40
705; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
706; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
707; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
708; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
709; ABORT-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
710; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
711; ABORT-DYNAMIC-SHADOW-NEXT:    ret i40 [[B]]
712;
713; RECOVER-DYNAMIC-SHADOW-LABEL: define i40 @test_load40
714; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
715; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
716; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
717; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
718; RECOVER-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_loadN_noabort(i64 [[TMP0]], i64 5)
719; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
720; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i40 [[B]]
721;
722; ABORT-ZERO-BASED-SHADOW-LABEL: define i40 @test_load40
723; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
724; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
725; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
726; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
727; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
728; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
729; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i40 [[B]]
730;
731; RECOVER-ZERO-BASED-SHADOW-LABEL: define i40 @test_load40
732; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
733; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
734; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
735; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
736; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_loadN_noabort(i64 [[TMP0]], i64 5)
737; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
738; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i40 [[B]]
739;
740entry:
741  %b = load i40, ptr %a, align 4
742  ret i40 %b
743}
744
745define void @test_store8(ptr %a, i8 %b) sanitize_hwaddress {
746; CHECK-LABEL: define void @test_store8
747; CHECK-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
748; CHECK-NEXT:  entry:
749; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
750; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 16)
751; CHECK-NEXT:    store i8 [[B]], ptr [[A]], align 4
752; CHECK-NEXT:    ret void
753;
754; NOFASTPATH-LABEL: define void @test_store8
755; NOFASTPATH-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
756; NOFASTPATH-NEXT:  entry:
757; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
758; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 16)
759; NOFASTPATH-NEXT:    store i8 [[B]], ptr [[A]], align 4
760; NOFASTPATH-NEXT:    ret void
761;
762; FASTPATH-LABEL: define void @test_store8
763; FASTPATH-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
764; FASTPATH-NEXT:  entry:
765; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
766; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
767; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
768; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
769; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
770; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
771; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
772; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
773; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
774; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
775; FASTPATH:       8:
776; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 16)
777; FASTPATH-NEXT:    br label [[TMP9]]
778; FASTPATH:       9:
779; FASTPATH-NEXT:    store i8 [[B]], ptr [[A]], align 4
780; FASTPATH-NEXT:    ret void
781;
782; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store8
783; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
784; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
785; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
786; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 16)
787; ABORT-DYNAMIC-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
788; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
789;
790; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store8
791; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
792; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
793; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
794; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
795; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
796; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
797; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
798; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
799; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
800; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
801; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
802; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
803; RECOVER-DYNAMIC-SHADOW:       8:
804; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
805; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
806; RECOVER-DYNAMIC-SHADOW:       10:
807; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2352", "{x0}"(i64 [[TMP0]])
808; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
809; RECOVER-DYNAMIC-SHADOW:       11:
810; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
811; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
812; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
813; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
814; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
815; RECOVER-DYNAMIC-SHADOW:       16:
816; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
817; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
818; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
819; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
820; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
821; RECOVER-DYNAMIC-SHADOW:       21:
822; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
823; RECOVER-DYNAMIC-SHADOW:       22:
824; RECOVER-DYNAMIC-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
825; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
826;
827; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store8
828; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
829; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
830; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
831; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 16, i64 0)
832; ABORT-ZERO-BASED-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
833; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
834;
835; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store8
836; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
837; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
838; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
839; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
840; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
841; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
842; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
843; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
844; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
845; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
846; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
847; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
848; RECOVER-ZERO-BASED-SHADOW:       8:
849; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
850; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
851; RECOVER-ZERO-BASED-SHADOW:       10:
852; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2352", "{x0}"(i64 [[TMP0]])
853; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
854; RECOVER-ZERO-BASED-SHADOW:       11:
855; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
856; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
857; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
858; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
859; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
860; RECOVER-ZERO-BASED-SHADOW:       16:
861; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
862; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
863; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
864; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
865; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
866; RECOVER-ZERO-BASED-SHADOW:       21:
867; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
868; RECOVER-ZERO-BASED-SHADOW:       22:
869; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
870; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
871;
872entry:
873  store i8 %b, ptr %a, align 4
874  ret void
875}
876
877define void @test_store16(ptr %a, i16 %b) sanitize_hwaddress {
878; CHECK-LABEL: define void @test_store16
879; CHECK-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
880; CHECK-NEXT:  entry:
881; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
882; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 17)
883; CHECK-NEXT:    store i16 [[B]], ptr [[A]], align 4
884; CHECK-NEXT:    ret void
885;
886; NOFASTPATH-LABEL: define void @test_store16
887; NOFASTPATH-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
888; NOFASTPATH-NEXT:  entry:
889; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
890; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 17)
891; NOFASTPATH-NEXT:    store i16 [[B]], ptr [[A]], align 4
892; NOFASTPATH-NEXT:    ret void
893;
894; FASTPATH-LABEL: define void @test_store16
895; FASTPATH-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
896; FASTPATH-NEXT:  entry:
897; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
898; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
899; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
900; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
901; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
902; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
903; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
904; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
905; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
906; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
907; FASTPATH:       8:
908; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 17)
909; FASTPATH-NEXT:    br label [[TMP9]]
910; FASTPATH:       9:
911; FASTPATH-NEXT:    store i16 [[B]], ptr [[A]], align 4
912; FASTPATH-NEXT:    ret void
913;
914; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store16
915; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
916; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
917; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
918; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 17)
919; ABORT-DYNAMIC-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
920; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
921;
922; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store16
923; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
924; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
925; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
926; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
927; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
928; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
929; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
930; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
931; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
932; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
933; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
934; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
935; RECOVER-DYNAMIC-SHADOW:       8:
936; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
937; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
938; RECOVER-DYNAMIC-SHADOW:       10:
939; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2353", "{x0}"(i64 [[TMP0]])
940; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
941; RECOVER-DYNAMIC-SHADOW:       11:
942; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
943; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
944; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
945; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
946; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
947; RECOVER-DYNAMIC-SHADOW:       16:
948; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
949; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
950; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
951; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
952; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
953; RECOVER-DYNAMIC-SHADOW:       21:
954; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
955; RECOVER-DYNAMIC-SHADOW:       22:
956; RECOVER-DYNAMIC-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
957; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
958;
959; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store16
960; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
961; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
962; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
963; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 17, i64 0)
964; ABORT-ZERO-BASED-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
965; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
966;
967; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store16
968; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
969; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
970; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
971; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
972; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
973; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
974; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
975; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
976; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
977; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
978; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
979; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
980; RECOVER-ZERO-BASED-SHADOW:       8:
981; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
982; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
983; RECOVER-ZERO-BASED-SHADOW:       10:
984; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2353", "{x0}"(i64 [[TMP0]])
985; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
986; RECOVER-ZERO-BASED-SHADOW:       11:
987; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
988; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
989; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
990; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
991; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
992; RECOVER-ZERO-BASED-SHADOW:       16:
993; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
994; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
995; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
996; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
997; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
998; RECOVER-ZERO-BASED-SHADOW:       21:
999; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1000; RECOVER-ZERO-BASED-SHADOW:       22:
1001; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
1002; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1003;
1004entry:
1005  store i16 %b, ptr %a, align 4
1006  ret void
1007}
1008
1009define void @test_store32(ptr %a, i32 %b) sanitize_hwaddress {
1010; CHECK-LABEL: define void @test_store32
1011; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1012; CHECK-NEXT:  entry:
1013; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1014; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 18)
1015; CHECK-NEXT:    store i32 [[B]], ptr [[A]], align 4
1016; CHECK-NEXT:    ret void
1017;
1018; NOFASTPATH-LABEL: define void @test_store32
1019; NOFASTPATH-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1020; NOFASTPATH-NEXT:  entry:
1021; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1022; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 18)
1023; NOFASTPATH-NEXT:    store i32 [[B]], ptr [[A]], align 4
1024; NOFASTPATH-NEXT:    ret void
1025;
1026; FASTPATH-LABEL: define void @test_store32
1027; FASTPATH-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1028; FASTPATH-NEXT:  entry:
1029; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1030; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1031; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1032; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1033; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1034; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1035; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1036; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1037; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1038; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1039; FASTPATH:       8:
1040; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 18)
1041; FASTPATH-NEXT:    br label [[TMP9]]
1042; FASTPATH:       9:
1043; FASTPATH-NEXT:    store i32 [[B]], ptr [[A]], align 4
1044; FASTPATH-NEXT:    ret void
1045;
1046; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store32
1047; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1048; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1049; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1050; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 18)
1051; ABORT-DYNAMIC-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1052; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1053;
1054; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store32
1055; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1056; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1057; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1058; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1059; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1060; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1061; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1062; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1063; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1064; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1065; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1066; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1067; RECOVER-DYNAMIC-SHADOW:       8:
1068; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1069; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1070; RECOVER-DYNAMIC-SHADOW:       10:
1071; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2354", "{x0}"(i64 [[TMP0]])
1072; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1073; RECOVER-DYNAMIC-SHADOW:       11:
1074; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1075; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1076; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
1077; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1078; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1079; RECOVER-DYNAMIC-SHADOW:       16:
1080; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1081; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1082; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1083; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1084; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1085; RECOVER-DYNAMIC-SHADOW:       21:
1086; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1087; RECOVER-DYNAMIC-SHADOW:       22:
1088; RECOVER-DYNAMIC-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1089; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1090;
1091; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store32
1092; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1093; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1094; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1095; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 18, i64 0)
1096; ABORT-ZERO-BASED-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1097; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1098;
1099; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store32
1100; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1101; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1102; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1103; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1104; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1105; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1106; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1107; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1108; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1109; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1110; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1111; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1112; RECOVER-ZERO-BASED-SHADOW:       8:
1113; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1114; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1115; RECOVER-ZERO-BASED-SHADOW:       10:
1116; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2354", "{x0}"(i64 [[TMP0]])
1117; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1118; RECOVER-ZERO-BASED-SHADOW:       11:
1119; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1120; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1121; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
1122; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1123; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1124; RECOVER-ZERO-BASED-SHADOW:       16:
1125; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1126; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1127; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1128; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1129; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1130; RECOVER-ZERO-BASED-SHADOW:       21:
1131; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1132; RECOVER-ZERO-BASED-SHADOW:       22:
1133; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1134; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1135;
1136entry:
1137  store i32 %b, ptr %a, align 4
1138  ret void
1139}
1140
1141define void @test_store64(ptr %a, i64 %b) sanitize_hwaddress {
1142; CHECK-LABEL: define void @test_store64
1143; CHECK-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1144; CHECK-NEXT:  entry:
1145; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1146; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 19)
1147; CHECK-NEXT:    store i64 [[B]], ptr [[A]], align 8
1148; CHECK-NEXT:    ret void
1149;
1150; NOFASTPATH-LABEL: define void @test_store64
1151; NOFASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1152; NOFASTPATH-NEXT:  entry:
1153; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1154; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 19)
1155; NOFASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 8
1156; NOFASTPATH-NEXT:    ret void
1157;
1158; FASTPATH-LABEL: define void @test_store64
1159; FASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1160; FASTPATH-NEXT:  entry:
1161; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1162; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1163; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1164; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1165; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1166; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1167; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1168; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1169; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1170; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1171; FASTPATH:       8:
1172; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 19)
1173; FASTPATH-NEXT:    br label [[TMP9]]
1174; FASTPATH:       9:
1175; FASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 8
1176; FASTPATH-NEXT:    ret void
1177;
1178; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store64
1179; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1180; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1181; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1182; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 19)
1183; ABORT-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1184; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1185;
1186; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store64
1187; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1188; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1189; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1190; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1191; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1192; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1193; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1194; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1195; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1196; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1197; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1198; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1199; RECOVER-DYNAMIC-SHADOW:       8:
1200; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1201; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1202; RECOVER-DYNAMIC-SHADOW:       10:
1203; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2355", "{x0}"(i64 [[TMP0]])
1204; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1205; RECOVER-DYNAMIC-SHADOW:       11:
1206; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1207; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1208; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
1209; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1210; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1211; RECOVER-DYNAMIC-SHADOW:       16:
1212; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1213; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1214; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1215; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1216; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1217; RECOVER-DYNAMIC-SHADOW:       21:
1218; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1219; RECOVER-DYNAMIC-SHADOW:       22:
1220; RECOVER-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1221; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1222;
1223; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store64
1224; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1225; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1226; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1227; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 19, i64 0)
1228; ABORT-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1229; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1230;
1231; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store64
1232; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1233; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1234; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1235; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1236; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1237; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1238; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1239; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1240; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1241; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1242; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1243; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1244; RECOVER-ZERO-BASED-SHADOW:       8:
1245; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1246; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1247; RECOVER-ZERO-BASED-SHADOW:       10:
1248; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2355", "{x0}"(i64 [[TMP0]])
1249; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1250; RECOVER-ZERO-BASED-SHADOW:       11:
1251; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1252; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1253; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
1254; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1255; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1256; RECOVER-ZERO-BASED-SHADOW:       16:
1257; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1258; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1259; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1260; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1261; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1262; RECOVER-ZERO-BASED-SHADOW:       21:
1263; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1264; RECOVER-ZERO-BASED-SHADOW:       22:
1265; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1266; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1267;
1268entry:
1269  store i64 %b, ptr %a, align 8
1270  ret void
1271}
1272
1273define void @test_store128(ptr %a, i128 %b) sanitize_hwaddress {
1274; CHECK-LABEL: define void @test_store128
1275; CHECK-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1276; CHECK-NEXT:  entry:
1277; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1278; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 20)
1279; CHECK-NEXT:    store i128 [[B]], ptr [[A]], align 16
1280; CHECK-NEXT:    ret void
1281;
1282; NOFASTPATH-LABEL: define void @test_store128
1283; NOFASTPATH-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1284; NOFASTPATH-NEXT:  entry:
1285; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1286; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 20)
1287; NOFASTPATH-NEXT:    store i128 [[B]], ptr [[A]], align 16
1288; NOFASTPATH-NEXT:    ret void
1289;
1290; FASTPATH-LABEL: define void @test_store128
1291; FASTPATH-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1292; FASTPATH-NEXT:  entry:
1293; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1294; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1295; FASTPATH-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1296; FASTPATH-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1297; FASTPATH-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1298; FASTPATH-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1299; FASTPATH-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1300; FASTPATH-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1301; FASTPATH-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1302; FASTPATH-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1303; FASTPATH:       8:
1304; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 20)
1305; FASTPATH-NEXT:    br label [[TMP9]]
1306; FASTPATH:       9:
1307; FASTPATH-NEXT:    store i128 [[B]], ptr [[A]], align 16
1308; FASTPATH-NEXT:    ret void
1309;
1310; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store128
1311; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1312; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1313; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1314; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 20)
1315; ABORT-DYNAMIC-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1316; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1317;
1318; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store128
1319; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1320; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1321; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1322; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1323; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1324; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1325; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1326; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1327; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1328; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1329; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1330; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1331; RECOVER-DYNAMIC-SHADOW:       8:
1332; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1333; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1334; RECOVER-DYNAMIC-SHADOW:       10:
1335; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "brk #2356", "{x0}"(i64 [[TMP0]])
1336; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1337; RECOVER-DYNAMIC-SHADOW:       11:
1338; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1339; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1340; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
1341; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1342; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1343; RECOVER-DYNAMIC-SHADOW:       16:
1344; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1345; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1346; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1347; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1348; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1349; RECOVER-DYNAMIC-SHADOW:       21:
1350; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1351; RECOVER-DYNAMIC-SHADOW:       22:
1352; RECOVER-DYNAMIC-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1353; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1354;
1355; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store128
1356; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1357; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1358; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1359; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules.fixedshadow(ptr [[A]], i32 20, i64 0)
1360; ABORT-ZERO-BASED-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1361; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1362;
1363; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store128
1364; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1365; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1366; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1367; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1368; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1369; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1370; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1371; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1372; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1373; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1374; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1375; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1376; RECOVER-ZERO-BASED-SHADOW:       8:
1377; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1378; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1379; RECOVER-ZERO-BASED-SHADOW:       10:
1380; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "brk #2356", "{x0}"(i64 [[TMP0]])
1381; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1382; RECOVER-ZERO-BASED-SHADOW:       11:
1383; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1384; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1385; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
1386; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1387; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1388; RECOVER-ZERO-BASED-SHADOW:       16:
1389; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1390; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1391; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1392; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1393; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1394; RECOVER-ZERO-BASED-SHADOW:       21:
1395; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1396; RECOVER-ZERO-BASED-SHADOW:       22:
1397; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1398; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1399;
1400entry:
1401  store i128 %b, ptr %a, align 16
1402  ret void
1403}
1404
1405define void @test_store40(ptr %a, i40 %b) sanitize_hwaddress {
1406; CHECK-LABEL: define void @test_store40
1407; CHECK-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1408; CHECK-NEXT:  entry:
1409; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1410; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1411; CHECK-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1412; CHECK-NEXT:    store i40 [[B]], ptr [[A]], align 4
1413; CHECK-NEXT:    ret void
1414;
1415; NOFASTPATH-LABEL: define void @test_store40
1416; NOFASTPATH-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1417; NOFASTPATH-NEXT:  entry:
1418; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1419; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1420; NOFASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1421; NOFASTPATH-NEXT:    store i40 [[B]], ptr [[A]], align 4
1422; NOFASTPATH-NEXT:    ret void
1423;
1424; FASTPATH-LABEL: define void @test_store40
1425; FASTPATH-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1426; FASTPATH-NEXT:  entry:
1427; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1428; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1429; FASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1430; FASTPATH-NEXT:    store i40 [[B]], ptr [[A]], align 4
1431; FASTPATH-NEXT:    ret void
1432;
1433; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store40
1434; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1435; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1436; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1437; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1438; ABORT-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1439; ABORT-DYNAMIC-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1440; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1441;
1442; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store40
1443; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1444; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1445; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1446; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1447; RECOVER-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 5)
1448; RECOVER-DYNAMIC-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1449; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1450;
1451; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store40
1452; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1453; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1454; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1455; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1456; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1457; ABORT-ZERO-BASED-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1458; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1459;
1460; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store40
1461; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1462; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1463; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1464; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1465; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 5)
1466; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1467; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1468;
1469entry:
1470  store i40 %b, ptr %a, align 4
1471  ret void
1472}
1473
1474define void @test_store_unaligned(ptr %a, i64 %b) sanitize_hwaddress {
1475; CHECK-LABEL: define void @test_store_unaligned
1476; CHECK-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1477; CHECK-NEXT:  entry:
1478; CHECK-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1479; CHECK-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1480; CHECK-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
1481; CHECK-NEXT:    store i64 [[B]], ptr [[A]], align 4
1482; CHECK-NEXT:    ret void
1483;
1484; NOFASTPATH-LABEL: define void @test_store_unaligned
1485; NOFASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1486; NOFASTPATH-NEXT:  entry:
1487; NOFASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1488; NOFASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1489; NOFASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
1490; NOFASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 4
1491; NOFASTPATH-NEXT:    ret void
1492;
1493; FASTPATH-LABEL: define void @test_store_unaligned
1494; FASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1495; FASTPATH-NEXT:  entry:
1496; FASTPATH-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1497; FASTPATH-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1498; FASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
1499; FASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 4
1500; FASTPATH-NEXT:    ret void
1501;
1502; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store_unaligned
1503; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1504; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1505; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1506; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1507; ABORT-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
1508; ABORT-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
1509; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1510;
1511; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store_unaligned
1512; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1513; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1514; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1515; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1516; RECOVER-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 8)
1517; RECOVER-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
1518; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1519;
1520; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store_unaligned
1521; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1522; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1523; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1524; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1525; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
1526; ABORT-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
1527; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1528;
1529; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store_unaligned
1530; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1531; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1532; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1533; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1534; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 8)
1535; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
1536; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1537;
1538entry:
1539  store i64 %b, ptr %a, align 4
1540  ret void
1541}
1542
1543define i8 @test_load_noattr(ptr %a) {
1544; CHECK-LABEL: define i8 @test_load_noattr
1545; CHECK-SAME: (ptr [[A:%.*]]) {
1546; CHECK-NEXT:  entry:
1547; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1548; CHECK-NEXT:    ret i8 [[B]]
1549;
1550; NOFASTPATH-LABEL: define i8 @test_load_noattr
1551; NOFASTPATH-SAME: (ptr [[A:%.*]]) {
1552; NOFASTPATH-NEXT:  entry:
1553; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1554; NOFASTPATH-NEXT:    ret i8 [[B]]
1555;
1556; FASTPATH-LABEL: define i8 @test_load_noattr
1557; FASTPATH-SAME: (ptr [[A:%.*]]) {
1558; FASTPATH-NEXT:  entry:
1559; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1560; FASTPATH-NEXT:    ret i8 [[B]]
1561;
1562; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load_noattr
1563; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) {
1564; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1565; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1566; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
1567;
1568; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load_noattr
1569; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) {
1570; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1571; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1572; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
1573;
1574; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_noattr
1575; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) {
1576; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1577; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1578; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
1579;
1580; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_noattr
1581; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) {
1582; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1583; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1584; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
1585;
1586entry:
1587  %b = load i8, ptr %a, align 4
1588  ret i8 %b
1589}
1590
1591define i8 @test_load_notmyattr(ptr %a) sanitize_address {
1592; CHECK-LABEL: define i8 @test_load_notmyattr
1593; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1594; CHECK-NEXT:  entry:
1595; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1596; CHECK-NEXT:    ret i8 [[B]]
1597;
1598; NOFASTPATH-LABEL: define i8 @test_load_notmyattr
1599; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1600; NOFASTPATH-NEXT:  entry:
1601; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1602; NOFASTPATH-NEXT:    ret i8 [[B]]
1603;
1604; FASTPATH-LABEL: define i8 @test_load_notmyattr
1605; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1606; FASTPATH-NEXT:  entry:
1607; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1608; FASTPATH-NEXT:    ret i8 [[B]]
1609;
1610; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load_notmyattr
1611; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1612; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1613; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1614; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
1615;
1616; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load_notmyattr
1617; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1618; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1619; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1620; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
1621;
1622; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_notmyattr
1623; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1624; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1625; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1626; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
1627;
1628; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_notmyattr
1629; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
1630; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1631; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
1632; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
1633;
1634entry:
1635  %b = load i8, ptr %a, align 4
1636  ret i8 %b
1637}
1638
1639define i8 @test_load_addrspace(ptr addrspace(256) %a) sanitize_hwaddress {
1640; CHECK-LABEL: define i8 @test_load_addrspace
1641; CHECK-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1642; CHECK-NEXT:  entry:
1643; CHECK-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1644; CHECK-NEXT:    ret i8 [[B]]
1645;
1646; NOFASTPATH-LABEL: define i8 @test_load_addrspace
1647; NOFASTPATH-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1648; NOFASTPATH-NEXT:  entry:
1649; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1650; NOFASTPATH-NEXT:    ret i8 [[B]]
1651;
1652; FASTPATH-LABEL: define i8 @test_load_addrspace
1653; FASTPATH-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1654; FASTPATH-NEXT:  entry:
1655; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1656; FASTPATH-NEXT:    ret i8 [[B]]
1657;
1658; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load_addrspace
1659; ABORT-DYNAMIC-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1660; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1661; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1662; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
1663;
1664; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load_addrspace
1665; RECOVER-DYNAMIC-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1666; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1667; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1668; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
1669;
1670; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_addrspace
1671; ABORT-ZERO-BASED-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1672; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1673; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1674; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
1675;
1676; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_addrspace
1677; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
1678; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1679; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
1680; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
1681;
1682entry:
1683  %b = load i8, ptr addrspace(256) %a, align 4
1684  ret i8 %b
1685}
1686