1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt < %s -aarch64-stack-tagging -S -o - | FileCheck %s
4 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5 target triple = "aarch64--linux-android"
8 declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
9 declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
10 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
12 define void @OneVarNoInit() sanitize_memtag {
13 ; CHECK-LABEL: define void @OneVarNoInit(
14 ; CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
15 ; CHECK-NEXT: [[ENTRY:.*:]]
16 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
17 ; CHECK-NEXT: [[X:%.*]] = alloca { i32, [12 x i8] }, align 16
18 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
19 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]])
20 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[TX]], i64 16)
21 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
22 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16)
23 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]])
24 ; CHECK-NEXT: ret void
27 %x = alloca i32, align 4
28 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
29 call void @use(ptr nonnull %x)
30 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
35 define void @OneVarInitConst() sanitize_memtag {
36 ; CHECK-LABEL: define void @OneVarInitConst(
37 ; CHECK-SAME: ) #[[ATTR2]] {
38 ; CHECK-NEXT: [[ENTRY:.*:]]
39 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
40 ; CHECK-NEXT: [[X:%.*]] = alloca { i32, [12 x i8] }, align 16
41 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
42 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]])
43 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 42, i64 0)
44 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
45 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16)
46 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]])
47 ; CHECK-NEXT: ret void
50 %x = alloca i32, align 4
51 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
52 store i32 42, ptr %x, align 4
53 call void @use(ptr nonnull %x)
54 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
58 ; Untagging before lifetime.end:
60 define void @ArrayInitConst() sanitize_memtag {
61 ; CHECK-LABEL: define void @ArrayInitConst(
62 ; CHECK-SAME: ) #[[ATTR2]] {
63 ; CHECK-NEXT: [[ENTRY:.*:]]
64 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
65 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 16, align 16
66 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
67 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr nonnull [[X]])
68 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 42, i64 0)
69 ; CHECK-NEXT: [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16
70 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_16]], i64 48)
71 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
72 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 64)
73 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr nonnull [[X]])
74 ; CHECK-NEXT: ret void
77 %x = alloca i32, i32 16, align 4
78 call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x)
79 store i32 42, ptr %x, align 4
80 call void @use(ptr nonnull %x)
81 call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x)
86 define void @ArrayInitConst2() sanitize_memtag {
87 ; CHECK-LABEL: define void @ArrayInitConst2(
88 ; CHECK-SAME: ) #[[ATTR2]] {
89 ; CHECK-NEXT: [[ENTRY:.*:]]
90 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
91 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 16, align 16
92 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
93 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr nonnull [[X]])
94 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 1
95 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[TX]], i32 2
96 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 184683593770, i64 -1)
97 ; CHECK-NEXT: [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16
98 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_16]], i64 48)
99 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
100 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 64)
101 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr nonnull [[X]])
102 ; CHECK-NEXT: ret void
105 %x = alloca i32, i32 16, align 4
106 call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x)
107 store i32 42, ptr %x, align 4
108 %0 = getelementptr i32, ptr %x, i32 1
109 store i32 43, ptr %0, align 4
110 %1 = getelementptr i32, ptr %x, i32 2
111 store i64 -1, ptr %1, align 4
112 call void @use(ptr nonnull %x)
113 call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x)
118 define void @ArrayInitConstSplit() sanitize_memtag {
119 ; CHECK-LABEL: define void @ArrayInitConstSplit(
120 ; CHECK-SAME: ) #[[ATTR2]] {
121 ; CHECK-NEXT: [[ENTRY:.*:]]
122 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
123 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 16, align 16
124 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
125 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr nonnull [[X]])
126 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 1
127 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 -4294967296, i64 4294967295)
128 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TX]], i32 16
129 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TMP1]], i64 48)
130 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
131 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 64)
132 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr nonnull [[X]])
133 ; CHECK-NEXT: ret void
136 %x = alloca i32, i32 16, align 4
137 call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x)
138 %0 = getelementptr i32, ptr %x, i32 1
139 store i64 -1, ptr %0, align 4
140 call void @use(ptr nonnull %x)
141 call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x)
146 define void @ArrayInitConstWithHoles() sanitize_memtag {
147 ; CHECK-LABEL: define void @ArrayInitConstWithHoles(
148 ; CHECK-SAME: ) #[[ATTR2]] {
149 ; CHECK-NEXT: [[ENTRY:.*:]]
150 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
151 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 32, align 16
152 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
153 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 128, ptr nonnull [[X]])
154 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 5
155 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[TX]], i32 14
156 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX]], i64 16)
157 ; CHECK-NEXT: [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16
158 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX8_16]], i64 180388626432, i64 0)
159 ; CHECK-NEXT: [[TX8_32:%.*]] = getelementptr i8, ptr [[TX]], i32 32
160 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_32]], i64 16)
161 ; CHECK-NEXT: [[TX8_48:%.*]] = getelementptr i8, ptr [[TX]], i32 48
162 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX8_48]], i64 0, i64 43)
163 ; CHECK-NEXT: [[TX8_64:%.*]] = getelementptr i8, ptr [[TX]], i32 64
164 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_64]], i64 64)
165 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
166 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 128)
167 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 128, ptr nonnull [[X]])
168 ; CHECK-NEXT: ret void
171 %x = alloca i32, i32 32, align 4
172 call void @llvm.lifetime.start.p0(i64 128, ptr nonnull %x)
173 %0 = getelementptr i32, ptr %x, i32 5
174 store i32 42, ptr %0, align 4
175 %1 = getelementptr i32, ptr %x, i32 14
176 store i32 43, ptr %1, align 4
177 call void @use(ptr nonnull %x)
178 call void @llvm.lifetime.end.p0(i64 128, ptr nonnull %x)
183 define void @InitNonConst(i32 %v) sanitize_memtag {
184 ; CHECK-LABEL: define void @InitNonConst(
185 ; CHECK-SAME: i32 [[V:%.*]]) #[[ATTR2]] {
186 ; CHECK-NEXT: [[ENTRY:.*:]]
187 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
188 ; CHECK-NEXT: [[X:%.*]] = alloca { i32, [12 x i8] }, align 16
189 ; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
190 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]])
191 ; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[V]] to i64
192 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 [[TMP0]], i64 0)
193 ; CHECK-NEXT: call void @use(ptr nonnull [[X_TAG]])
194 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16)
195 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]])
196 ; CHECK-NEXT: ret void
199 %x = alloca i32, align 4
200 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
201 store i32 %v, ptr %x, align 4
202 call void @use(ptr nonnull %x)
203 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
208 define void @InitNonConst2(i32 %v, i32 %w) sanitize_memtag {
209 ; CHECK-LABEL: define void @InitNonConst2(
210 ; CHECK-SAME: i32 [[V:%.*]], i32 [[W:%.*]]) #[[ATTR2]] {
211 ; CHECK-NEXT: [[ENTRY:.*:]]
212 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
213 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 4, align 16
214 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
215 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[X]])
216 ; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[V]] to i64
217 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[TX]], i32 1
218 ; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[W]] to i64
219 ; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 32
220 ; CHECK-NEXT: [[VW:%.*]] = or i64 [[TMP0]], [[TMP3]]
221 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 [[VW]], i64 0)
222 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
223 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16)
224 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[X]])
225 ; CHECK-NEXT: ret void
228 %x = alloca i32, i32 4, align 4
229 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x)
230 store i32 %v, ptr %x, align 4
231 %0 = getelementptr i32, ptr %x, i32 1
232 store i32 %w, ptr %0, align 4
233 call void @use(ptr nonnull %x)
234 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x)
239 define void @InitVector() sanitize_memtag {
240 ; CHECK-LABEL: define void @InitVector(
241 ; CHECK-SAME: ) #[[ATTR2]] {
242 ; CHECK-NEXT: [[ENTRY:.*:]]
243 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
244 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 4, align 16
245 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
246 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[X]])
247 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), i64 0)
248 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
249 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16)
250 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[X]])
251 ; CHECK-NEXT: ret void
254 %x = alloca i32, i32 4, align 4
255 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x)
256 store <2 x i32> <i32 1, i32 2>, ptr %x, align 4
257 call void @use(ptr nonnull %x)
258 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x)
263 define void @InitVectorPtr(ptr %p) sanitize_memtag {
264 ; CHECK-LABEL: define void @InitVectorPtr(
265 ; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR2]] {
266 ; CHECK-NEXT: [[ENTRY:.*:]]
267 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
268 ; CHECK-NEXT: [[S:%.*]] = alloca <4 x ptr>, align 16
269 ; CHECK-NEXT: [[S_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[S]], ptr [[BASETAG]], i64 0)
270 ; CHECK-NEXT: [[V0:%.*]] = insertelement <4 x ptr> undef, ptr [[P]], i32 0
271 ; CHECK-NEXT: [[V1:%.*]] = shufflevector <4 x ptr> [[V0]], <4 x ptr> undef, <4 x i32> zeroinitializer
272 ; CHECK-NEXT: [[V2:%.*]] = ptrtoint <4 x ptr> [[V1]] to <4 x i64>
273 ; CHECK-NEXT: [[V3:%.*]] = bitcast <4 x i64> [[V2]] to i256
274 ; CHECK-NEXT: [[A1:%.*]] = trunc i256 [[V3]] to i64
275 ; CHECK-NEXT: [[A2_:%.*]] = lshr i256 [[V3]], 64
276 ; CHECK-NEXT: [[A2:%.*]] = trunc i256 [[A2_]] to i64
277 ; CHECK-NEXT: [[A3_:%.*]] = lshr i256 [[V3]], 128
278 ; CHECK-NEXT: [[A3:%.*]] = trunc i256 [[A3_]] to i64
279 ; CHECK-NEXT: [[A4_:%.*]] = lshr i256 [[V3]], 192
280 ; CHECK-NEXT: [[A4:%.*]] = trunc i256 [[A4_]] to i64
281 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[S_TAG]], i64 [[A1]], i64 [[A2]])
282 ; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S_TAG]], i32 16
283 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP9]], i64 [[A3]], i64 [[A4]])
284 ; CHECK-NEXT: call void @use(ptr nonnull [[S_TAG]])
285 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[S]], i64 32)
286 ; CHECK-NEXT: ret void
289 %s = alloca <4 x ptr>, align 8
290 %v0 = insertelement <4 x ptr> undef, ptr %p, i32 0
291 %v1 = shufflevector <4 x ptr> %v0, <4 x ptr> undef, <4 x i32> zeroinitializer
292 store <4 x ptr> %v1, ptr %s
293 call void @use(ptr nonnull %s)
298 define void @InitVectorSplit() sanitize_memtag {
299 ; CHECK-LABEL: define void @InitVectorSplit(
300 ; CHECK-SAME: ) #[[ATTR2]] {
301 ; CHECK-NEXT: [[ENTRY:.*:]]
302 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
303 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 4, align 16
304 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
305 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[X]])
306 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 1
307 ; CHECK-NEXT: [[TMP1:%.*]] = shl i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), 32
308 ; CHECK-NEXT: [[LSHR:%.*]] = lshr i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), 32
309 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 [[TMP1]], i64 [[LSHR]])
310 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
311 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16)
312 ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[X]])
313 ; CHECK-NEXT: ret void
316 %x = alloca i32, i32 4, align 4
317 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x)
318 %0 = getelementptr i32, ptr %x, i32 1
319 store <2 x i32> <i32 1, i32 2>, ptr %0, align 4
320 call void @use(ptr nonnull %x)
321 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x)
326 define void @MemSetZero() sanitize_memtag {
327 ; CHECK-LABEL: define void @MemSetZero(
328 ; CHECK-SAME: ) #[[ATTR2]] {
329 ; CHECK-NEXT: [[ENTRY:.*:]]
330 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
331 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 8, align 16
332 ; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
333 ; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX]], i64 32)
334 ; CHECK-NEXT: call void @use(ptr nonnull [[TX]])
335 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32)
336 ; CHECK-NEXT: ret void
339 %x = alloca i32, i32 8, align 16
340 call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 0, i64 32, i1 false)
341 call void @use(ptr nonnull %x)
347 define void @MemSetNonZero() sanitize_memtag {
348 ; CHECK-LABEL: define void @MemSetNonZero(
349 ; CHECK-SAME: ) #[[ATTR2]] {
350 ; CHECK-NEXT: [[ENTRY:.*:]]
351 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
352 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 8, align 16
353 ; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
354 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 3038287259199220266, i64 3038287259199220266)
355 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[X_TAG]], i32 16
356 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP0]], i64 3038287259199220266, i64 3038287259199220266)
357 ; CHECK-NEXT: call void @use(ptr nonnull [[X_TAG]])
358 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32)
359 ; CHECK-NEXT: ret void
362 %x = alloca i32, i32 8, align 16
363 call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 42, i64 32, i1 false)
364 call void @use(ptr nonnull %x)
370 define void @MemSetNonZero2() sanitize_memtag {
371 ; CHECK-LABEL: define void @MemSetNonZero2(
372 ; CHECK-SAME: ) #[[ATTR2]] {
373 ; CHECK-NEXT: [[ENTRY:.*:]]
374 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
375 ; CHECK-NEXT: [[X:%.*]] = alloca [32 x i8], align 16
376 ; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
377 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [32 x i8], ptr [[X_TAG]], i64 0, i64 2
378 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 3038287259199209472, i64 3038287259199220266)
379 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[X_TAG]], i32 16
380 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP1]], i64 3038287259199220266, i64 46360584399402)
381 ; CHECK-NEXT: call void @use(ptr nonnull [[TMP0]])
382 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32)
383 ; CHECK-NEXT: ret void
386 %x = alloca [32 x i8], align 16
387 %0 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 2
388 call void @llvm.memset.p0.i64(ptr nonnull %0, i8 42, i64 28, i1 false)
389 call void @use(ptr nonnull %0)
394 define void @MemSetNonZero3() sanitize_memtag {
395 ; CHECK-LABEL: define void @MemSetNonZero3(
396 ; CHECK-SAME: ) #[[ATTR2]] {
397 ; CHECK-NEXT: [[ENTRY:.*:]]
398 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
399 ; CHECK-NEXT: [[X:%.*]] = alloca [32 x i8], align 16
400 ; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
401 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [32 x i8], ptr [[X_TAG]], i64 0, i64 2
402 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [32 x i8], ptr [[X_TAG]], i64 0, i64 24
403 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 46360584388608, i64 0)
404 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[X_TAG]], i32 16
405 ; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP2]], i64 0, i64 3038287259199220266)
406 ; CHECK-NEXT: call void @use(ptr nonnull [[TMP0]])
407 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32)
408 ; CHECK-NEXT: ret void
411 %x = alloca [32 x i8], align 16
412 %0 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 2
413 call void @llvm.memset.p0.i64(ptr nonnull %0, i8 42, i64 4, i1 false)
414 %1 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 24
415 call void @llvm.memset.p0.i64(ptr nonnull %1, i8 42, i64 8, i1 false)
416 call void @use(ptr nonnull %0)
421 define void @LargeAlloca() sanitize_memtag {
422 ; CHECK-LABEL: define void @LargeAlloca(
423 ; CHECK-SAME: ) #[[ATTR2]] {
424 ; CHECK-NEXT: [[ENTRY:.*:]]
425 ; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
426 ; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 256, align 16
427 ; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0)
428 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X_TAG]], i64 1024)
429 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr nonnull align 16 [[X_TAG]], i8 42, i64 256, i1 false)
430 ; CHECK-NEXT: call void @use(ptr nonnull [[X_TAG]])
431 ; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 1024)
432 ; CHECK-NEXT: ret void
435 %x = alloca i32, i32 256, align 16
436 call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 42, i64 256, i1 false)
437 call void @use(ptr nonnull %x)