xref: /llvm-project/llvm/test/Instrumentation/HWAddressSanitizer/RISCV/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 = "riscv64-unknown-linux"
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:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
21; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
22; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
23; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
24; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
25; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
26; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
27; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
28; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
29; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
30; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
31; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
32; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
33; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2:![0-9]+]]
34; CHECK:       12:
35; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 0)
36; CHECK-NEXT:    br label [[TMP13]]
37; CHECK:       13:
38; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
39; CHECK-NEXT:    ret i8 [[B]]
40;
41; NOFASTPATH-LABEL: define i8 @test_load8
42; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
43; NOFASTPATH-NEXT:  entry:
44; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
45; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
46; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
47; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
48; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
49; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 0)
50; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
51; NOFASTPATH-NEXT:    ret i8 [[B]]
52;
53; FASTPATH-LABEL: define i8 @test_load8
54; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
55; FASTPATH-NEXT:  entry:
56; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
57; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
58; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
59; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
60; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
61; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
62; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
63; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
64; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
65; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
66; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
67; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
68; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
69; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2:![0-9]+]]
70; FASTPATH:       12:
71; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 0)
72; FASTPATH-NEXT:    br label [[TMP13]]
73; FASTPATH:       13:
74; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
75; FASTPATH-NEXT:    ret i8 [[B]]
76;
77; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load8
78; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
79; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
80; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
81; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
82; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
83; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
84; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
85; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
86; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
87; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
88; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
89; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2:![0-9]+]]
90; ABORT-DYNAMIC-SHADOW:       8:
91; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 0)
92; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
93; ABORT-DYNAMIC-SHADOW:       9:
94; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
95; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
96;
97; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load8
98; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
99; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
100; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
101; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
102; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
103; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
104; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
105; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
106; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
107; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
108; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
109; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2:![0-9]+]]
110; RECOVER-DYNAMIC-SHADOW:       8:
111; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
112; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
113; RECOVER-DYNAMIC-SHADOW:       10:
114; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 96", "{x10}"(i64 [[TMP0]])
115; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
116; RECOVER-DYNAMIC-SHADOW:       11:
117; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
118; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
119; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
120; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
121; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
122; RECOVER-DYNAMIC-SHADOW:       16:
123; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
124; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
125; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
126; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
127; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
128; RECOVER-DYNAMIC-SHADOW:       21:
129; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
130; RECOVER-DYNAMIC-SHADOW:       22:
131; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
132; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
133;
134; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load8
135; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
136; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
137; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
138; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
139; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
140; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
141; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
142; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
143; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
144; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
145; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
146; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2:![0-9]+]]
147; ABORT-ZERO-BASED-SHADOW:       8:
148; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 0)
149; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
150; ABORT-ZERO-BASED-SHADOW:       9:
151; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
152; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
153;
154; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load8
155; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
156; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
157; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
158; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
159; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
160; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
161; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
162; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
163; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
164; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
165; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
166; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2:![0-9]+]]
167; RECOVER-ZERO-BASED-SHADOW:       8:
168; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
169; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
170; RECOVER-ZERO-BASED-SHADOW:       10:
171; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 96", "{x10}"(i64 [[TMP0]])
172; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
173; RECOVER-ZERO-BASED-SHADOW:       11:
174; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
175; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
176; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
177; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
178; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
179; RECOVER-ZERO-BASED-SHADOW:       16:
180; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
181; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
182; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
183; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
184; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
185; RECOVER-ZERO-BASED-SHADOW:       21:
186; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
187; RECOVER-ZERO-BASED-SHADOW:       22:
188; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
189; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
190;
191entry:
192  %b = load i8, ptr %a, align 4
193  ret i8 %b
194}
195
196define i16 @test_load16(ptr %a) sanitize_hwaddress {
197; CHECK-LABEL: define i16 @test_load16
198; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
199; CHECK-NEXT:  entry:
200; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
201; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
202; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
203; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
204; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
205; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
206; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
207; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
208; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
209; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
210; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
211; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
212; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
213; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
214; CHECK:       12:
215; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 1)
216; CHECK-NEXT:    br label [[TMP13]]
217; CHECK:       13:
218; CHECK-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
219; CHECK-NEXT:    ret i16 [[B]]
220;
221; NOFASTPATH-LABEL: define i16 @test_load16
222; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
223; NOFASTPATH-NEXT:  entry:
224; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
225; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
226; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
227; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
228; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
229; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 1)
230; NOFASTPATH-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
231; NOFASTPATH-NEXT:    ret i16 [[B]]
232;
233; FASTPATH-LABEL: define i16 @test_load16
234; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
235; FASTPATH-NEXT:  entry:
236; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
237; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
238; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
239; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
240; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
241; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
242; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
243; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
244; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
245; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
246; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
247; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
248; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
249; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
250; FASTPATH:       12:
251; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 1)
252; FASTPATH-NEXT:    br label [[TMP13]]
253; FASTPATH:       13:
254; FASTPATH-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
255; FASTPATH-NEXT:    ret i16 [[B]]
256;
257; ABORT-DYNAMIC-SHADOW-LABEL: define i16 @test_load16
258; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
259; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
260; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
261; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
262; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
263; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
264; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
265; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
266; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
267; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
268; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
269; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
270; ABORT-DYNAMIC-SHADOW:       8:
271; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 1)
272; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
273; ABORT-DYNAMIC-SHADOW:       9:
274; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
275; ABORT-DYNAMIC-SHADOW-NEXT:    ret i16 [[B]]
276;
277; RECOVER-DYNAMIC-SHADOW-LABEL: define i16 @test_load16
278; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
279; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
280; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
281; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
282; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
283; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
284; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
285; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
286; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
287; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
288; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
289; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
290; RECOVER-DYNAMIC-SHADOW:       8:
291; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
292; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
293; RECOVER-DYNAMIC-SHADOW:       10:
294; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 97", "{x10}"(i64 [[TMP0]])
295; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
296; RECOVER-DYNAMIC-SHADOW:       11:
297; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
298; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
299; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
300; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
301; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
302; RECOVER-DYNAMIC-SHADOW:       16:
303; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
304; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
305; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
306; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
307; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
308; RECOVER-DYNAMIC-SHADOW:       21:
309; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
310; RECOVER-DYNAMIC-SHADOW:       22:
311; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
312; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i16 [[B]]
313;
314; ABORT-ZERO-BASED-SHADOW-LABEL: define i16 @test_load16
315; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
316; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
317; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
318; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
319; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
320; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
321; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
322; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
323; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
324; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
325; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
326; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
327; ABORT-ZERO-BASED-SHADOW:       8:
328; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 1)
329; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
330; ABORT-ZERO-BASED-SHADOW:       9:
331; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
332; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i16 [[B]]
333;
334; RECOVER-ZERO-BASED-SHADOW-LABEL: define i16 @test_load16
335; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
336; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
337; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
338; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
339; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
340; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
341; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
342; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
343; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
344; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
345; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
346; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
347; RECOVER-ZERO-BASED-SHADOW:       8:
348; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
349; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
350; RECOVER-ZERO-BASED-SHADOW:       10:
351; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 97", "{x10}"(i64 [[TMP0]])
352; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
353; RECOVER-ZERO-BASED-SHADOW:       11:
354; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
355; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
356; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
357; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
358; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
359; RECOVER-ZERO-BASED-SHADOW:       16:
360; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
361; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
362; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
363; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
364; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
365; RECOVER-ZERO-BASED-SHADOW:       21:
366; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
367; RECOVER-ZERO-BASED-SHADOW:       22:
368; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i16, ptr [[A]], align 4
369; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i16 [[B]]
370;
371entry:
372  %b = load i16, ptr %a, align 4
373  ret i16 %b
374}
375
376define i32 @test_load32(ptr %a) sanitize_hwaddress {
377; CHECK-LABEL: define i32 @test_load32
378; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
379; CHECK-NEXT:  entry:
380; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
381; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
382; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
383; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
384; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
385; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
386; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
387; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
388; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
389; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
390; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
391; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
392; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
393; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
394; CHECK:       12:
395; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 2)
396; CHECK-NEXT:    br label [[TMP13]]
397; CHECK:       13:
398; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
399; CHECK-NEXT:    ret i32 [[B]]
400;
401; NOFASTPATH-LABEL: define i32 @test_load32
402; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
403; NOFASTPATH-NEXT:  entry:
404; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
405; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
406; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
407; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
408; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
409; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 2)
410; NOFASTPATH-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
411; NOFASTPATH-NEXT:    ret i32 [[B]]
412;
413; FASTPATH-LABEL: define i32 @test_load32
414; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
415; FASTPATH-NEXT:  entry:
416; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
417; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
418; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
419; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
420; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
421; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
422; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
423; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
424; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
425; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
426; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
427; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
428; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
429; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
430; FASTPATH:       12:
431; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 2)
432; FASTPATH-NEXT:    br label [[TMP13]]
433; FASTPATH:       13:
434; FASTPATH-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
435; FASTPATH-NEXT:    ret i32 [[B]]
436;
437; ABORT-DYNAMIC-SHADOW-LABEL: define i32 @test_load32
438; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
439; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
440; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
441; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
442; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
443; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
444; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
445; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
446; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
447; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
448; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
449; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
450; ABORT-DYNAMIC-SHADOW:       8:
451; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 2)
452; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
453; ABORT-DYNAMIC-SHADOW:       9:
454; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
455; ABORT-DYNAMIC-SHADOW-NEXT:    ret i32 [[B]]
456;
457; RECOVER-DYNAMIC-SHADOW-LABEL: define i32 @test_load32
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 "ebreak\0Aaddiw x0, x11, 98", "{x10}"(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]], 3
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 i32, ptr [[A]], align 4
492; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i32 [[B]]
493;
494; ABORT-ZERO-BASED-SHADOW-LABEL: define i32 @test_load32
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:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
499; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
500; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
501; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
502; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
503; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
504; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
505; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
506; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
507; ABORT-ZERO-BASED-SHADOW:       8:
508; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 2)
509; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
510; ABORT-ZERO-BASED-SHADOW:       9:
511; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
512; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i32 [[B]]
513;
514; RECOVER-ZERO-BASED-SHADOW-LABEL: define i32 @test_load32
515; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
516; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
517; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
518; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
519; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
520; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
521; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
522; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
523; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
524; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
525; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
526; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
527; RECOVER-ZERO-BASED-SHADOW:       8:
528; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
529; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
530; RECOVER-ZERO-BASED-SHADOW:       10:
531; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 98", "{x10}"(i64 [[TMP0]])
532; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
533; RECOVER-ZERO-BASED-SHADOW:       11:
534; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
535; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
536; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
537; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
538; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
539; RECOVER-ZERO-BASED-SHADOW:       16:
540; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
541; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
542; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
543; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
544; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
545; RECOVER-ZERO-BASED-SHADOW:       21:
546; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
547; RECOVER-ZERO-BASED-SHADOW:       22:
548; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i32, ptr [[A]], align 4
549; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i32 [[B]]
550;
551entry:
552  %b = load i32, ptr %a, align 4
553  ret i32 %b
554}
555
556define i64 @test_load64(ptr %a) sanitize_hwaddress {
557; CHECK-LABEL: define i64 @test_load64
558; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
559; CHECK-NEXT:  entry:
560; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
561; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
562; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
563; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
564; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
565; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
566; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
567; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
568; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
569; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
570; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
571; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
572; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
573; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
574; CHECK:       12:
575; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 3)
576; CHECK-NEXT:    br label [[TMP13]]
577; CHECK:       13:
578; CHECK-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
579; CHECK-NEXT:    ret i64 [[B]]
580;
581; NOFASTPATH-LABEL: define i64 @test_load64
582; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
583; NOFASTPATH-NEXT:  entry:
584; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
585; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
586; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
587; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
588; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
589; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 3)
590; NOFASTPATH-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
591; NOFASTPATH-NEXT:    ret i64 [[B]]
592;
593; FASTPATH-LABEL: define i64 @test_load64
594; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
595; FASTPATH-NEXT:  entry:
596; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
597; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
598; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
599; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
600; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
601; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
602; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
603; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
604; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
605; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
606; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
607; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
608; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
609; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
610; FASTPATH:       12:
611; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 3)
612; FASTPATH-NEXT:    br label [[TMP13]]
613; FASTPATH:       13:
614; FASTPATH-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
615; FASTPATH-NEXT:    ret i64 [[B]]
616;
617; ABORT-DYNAMIC-SHADOW-LABEL: define i64 @test_load64
618; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
619; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
620; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
621; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
622; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
623; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
624; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
625; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
626; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
627; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
628; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
629; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
630; ABORT-DYNAMIC-SHADOW:       8:
631; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 3)
632; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
633; ABORT-DYNAMIC-SHADOW:       9:
634; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
635; ABORT-DYNAMIC-SHADOW-NEXT:    ret i64 [[B]]
636;
637; RECOVER-DYNAMIC-SHADOW-LABEL: define i64 @test_load64
638; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
639; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
640; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
641; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
642; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
643; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
644; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
645; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
646; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
647; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
648; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
649; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
650; RECOVER-DYNAMIC-SHADOW:       8:
651; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
652; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
653; RECOVER-DYNAMIC-SHADOW:       10:
654; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 99", "{x10}"(i64 [[TMP0]])
655; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
656; RECOVER-DYNAMIC-SHADOW:       11:
657; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
658; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
659; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
660; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
661; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
662; RECOVER-DYNAMIC-SHADOW:       16:
663; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
664; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
665; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
666; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
667; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
668; RECOVER-DYNAMIC-SHADOW:       21:
669; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
670; RECOVER-DYNAMIC-SHADOW:       22:
671; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
672; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i64 [[B]]
673;
674; ABORT-ZERO-BASED-SHADOW-LABEL: define i64 @test_load64
675; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
676; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
677; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
678; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
679; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
680; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
681; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
682; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
683; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
684; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
685; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
686; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
687; ABORT-ZERO-BASED-SHADOW:       8:
688; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 3)
689; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
690; ABORT-ZERO-BASED-SHADOW:       9:
691; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
692; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i64 [[B]]
693;
694; RECOVER-ZERO-BASED-SHADOW-LABEL: define i64 @test_load64
695; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
696; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
697; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
698; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
699; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
700; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
701; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
702; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
703; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
704; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
705; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
706; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
707; RECOVER-ZERO-BASED-SHADOW:       8:
708; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
709; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
710; RECOVER-ZERO-BASED-SHADOW:       10:
711; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 99", "{x10}"(i64 [[TMP0]])
712; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
713; RECOVER-ZERO-BASED-SHADOW:       11:
714; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
715; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
716; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
717; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
718; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
719; RECOVER-ZERO-BASED-SHADOW:       16:
720; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
721; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
722; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
723; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
724; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
725; RECOVER-ZERO-BASED-SHADOW:       21:
726; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
727; RECOVER-ZERO-BASED-SHADOW:       22:
728; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i64, ptr [[A]], align 8
729; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i64 [[B]]
730;
731entry:
732  %b = load i64, ptr %a, align 8
733  ret i64 %b
734}
735
736define i128 @test_load128(ptr %a) sanitize_hwaddress {
737; CHECK-LABEL: define i128 @test_load128
738; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
739; CHECK-NEXT:  entry:
740; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
741; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
742; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
743; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
744; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
745; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
746; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
747; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
748; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
749; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
750; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
751; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
752; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
753; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
754; CHECK:       12:
755; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 4)
756; CHECK-NEXT:    br label [[TMP13]]
757; CHECK:       13:
758; CHECK-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
759; CHECK-NEXT:    ret i128 [[B]]
760;
761; NOFASTPATH-LABEL: define i128 @test_load128
762; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
763; NOFASTPATH-NEXT:  entry:
764; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
765; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
766; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
767; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
768; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
769; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 4)
770; NOFASTPATH-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
771; NOFASTPATH-NEXT:    ret i128 [[B]]
772;
773; FASTPATH-LABEL: define i128 @test_load128
774; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
775; FASTPATH-NEXT:  entry:
776; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
777; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
778; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
779; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
780; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
781; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
782; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
783; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
784; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
785; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
786; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
787; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
788; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
789; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
790; FASTPATH:       12:
791; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 4)
792; FASTPATH-NEXT:    br label [[TMP13]]
793; FASTPATH:       13:
794; FASTPATH-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
795; FASTPATH-NEXT:    ret i128 [[B]]
796;
797; ABORT-DYNAMIC-SHADOW-LABEL: define i128 @test_load128
798; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
799; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
800; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
801; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
802; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
803; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
804; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
805; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
806; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
807; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
808; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
809; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
810; ABORT-DYNAMIC-SHADOW:       8:
811; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 4)
812; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
813; ABORT-DYNAMIC-SHADOW:       9:
814; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
815; ABORT-DYNAMIC-SHADOW-NEXT:    ret i128 [[B]]
816;
817; RECOVER-DYNAMIC-SHADOW-LABEL: define i128 @test_load128
818; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
819; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
820; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
821; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
822; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
823; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
824; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
825; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
826; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
827; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
828; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
829; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
830; RECOVER-DYNAMIC-SHADOW:       8:
831; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
832; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
833; RECOVER-DYNAMIC-SHADOW:       10:
834; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 100", "{x10}"(i64 [[TMP0]])
835; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
836; RECOVER-DYNAMIC-SHADOW:       11:
837; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
838; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
839; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
840; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
841; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
842; RECOVER-DYNAMIC-SHADOW:       16:
843; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
844; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
845; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
846; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
847; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
848; RECOVER-DYNAMIC-SHADOW:       21:
849; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
850; RECOVER-DYNAMIC-SHADOW:       22:
851; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
852; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i128 [[B]]
853;
854; ABORT-ZERO-BASED-SHADOW-LABEL: define i128 @test_load128
855; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
856; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
857; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
858; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
859; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
860; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
861; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
862; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
863; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
864; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
865; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
866; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
867; ABORT-ZERO-BASED-SHADOW:       8:
868; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 4)
869; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
870; ABORT-ZERO-BASED-SHADOW:       9:
871; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
872; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i128 [[B]]
873;
874; RECOVER-ZERO-BASED-SHADOW-LABEL: define i128 @test_load128
875; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
876; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
877; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
878; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
879; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
880; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
881; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
882; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
883; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
884; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
885; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
886; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
887; RECOVER-ZERO-BASED-SHADOW:       8:
888; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
889; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
890; RECOVER-ZERO-BASED-SHADOW:       10:
891; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 100", "{x10}"(i64 [[TMP0]])
892; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
893; RECOVER-ZERO-BASED-SHADOW:       11:
894; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
895; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
896; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
897; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
898; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
899; RECOVER-ZERO-BASED-SHADOW:       16:
900; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
901; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
902; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
903; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
904; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
905; RECOVER-ZERO-BASED-SHADOW:       21:
906; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
907; RECOVER-ZERO-BASED-SHADOW:       22:
908; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i128, ptr [[A]], align 16
909; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i128 [[B]]
910;
911entry:
912  %b = load i128, ptr %a, align 16
913  ret i128 %b
914}
915
916define i40 @test_load40(ptr %a) sanitize_hwaddress {
917; CHECK-LABEL: define i40 @test_load40
918; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
919; CHECK-NEXT:  entry:
920; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
921; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
922; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
923; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
924; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
925; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
926; CHECK-NEXT:    call void @__hwasan_loadN(i64 [[TMP4]], i64 5)
927; CHECK-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
928; CHECK-NEXT:    ret i40 [[B]]
929;
930; NOFASTPATH-LABEL: define i40 @test_load40
931; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
932; NOFASTPATH-NEXT:  entry:
933; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
934; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
935; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
936; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
937; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
938; NOFASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
939; NOFASTPATH-NEXT:    call void @__hwasan_loadN(i64 [[TMP4]], i64 5)
940; NOFASTPATH-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
941; NOFASTPATH-NEXT:    ret i40 [[B]]
942;
943; FASTPATH-LABEL: define i40 @test_load40
944; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
945; FASTPATH-NEXT:  entry:
946; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
947; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
948; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
949; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
950; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
951; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
952; FASTPATH-NEXT:    call void @__hwasan_loadN(i64 [[TMP4]], i64 5)
953; FASTPATH-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
954; FASTPATH-NEXT:    ret i40 [[B]]
955;
956; ABORT-DYNAMIC-SHADOW-LABEL: define i40 @test_load40
957; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
958; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
959; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
960; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
961; ABORT-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
962; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
963; ABORT-DYNAMIC-SHADOW-NEXT:    ret i40 [[B]]
964;
965; RECOVER-DYNAMIC-SHADOW-LABEL: define i40 @test_load40
966; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
967; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
968; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
969; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
970; RECOVER-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_loadN_noabort(i64 [[TMP0]], i64 5)
971; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
972; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i40 [[B]]
973;
974; ABORT-ZERO-BASED-SHADOW-LABEL: define i40 @test_load40
975; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
976; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
977; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
978; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
979; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_loadN(i64 [[TMP0]], i64 5)
980; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
981; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i40 [[B]]
982;
983; RECOVER-ZERO-BASED-SHADOW-LABEL: define i40 @test_load40
984; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR0]] {
985; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
986; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
987; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
988; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_loadN_noabort(i64 [[TMP0]], i64 5)
989; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i40, ptr [[A]], align 4
990; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i40 [[B]]
991;
992entry:
993  %b = load i40, ptr %a, align 4
994  ret i40 %b
995}
996
997define void @test_store8(ptr %a, i8 %b) sanitize_hwaddress {
998; CHECK-LABEL: define void @test_store8
999; CHECK-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1000; CHECK-NEXT:  entry:
1001; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1002; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1003; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1004; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1005; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1006; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1007; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1008; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1009; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1010; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1011; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1012; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1013; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1014; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1015; CHECK:       12:
1016; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 16)
1017; CHECK-NEXT:    br label [[TMP13]]
1018; CHECK:       13:
1019; CHECK-NEXT:    store i8 [[B]], ptr [[A]], align 4
1020; CHECK-NEXT:    ret void
1021;
1022; NOFASTPATH-LABEL: define void @test_store8
1023; NOFASTPATH-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1024; NOFASTPATH-NEXT:  entry:
1025; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1026; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1027; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1028; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1029; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1030; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 16)
1031; NOFASTPATH-NEXT:    store i8 [[B]], ptr [[A]], align 4
1032; NOFASTPATH-NEXT:    ret void
1033;
1034; FASTPATH-LABEL: define void @test_store8
1035; FASTPATH-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1036; FASTPATH-NEXT:  entry:
1037; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1038; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1039; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1040; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1041; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1042; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1043; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1044; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1045; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1046; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1047; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1048; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1049; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1050; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1051; FASTPATH:       12:
1052; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 16)
1053; FASTPATH-NEXT:    br label [[TMP13]]
1054; FASTPATH:       13:
1055; FASTPATH-NEXT:    store i8 [[B]], ptr [[A]], align 4
1056; FASTPATH-NEXT:    ret void
1057;
1058; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store8
1059; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1060; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1061; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1062; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1063; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1064; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1065; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1066; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1067; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1068; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1069; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1070; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1071; ABORT-DYNAMIC-SHADOW:       8:
1072; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 16)
1073; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
1074; ABORT-DYNAMIC-SHADOW:       9:
1075; ABORT-DYNAMIC-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
1076; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1077;
1078; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store8
1079; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1080; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1081; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1082; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1083; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1084; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1085; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1086; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1087; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1088; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1089; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1090; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1091; RECOVER-DYNAMIC-SHADOW:       8:
1092; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1093; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1094; RECOVER-DYNAMIC-SHADOW:       10:
1095; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 112", "{x10}"(i64 [[TMP0]])
1096; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1097; RECOVER-DYNAMIC-SHADOW:       11:
1098; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1099; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1100; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
1101; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1102; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1103; RECOVER-DYNAMIC-SHADOW:       16:
1104; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1105; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1106; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1107; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1108; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1109; RECOVER-DYNAMIC-SHADOW:       21:
1110; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1111; RECOVER-DYNAMIC-SHADOW:       22:
1112; RECOVER-DYNAMIC-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
1113; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1114;
1115; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store8
1116; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1117; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1118; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1119; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1120; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1121; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1122; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1123; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1124; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1125; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1126; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1127; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1128; ABORT-ZERO-BASED-SHADOW:       8:
1129; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 16)
1130; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
1131; ABORT-ZERO-BASED-SHADOW:       9:
1132; ABORT-ZERO-BASED-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
1133; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1134;
1135; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store8
1136; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i8 [[B:%.*]]) #[[ATTR0]] {
1137; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1138; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1139; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1140; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1141; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1142; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1143; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1144; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1145; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1146; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1147; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1148; RECOVER-ZERO-BASED-SHADOW:       8:
1149; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1150; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1151; RECOVER-ZERO-BASED-SHADOW:       10:
1152; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 112", "{x10}"(i64 [[TMP0]])
1153; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1154; RECOVER-ZERO-BASED-SHADOW:       11:
1155; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1156; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1157; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 0
1158; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1159; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1160; RECOVER-ZERO-BASED-SHADOW:       16:
1161; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1162; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1163; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1164; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1165; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1166; RECOVER-ZERO-BASED-SHADOW:       21:
1167; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1168; RECOVER-ZERO-BASED-SHADOW:       22:
1169; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i8 [[B]], ptr [[A]], align 4
1170; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1171;
1172entry:
1173  store i8 %b, ptr %a, align 4
1174  ret void
1175}
1176
1177define void @test_store16(ptr %a, i16 %b) sanitize_hwaddress {
1178; CHECK-LABEL: define void @test_store16
1179; CHECK-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1180; CHECK-NEXT:  entry:
1181; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1182; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1183; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1184; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1185; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1186; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1187; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1188; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1189; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1190; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1191; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1192; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1193; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1194; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1195; CHECK:       12:
1196; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 17)
1197; CHECK-NEXT:    br label [[TMP13]]
1198; CHECK:       13:
1199; CHECK-NEXT:    store i16 [[B]], ptr [[A]], align 4
1200; CHECK-NEXT:    ret void
1201;
1202; NOFASTPATH-LABEL: define void @test_store16
1203; NOFASTPATH-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1204; NOFASTPATH-NEXT:  entry:
1205; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1206; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1207; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1208; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1209; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1210; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 17)
1211; NOFASTPATH-NEXT:    store i16 [[B]], ptr [[A]], align 4
1212; NOFASTPATH-NEXT:    ret void
1213;
1214; FASTPATH-LABEL: define void @test_store16
1215; FASTPATH-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1216; FASTPATH-NEXT:  entry:
1217; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1218; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1219; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1220; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1221; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1222; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1223; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1224; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1225; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1226; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1227; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1228; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1229; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1230; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1231; FASTPATH:       12:
1232; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 17)
1233; FASTPATH-NEXT:    br label [[TMP13]]
1234; FASTPATH:       13:
1235; FASTPATH-NEXT:    store i16 [[B]], ptr [[A]], align 4
1236; FASTPATH-NEXT:    ret void
1237;
1238; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store16
1239; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1240; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1241; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1242; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1243; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1244; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1245; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1246; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1247; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1248; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1249; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1250; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1251; ABORT-DYNAMIC-SHADOW:       8:
1252; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 17)
1253; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
1254; ABORT-DYNAMIC-SHADOW:       9:
1255; ABORT-DYNAMIC-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
1256; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1257;
1258; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store16
1259; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1260; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1261; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1262; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1263; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1264; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1265; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1266; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1267; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1268; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1269; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1270; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1271; RECOVER-DYNAMIC-SHADOW:       8:
1272; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1273; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1274; RECOVER-DYNAMIC-SHADOW:       10:
1275; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 113", "{x10}"(i64 [[TMP0]])
1276; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1277; RECOVER-DYNAMIC-SHADOW:       11:
1278; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1279; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1280; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
1281; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1282; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1283; RECOVER-DYNAMIC-SHADOW:       16:
1284; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1285; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1286; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1287; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1288; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1289; RECOVER-DYNAMIC-SHADOW:       21:
1290; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1291; RECOVER-DYNAMIC-SHADOW:       22:
1292; RECOVER-DYNAMIC-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
1293; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1294;
1295; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store16
1296; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1297; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1298; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1299; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1300; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1301; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1302; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1303; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1304; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1305; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1306; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1307; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1308; ABORT-ZERO-BASED-SHADOW:       8:
1309; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 17)
1310; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
1311; ABORT-ZERO-BASED-SHADOW:       9:
1312; ABORT-ZERO-BASED-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
1313; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1314;
1315; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store16
1316; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i16 [[B:%.*]]) #[[ATTR0]] {
1317; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1318; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1319; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1320; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1321; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1322; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1323; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1324; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1325; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1326; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1327; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1328; RECOVER-ZERO-BASED-SHADOW:       8:
1329; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1330; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1331; RECOVER-ZERO-BASED-SHADOW:       10:
1332; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 113", "{x10}"(i64 [[TMP0]])
1333; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1334; RECOVER-ZERO-BASED-SHADOW:       11:
1335; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1336; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1337; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 1
1338; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1339; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1340; RECOVER-ZERO-BASED-SHADOW:       16:
1341; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1342; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1343; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1344; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1345; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1346; RECOVER-ZERO-BASED-SHADOW:       21:
1347; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1348; RECOVER-ZERO-BASED-SHADOW:       22:
1349; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i16 [[B]], ptr [[A]], align 4
1350; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1351;
1352entry:
1353  store i16 %b, ptr %a, align 4
1354  ret void
1355}
1356
1357define void @test_store32(ptr %a, i32 %b) sanitize_hwaddress {
1358; CHECK-LABEL: define void @test_store32
1359; CHECK-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1360; CHECK-NEXT:  entry:
1361; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1362; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1363; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1364; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1365; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1366; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1367; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1368; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1369; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1370; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1371; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1372; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1373; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1374; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1375; CHECK:       12:
1376; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 18)
1377; CHECK-NEXT:    br label [[TMP13]]
1378; CHECK:       13:
1379; CHECK-NEXT:    store i32 [[B]], ptr [[A]], align 4
1380; CHECK-NEXT:    ret void
1381;
1382; NOFASTPATH-LABEL: define void @test_store32
1383; NOFASTPATH-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1384; NOFASTPATH-NEXT:  entry:
1385; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1386; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1387; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1388; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1389; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1390; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 18)
1391; NOFASTPATH-NEXT:    store i32 [[B]], ptr [[A]], align 4
1392; NOFASTPATH-NEXT:    ret void
1393;
1394; FASTPATH-LABEL: define void @test_store32
1395; FASTPATH-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1396; FASTPATH-NEXT:  entry:
1397; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1398; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1399; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1400; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1401; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1402; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1403; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1404; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1405; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1406; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1407; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1408; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1409; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1410; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1411; FASTPATH:       12:
1412; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 18)
1413; FASTPATH-NEXT:    br label [[TMP13]]
1414; FASTPATH:       13:
1415; FASTPATH-NEXT:    store i32 [[B]], ptr [[A]], align 4
1416; FASTPATH-NEXT:    ret void
1417;
1418; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store32
1419; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1420; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1421; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1422; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1423; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1424; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1425; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1426; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1427; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1428; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1429; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1430; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1431; ABORT-DYNAMIC-SHADOW:       8:
1432; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 18)
1433; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
1434; ABORT-DYNAMIC-SHADOW:       9:
1435; ABORT-DYNAMIC-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1436; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1437;
1438; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store32
1439; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1440; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1441; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1442; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1443; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1444; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1445; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1446; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1447; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1448; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1449; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1450; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1451; RECOVER-DYNAMIC-SHADOW:       8:
1452; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1453; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1454; RECOVER-DYNAMIC-SHADOW:       10:
1455; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 114", "{x10}"(i64 [[TMP0]])
1456; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1457; RECOVER-DYNAMIC-SHADOW:       11:
1458; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1459; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1460; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
1461; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1462; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1463; RECOVER-DYNAMIC-SHADOW:       16:
1464; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1465; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1466; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1467; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1468; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1469; RECOVER-DYNAMIC-SHADOW:       21:
1470; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1471; RECOVER-DYNAMIC-SHADOW:       22:
1472; RECOVER-DYNAMIC-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1473; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1474;
1475; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store32
1476; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1477; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1478; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1479; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1480; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1481; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1482; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1483; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1484; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1485; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1486; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1487; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1488; ABORT-ZERO-BASED-SHADOW:       8:
1489; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 18)
1490; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
1491; ABORT-ZERO-BASED-SHADOW:       9:
1492; ABORT-ZERO-BASED-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1493; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1494;
1495; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store32
1496; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0]] {
1497; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1498; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1499; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1500; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1501; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1502; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1503; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1504; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1505; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1506; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1507; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1508; RECOVER-ZERO-BASED-SHADOW:       8:
1509; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1510; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1511; RECOVER-ZERO-BASED-SHADOW:       10:
1512; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 114", "{x10}"(i64 [[TMP0]])
1513; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1514; RECOVER-ZERO-BASED-SHADOW:       11:
1515; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1516; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1517; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 3
1518; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1519; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1520; RECOVER-ZERO-BASED-SHADOW:       16:
1521; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1522; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1523; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1524; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1525; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1526; RECOVER-ZERO-BASED-SHADOW:       21:
1527; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1528; RECOVER-ZERO-BASED-SHADOW:       22:
1529; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i32 [[B]], ptr [[A]], align 4
1530; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1531;
1532entry:
1533  store i32 %b, ptr %a, align 4
1534  ret void
1535}
1536
1537define void @test_store64(ptr %a, i64 %b) sanitize_hwaddress {
1538; CHECK-LABEL: define void @test_store64
1539; CHECK-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1540; CHECK-NEXT:  entry:
1541; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1542; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1543; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1544; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1545; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1546; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1547; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1548; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1549; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1550; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1551; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1552; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1553; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1554; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1555; CHECK:       12:
1556; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 19)
1557; CHECK-NEXT:    br label [[TMP13]]
1558; CHECK:       13:
1559; CHECK-NEXT:    store i64 [[B]], ptr [[A]], align 8
1560; CHECK-NEXT:    ret void
1561;
1562; NOFASTPATH-LABEL: define void @test_store64
1563; NOFASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1564; NOFASTPATH-NEXT:  entry:
1565; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1566; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1567; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1568; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1569; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1570; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 19)
1571; NOFASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 8
1572; NOFASTPATH-NEXT:    ret void
1573;
1574; FASTPATH-LABEL: define void @test_store64
1575; FASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1576; FASTPATH-NEXT:  entry:
1577; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1578; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1579; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1580; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1581; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1582; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1583; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1584; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1585; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1586; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1587; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1588; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1589; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1590; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1591; FASTPATH:       12:
1592; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 19)
1593; FASTPATH-NEXT:    br label [[TMP13]]
1594; FASTPATH:       13:
1595; FASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 8
1596; FASTPATH-NEXT:    ret void
1597;
1598; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store64
1599; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1600; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1601; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1602; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1603; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1604; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1605; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1606; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1607; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1608; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1609; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1610; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1611; ABORT-DYNAMIC-SHADOW:       8:
1612; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 19)
1613; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
1614; ABORT-DYNAMIC-SHADOW:       9:
1615; ABORT-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1616; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1617;
1618; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store64
1619; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1620; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1621; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1622; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1623; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1624; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1625; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1626; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1627; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1628; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1629; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1630; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1631; RECOVER-DYNAMIC-SHADOW:       8:
1632; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1633; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1634; RECOVER-DYNAMIC-SHADOW:       10:
1635; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 115", "{x10}"(i64 [[TMP0]])
1636; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1637; RECOVER-DYNAMIC-SHADOW:       11:
1638; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1639; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1640; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
1641; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1642; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1643; RECOVER-DYNAMIC-SHADOW:       16:
1644; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1645; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1646; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1647; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1648; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1649; RECOVER-DYNAMIC-SHADOW:       21:
1650; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1651; RECOVER-DYNAMIC-SHADOW:       22:
1652; RECOVER-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1653; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1654;
1655; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store64
1656; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1657; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1658; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1659; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1660; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1661; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1662; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1663; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1664; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1665; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1666; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1667; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1668; ABORT-ZERO-BASED-SHADOW:       8:
1669; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 19)
1670; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
1671; ABORT-ZERO-BASED-SHADOW:       9:
1672; ABORT-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1673; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1674;
1675; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store64
1676; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1677; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1678; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1679; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1680; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1681; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1682; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1683; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1684; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1685; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1686; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1687; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1688; RECOVER-ZERO-BASED-SHADOW:       8:
1689; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1690; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1691; RECOVER-ZERO-BASED-SHADOW:       10:
1692; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 115", "{x10}"(i64 [[TMP0]])
1693; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1694; RECOVER-ZERO-BASED-SHADOW:       11:
1695; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1696; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1697; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 7
1698; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1699; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1700; RECOVER-ZERO-BASED-SHADOW:       16:
1701; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1702; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1703; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1704; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1705; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1706; RECOVER-ZERO-BASED-SHADOW:       21:
1707; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1708; RECOVER-ZERO-BASED-SHADOW:       22:
1709; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 8
1710; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1711;
1712entry:
1713  store i64 %b, ptr %a, align 8
1714  ret void
1715}
1716
1717define void @test_store128(ptr %a, i128 %b) sanitize_hwaddress {
1718; CHECK-LABEL: define void @test_store128
1719; CHECK-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1720; CHECK-NEXT:  entry:
1721; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1722; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1723; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1724; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1725; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1726; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1727; CHECK-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1728; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1729; CHECK-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1730; CHECK-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1731; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1732; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1733; CHECK-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1734; CHECK-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1735; CHECK:       12:
1736; CHECK-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 20)
1737; CHECK-NEXT:    br label [[TMP13]]
1738; CHECK:       13:
1739; CHECK-NEXT:    store i128 [[B]], ptr [[A]], align 16
1740; CHECK-NEXT:    ret void
1741;
1742; NOFASTPATH-LABEL: define void @test_store128
1743; NOFASTPATH-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1744; NOFASTPATH-NEXT:  entry:
1745; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1746; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1747; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1748; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1749; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1750; NOFASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 20)
1751; NOFASTPATH-NEXT:    store i128 [[B]], ptr [[A]], align 16
1752; NOFASTPATH-NEXT:    ret void
1753;
1754; FASTPATH-LABEL: define void @test_store128
1755; FASTPATH-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1756; FASTPATH-NEXT:  entry:
1757; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1758; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1759; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1760; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1761; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1762; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1763; FASTPATH-NEXT:    [[TMP5:%.*]] = lshr i64 [[TMP4]], 56
1764; FASTPATH-NEXT:    [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8
1765; FASTPATH-NEXT:    [[TMP7:%.*]] = and i64 [[TMP4]], 72057594037927935
1766; FASTPATH-NEXT:    [[TMP8:%.*]] = lshr i64 [[TMP7]], 4
1767; FASTPATH-NEXT:    [[TMP9:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[TMP8]]
1768; FASTPATH-NEXT:    [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 1
1769; FASTPATH-NEXT:    [[TMP11:%.*]] = icmp ne i8 [[TMP6]], [[TMP10]]
1770; FASTPATH-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP13:%.*]], !prof [[PROF2]]
1771; FASTPATH:       12:
1772; FASTPATH-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[TMP3]], ptr [[A]], i32 20)
1773; FASTPATH-NEXT:    br label [[TMP13]]
1774; FASTPATH:       13:
1775; FASTPATH-NEXT:    store i128 [[B]], ptr [[A]], align 16
1776; FASTPATH-NEXT:    ret void
1777;
1778; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store128
1779; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1780; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1781; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1782; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1783; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1784; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1785; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1786; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1787; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1788; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1789; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1790; ABORT-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1791; ABORT-DYNAMIC-SHADOW:       8:
1792; ABORT-DYNAMIC-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 20)
1793; ABORT-DYNAMIC-SHADOW-NEXT:    br label [[TMP9]]
1794; ABORT-DYNAMIC-SHADOW:       9:
1795; ABORT-DYNAMIC-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1796; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1797;
1798; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store128
1799; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1800; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1801; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1802; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1803; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1804; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1805; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1806; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1807; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP5:%.*]] = getelementptr i8, ptr [[DOTHWASAN_SHADOW]], i64 [[TMP4]]
1808; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1809; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1810; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1811; RECOVER-DYNAMIC-SHADOW:       8:
1812; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1813; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1814; RECOVER-DYNAMIC-SHADOW:       10:
1815; RECOVER-DYNAMIC-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 116", "{x10}"(i64 [[TMP0]])
1816; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP21:%.*]]
1817; RECOVER-DYNAMIC-SHADOW:       11:
1818; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1819; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1820; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
1821; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1822; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1823; RECOVER-DYNAMIC-SHADOW:       16:
1824; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1825; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1826; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1827; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1828; RECOVER-DYNAMIC-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1829; RECOVER-DYNAMIC-SHADOW:       21:
1830; RECOVER-DYNAMIC-SHADOW-NEXT:    br label [[TMP22]]
1831; RECOVER-DYNAMIC-SHADOW:       22:
1832; RECOVER-DYNAMIC-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1833; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1834;
1835; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store128
1836; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1837; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1838; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1839; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1840; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1841; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1842; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1843; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1844; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1845; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1846; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1847; ABORT-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP9:%.*]], !prof [[PROF2]]
1848; ABORT-ZERO-BASED-SHADOW:       8:
1849; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @llvm.hwasan.check.memaccess.shortgranules(ptr [[DOTHWASAN_SHADOW]], ptr [[A]], i32 20)
1850; ABORT-ZERO-BASED-SHADOW-NEXT:    br label [[TMP9]]
1851; ABORT-ZERO-BASED-SHADOW:       9:
1852; ABORT-ZERO-BASED-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1853; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1854;
1855; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store128
1856; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i128 [[B:%.*]]) #[[ATTR0]] {
1857; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1858; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1859; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1860; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP1:%.*]] = lshr i64 [[TMP0]], 56
1861; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i8
1862; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], 72057594037927935
1863; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP4:%.*]] = lshr i64 [[TMP3]], 4
1864; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr
1865; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
1866; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP7:%.*]] = icmp ne i8 [[TMP2]], [[TMP6]]
1867; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP22:%.*]], !prof [[PROF2]]
1868; RECOVER-ZERO-BASED-SHADOW:       8:
1869; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP9:%.*]] = icmp ugt i8 [[TMP6]], 15
1870; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP9]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF2]]
1871; RECOVER-ZERO-BASED-SHADOW:       10:
1872; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void asm sideeffect "ebreak\0Aaddiw x0, x11, 116", "{x10}"(i64 [[TMP0]])
1873; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP21:%.*]]
1874; RECOVER-ZERO-BASED-SHADOW:       11:
1875; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP12:%.*]] = and i64 [[TMP0]], 15
1876; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP13:%.*]] = trunc i64 [[TMP12]] to i8
1877; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP14:%.*]] = add i8 [[TMP13]], 15
1878; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP15:%.*]] = icmp uge i8 [[TMP14]], [[TMP6]]
1879; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP15]], label [[TMP10]], label [[TMP16:%.*]], !prof [[PROF2]]
1880; RECOVER-ZERO-BASED-SHADOW:       16:
1881; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP17:%.*]] = or i64 [[TMP3]], 15
1882; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP18:%.*]] = inttoptr i64 [[TMP17]] to ptr
1883; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP19:%.*]] = load i8, ptr [[TMP18]], align 1
1884; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP20:%.*]] = icmp ne i8 [[TMP2]], [[TMP19]]
1885; RECOVER-ZERO-BASED-SHADOW-NEXT:    br i1 [[TMP20]], label [[TMP10]], label [[TMP21]], !prof [[PROF2]]
1886; RECOVER-ZERO-BASED-SHADOW:       21:
1887; RECOVER-ZERO-BASED-SHADOW-NEXT:    br label [[TMP22]]
1888; RECOVER-ZERO-BASED-SHADOW:       22:
1889; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i128 [[B]], ptr [[A]], align 16
1890; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1891;
1892entry:
1893  store i128 %b, ptr %a, align 16
1894  ret void
1895}
1896
1897define void @test_store40(ptr %a, i40 %b) sanitize_hwaddress {
1898; CHECK-LABEL: define void @test_store40
1899; CHECK-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1900; CHECK-NEXT:  entry:
1901; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1902; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1903; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1904; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1905; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1906; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1907; CHECK-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 5)
1908; CHECK-NEXT:    store i40 [[B]], ptr [[A]], align 4
1909; CHECK-NEXT:    ret void
1910;
1911; NOFASTPATH-LABEL: define void @test_store40
1912; NOFASTPATH-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1913; NOFASTPATH-NEXT:  entry:
1914; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1915; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1916; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1917; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1918; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1919; NOFASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1920; NOFASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 5)
1921; NOFASTPATH-NEXT:    store i40 [[B]], ptr [[A]], align 4
1922; NOFASTPATH-NEXT:    ret void
1923;
1924; FASTPATH-LABEL: define void @test_store40
1925; FASTPATH-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1926; FASTPATH-NEXT:  entry:
1927; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1928; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1929; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1930; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1931; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1932; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1933; FASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 5)
1934; FASTPATH-NEXT:    store i40 [[B]], ptr [[A]], align 4
1935; FASTPATH-NEXT:    ret void
1936;
1937; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store40
1938; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1939; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
1940; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1941; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1942; ABORT-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1943; ABORT-DYNAMIC-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1944; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
1945;
1946; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store40
1947; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1948; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
1949; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
1950; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1951; RECOVER-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 5)
1952; RECOVER-DYNAMIC-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1953; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
1954;
1955; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store40
1956; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1957; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
1958; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1959; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1960; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 5)
1961; ABORT-ZERO-BASED-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1962; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
1963;
1964; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store40
1965; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i40 [[B:%.*]]) #[[ATTR0]] {
1966; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
1967; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
1968; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
1969; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 5)
1970; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i40 [[B]], ptr [[A]], align 4
1971; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
1972;
1973entry:
1974  store i40 %b, ptr %a, align 4
1975  ret void
1976}
1977
1978define void @test_store_unaligned(ptr %a, i64 %b) sanitize_hwaddress {
1979; CHECK-LABEL: define void @test_store_unaligned
1980; CHECK-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1981; CHECK-NEXT:  entry:
1982; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1983; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1984; CHECK-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1985; CHECK-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1986; CHECK-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
1987; CHECK-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
1988; CHECK-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 8)
1989; CHECK-NEXT:    store i64 [[B]], ptr [[A]], align 4
1990; CHECK-NEXT:    ret void
1991;
1992; NOFASTPATH-LABEL: define void @test_store_unaligned
1993; NOFASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
1994; NOFASTPATH-NEXT:  entry:
1995; NOFASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
1996; NOFASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
1997; NOFASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
1998; NOFASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
1999; NOFASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
2000; NOFASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
2001; NOFASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 8)
2002; NOFASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 4
2003; NOFASTPATH-NEXT:    ret void
2004;
2005; FASTPATH-LABEL: define void @test_store_unaligned
2006; FASTPATH-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
2007; FASTPATH-NEXT:  entry:
2008; FASTPATH-NEXT:    [[TMP0:%.*]] = load i64, ptr @__hwasan_tls, align 8
2009; FASTPATH-NEXT:    [[TMP1:%.*]] = and i64 [[TMP0]], 72057594037927935
2010; FASTPATH-NEXT:    [[TMP2:%.*]] = or i64 [[TMP1]], 4294967295
2011; FASTPATH-NEXT:    [[HWASAN_SHADOW:%.*]] = add i64 [[TMP2]], 1
2012; FASTPATH-NEXT:    [[TMP3:%.*]] = inttoptr i64 [[HWASAN_SHADOW]] to ptr
2013; FASTPATH-NEXT:    [[TMP4:%.*]] = ptrtoint ptr [[A]] to i64
2014; FASTPATH-NEXT:    call void @__hwasan_storeN(i64 [[TMP4]], i64 8)
2015; FASTPATH-NEXT:    store i64 [[B]], ptr [[A]], align 4
2016; FASTPATH-NEXT:    ret void
2017;
2018; ABORT-DYNAMIC-SHADOW-LABEL: define void @test_store_unaligned
2019; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
2020; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
2021; ABORT-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
2022; ABORT-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
2023; ABORT-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
2024; ABORT-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
2025; ABORT-DYNAMIC-SHADOW-NEXT:    ret void
2026;
2027; RECOVER-DYNAMIC-SHADOW-LABEL: define void @test_store_unaligned
2028; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
2029; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
2030; RECOVER-DYNAMIC-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr @__hwasan_shadow)
2031; RECOVER-DYNAMIC-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
2032; RECOVER-DYNAMIC-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 8)
2033; RECOVER-DYNAMIC-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
2034; RECOVER-DYNAMIC-SHADOW-NEXT:    ret void
2035;
2036; ABORT-ZERO-BASED-SHADOW-LABEL: define void @test_store_unaligned
2037; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
2038; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
2039; ABORT-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
2040; ABORT-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
2041; ABORT-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN(i64 [[TMP0]], i64 8)
2042; ABORT-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
2043; ABORT-ZERO-BASED-SHADOW-NEXT:    ret void
2044;
2045; RECOVER-ZERO-BASED-SHADOW-LABEL: define void @test_store_unaligned
2046; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
2047; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
2048; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[DOTHWASAN_SHADOW:%.*]] = call ptr asm "", "=r,0"(ptr null)
2049; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64
2050; RECOVER-ZERO-BASED-SHADOW-NEXT:    call void @__hwasan_storeN_noabort(i64 [[TMP0]], i64 8)
2051; RECOVER-ZERO-BASED-SHADOW-NEXT:    store i64 [[B]], ptr [[A]], align 4
2052; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret void
2053;
2054entry:
2055  store i64 %b, ptr %a, align 4
2056  ret void
2057}
2058
2059define i8 @test_load_noattr(ptr %a) {
2060; CHECK-LABEL: define i8 @test_load_noattr
2061; CHECK-SAME: (ptr [[A:%.*]]) {
2062; CHECK-NEXT:  entry:
2063; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2064; CHECK-NEXT:    ret i8 [[B]]
2065;
2066; NOFASTPATH-LABEL: define i8 @test_load_noattr
2067; NOFASTPATH-SAME: (ptr [[A:%.*]]) {
2068; NOFASTPATH-NEXT:  entry:
2069; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2070; NOFASTPATH-NEXT:    ret i8 [[B]]
2071;
2072; FASTPATH-LABEL: define i8 @test_load_noattr
2073; FASTPATH-SAME: (ptr [[A:%.*]]) {
2074; FASTPATH-NEXT:  entry:
2075; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2076; FASTPATH-NEXT:    ret i8 [[B]]
2077;
2078; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load_noattr
2079; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) {
2080; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
2081; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2082; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
2083;
2084; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load_noattr
2085; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) {
2086; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
2087; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2088; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
2089;
2090; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_noattr
2091; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) {
2092; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
2093; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2094; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
2095;
2096; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_noattr
2097; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) {
2098; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
2099; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2100; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
2101;
2102entry:
2103  %b = load i8, ptr %a, align 4
2104  ret i8 %b
2105}
2106
2107define i8 @test_load_notmyattr(ptr %a) sanitize_address {
2108; CHECK-LABEL: define i8 @test_load_notmyattr
2109; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2110; CHECK-NEXT:  entry:
2111; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2112; CHECK-NEXT:    ret i8 [[B]]
2113;
2114; NOFASTPATH-LABEL: define i8 @test_load_notmyattr
2115; NOFASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2116; NOFASTPATH-NEXT:  entry:
2117; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2118; NOFASTPATH-NEXT:    ret i8 [[B]]
2119;
2120; FASTPATH-LABEL: define i8 @test_load_notmyattr
2121; FASTPATH-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2122; FASTPATH-NEXT:  entry:
2123; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2124; FASTPATH-NEXT:    ret i8 [[B]]
2125;
2126; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load_notmyattr
2127; ABORT-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2128; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
2129; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2130; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
2131;
2132; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load_notmyattr
2133; RECOVER-DYNAMIC-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2134; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
2135; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2136; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
2137;
2138; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_notmyattr
2139; ABORT-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2140; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
2141; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2142; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
2143;
2144; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_notmyattr
2145; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
2146; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
2147; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr [[A]], align 4
2148; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
2149;
2150entry:
2151  %b = load i8, ptr %a, align 4
2152  ret i8 %b
2153}
2154
2155define i8 @test_load_addrspace(ptr addrspace(256) %a) sanitize_hwaddress {
2156; CHECK-LABEL: define i8 @test_load_addrspace
2157; CHECK-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2158; CHECK-NEXT:  entry:
2159; CHECK-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2160; CHECK-NEXT:    ret i8 [[B]]
2161;
2162; NOFASTPATH-LABEL: define i8 @test_load_addrspace
2163; NOFASTPATH-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2164; NOFASTPATH-NEXT:  entry:
2165; NOFASTPATH-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2166; NOFASTPATH-NEXT:    ret i8 [[B]]
2167;
2168; FASTPATH-LABEL: define i8 @test_load_addrspace
2169; FASTPATH-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2170; FASTPATH-NEXT:  entry:
2171; FASTPATH-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2172; FASTPATH-NEXT:    ret i8 [[B]]
2173;
2174; ABORT-DYNAMIC-SHADOW-LABEL: define i8 @test_load_addrspace
2175; ABORT-DYNAMIC-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2176; ABORT-DYNAMIC-SHADOW-NEXT:  entry:
2177; ABORT-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2178; ABORT-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
2179;
2180; RECOVER-DYNAMIC-SHADOW-LABEL: define i8 @test_load_addrspace
2181; RECOVER-DYNAMIC-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2182; RECOVER-DYNAMIC-SHADOW-NEXT:  entry:
2183; RECOVER-DYNAMIC-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2184; RECOVER-DYNAMIC-SHADOW-NEXT:    ret i8 [[B]]
2185;
2186; ABORT-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_addrspace
2187; ABORT-ZERO-BASED-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2188; ABORT-ZERO-BASED-SHADOW-NEXT:  entry:
2189; ABORT-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2190; ABORT-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
2191;
2192; RECOVER-ZERO-BASED-SHADOW-LABEL: define i8 @test_load_addrspace
2193; RECOVER-ZERO-BASED-SHADOW-SAME: (ptr addrspace(256) [[A:%.*]]) #[[ATTR0]] {
2194; RECOVER-ZERO-BASED-SHADOW-NEXT:  entry:
2195; RECOVER-ZERO-BASED-SHADOW-NEXT:    [[B:%.*]] = load i8, ptr addrspace(256) [[A]], align 4
2196; RECOVER-ZERO-BASED-SHADOW-NEXT:    ret i8 [[B]]
2197;
2198entry:
2199  %b = load i8, ptr addrspace(256) %a, align 4
2200  ret i8 %b
2201}
2202
2203