1 ; RUN: llc < %s -mtriple=arm64-eabi -mattr=+mte | FileCheck %s
4 define ptr @create_tag(ptr %ptr, i32 %m) {
6 ; CHECK-LABEL: create_tag:
7 %0 = zext i32 %m to i64
8 %1 = tail call ptr @llvm.aarch64.irg(ptr %ptr, i64 %0)
10 ;CHECK: irg x0, x0, {{x[0-9]+}}
13 ; *********** __arm_mte_increment_tag *************
15 define ptr @increment_tag1(ptr %ptr) {
17 ; CHECK-LABEL: increment_tag1:
18 %0 = tail call ptr @llvm.aarch64.addg(ptr %ptr, i64 7)
20 ; CHECK: addg x0, x0, #0, #7
23 %struct.S2K = type { [512 x i32] }
24 define ptr @increment_tag1stack(ptr %ptr) {
26 ; CHECK-LABEL: increment_tag1stack:
27 %s = alloca %struct.S2K, align 4
28 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)
29 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %s, i64 7)
30 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)
32 ; CHECK: addg x0, sp, #0, #7
36 define ptr @increment_tag2(ptr %ptr) {
38 ; CHECK-LABEL: increment_tag2:
39 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 4
40 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)
42 ; CHECK: addg x0, x0, #16, #7
45 define ptr @increment_tag2stack(ptr %ptr) {
47 ; CHECK-LABEL: increment_tag2stack:
48 %s = alloca %struct.S2K, align 4
49 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)
50 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 4
51 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)
52 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)
54 ; CHECK: addg x0, sp, #16, #7
57 define ptr @increment_tag3(ptr %ptr) {
59 ; CHECK-LABEL: increment_tag3:
60 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 252
61 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)
63 ; CHECK: addg x0, x0, #1008, #7
66 define ptr @increment_tag3stack(ptr %ptr) {
68 ; CHECK-LABEL: increment_tag3stack:
69 %s = alloca %struct.S2K, align 4
70 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)
71 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 252
72 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)
73 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)
75 ; CHECK: addg x0, sp, #1008, #7
79 define ptr @increment_tag4(ptr %ptr) {
81 ; CHECK-LABEL: increment_tag4:
82 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 256
83 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)
85 ; CHECK: add [[T0:x[0-9]+]], x0, #1024
86 ; CHECK-NEXT: addg x0, [[T0]], #0, #7
89 define ptr @increment_tag4stack(ptr %ptr) {
91 ; CHECK-LABEL: increment_tag4stack:
92 %s = alloca %struct.S2K, align 4
93 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)
94 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 256
95 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)
96 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)
98 ; CHECK: add [[T0:x[0-9]+]], {{.*}}, #1024
99 ; CHECK-NEXT: addg x0, [[T0]], #0, #7
103 define ptr @increment_tag5(ptr %ptr) {
105 ; CHECK-LABEL: increment_tag5:
106 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 5
107 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)
109 ; CHECK: add [[T0:x[0-9]+]], x0, #20
110 ; CHECK-NEXT: addg x0, [[T0]], #0, #7
113 define ptr @increment_tag5stack(ptr %ptr) {
115 ; CHECK-LABEL: increment_tag5stack:
116 %s = alloca %struct.S2K, align 4
117 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)
118 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 5
119 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)
120 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)
122 ; CHECK: add [[T0:x[0-9]+]], {{.*}}, #20
123 ; CHECK-NEXT: addg x0, [[T0]], #0, #7
127 ; *********** __arm_mte_exclude_tag *************
129 define i32 @exclude_tag(ptr %ptr, i32 %m) local_unnamed_addr #0 {
131 ;CHECK-LABEL: exclude_tag:
132 %0 = zext i32 %m to i64
133 %1 = tail call i64 @llvm.aarch64.gmi(ptr %ptr, i64 %0)
134 %conv = trunc i64 %1 to i32
136 ; CHECK: gmi x0, x0, {{x[0-9]+}}
140 ; *********** __arm_mte_get_tag *************
141 %struct.S8K = type { [2048 x i32] }
142 define ptr @get_tag1(ptr %ptr) {
144 ; CHECK-LABEL: get_tag1:
145 %0 = tail call ptr @llvm.aarch64.ldg(ptr %ptr, ptr %ptr)
147 ; CHECK: ldg x0, [x0]
150 define ptr @get_tag1_two_parm(ptr %ret_ptr, ptr %ptr) {
152 ; CHECK-LABEL: get_tag1_two_parm:
153 %0 = tail call ptr @llvm.aarch64.ldg(ptr %ret_ptr, ptr %ptr)
155 ; CHECK: ldg x0, [x1]
158 define ptr @get_tag1stack() {
160 ; CHECK-LABEL: get_tag1stack:
161 %s = alloca %struct.S8K, align 4
162 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
163 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %s, ptr nonnull %s)
164 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
166 ; CHECK: mov [[T0:x[0-9]+]], sp
167 ; CHECK: ldg [[T0]], [sp]
170 define ptr @get_tag1stack_two_param(ptr %ret_ptr) {
172 ; CHECK-LABEL: get_tag1stack_two_param:
173 %s = alloca %struct.S8K, align 4
174 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
175 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %ret_ptr, ptr nonnull %s)
176 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
178 ; CHECK-NOT: mov {{.*}}, sp
179 ; CHECK: ldg x0, [sp]
183 define ptr @get_tag2(ptr %ptr) {
185 ; CHECK-LABEL: get_tag2:
186 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 4
187 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)
189 ; CHECK: add [[T0:x[0-9]+]], x0, #16
190 ; CHECK: ldg [[T0]], [x0, #16]
193 define ptr @get_tag2stack() {
195 ; CHECK-LABEL: get_tag2stack:
196 %s = alloca %struct.S8K, align 4
197 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
198 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 4
199 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)
200 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
202 ; CHECK: mov [[T0:x[0-9]+]], sp
203 ; CHECK: add x0, [[T0]], #16
204 ; CHECK: ldg x0, [sp, #16]
208 define ptr @get_tag3(ptr %ptr) {
210 ; CHECK-LABEL: get_tag3:
211 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1020
212 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)
214 ; CHECK: add [[T0:x[0-8]+]], x0, #4080
215 ; CHECK: ldg [[T0]], [x0, #4080]
218 define ptr @get_tag3stack() {
220 ; CHECK-LABEL: get_tag3stack:
221 %s = alloca %struct.S8K, align 4
222 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
223 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1020
224 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)
225 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
227 ; CHECK: mov [[T0:x[0-9]+]], sp
228 ; CHECK: add x0, [[T0]], #4080
229 ; CHECK: ldg x0, [sp, #4080]
233 define ptr @get_tag4(ptr %ptr) {
235 ; CHECK-LABEL: get_tag4:
236 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1024
237 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)
239 ; CHECK: add x0, x0, #1, lsl #12
240 ; CHECK-NEXT: ldg x0, [x0]
243 define ptr @get_tag4stack() {
245 ; CHECK-LABEL: get_tag4stack:
246 %s = alloca %struct.S8K, align 4
247 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
248 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1024
249 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)
250 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
252 ; CHECK: mov [[T0:x[0-9]+]], sp
253 ; CHECK-NEXT: add x[[T1:[0-9]+]], [[T0]], #1, lsl #12
254 ; CHECK-NEXT: ldg x[[T1]], [x[[T1]]]
257 define ptr @get_tag5(ptr %ptr) {
259 ; CHECK-LABEL: get_tag5:
260 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 5
261 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)
263 ; CHECK: add x0, x0, #20
264 ; CHECK-NEXT: ldg x0, [x0]
267 define ptr @get_tag5stack() {
269 ; CHECK-LABEL: get_tag5stack:
270 %s = alloca %struct.S8K, align 4
271 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
272 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 5
273 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)
274 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
276 ; CHECK: mov [[T0:x[0-9]+]], sp
277 ; CHECK: add x[[T1:[0-9]+]], [[T0]], #20
278 ; CHECK-NEXT: ldg x[[T1]], [x[[T1]]]
282 ; *********** __arm_mte_set_tag *************
283 define void @set_tag1(ptr %tag, ptr %ptr) {
285 ; CHECK-LABEL: set_tag1:
286 tail call void @llvm.aarch64.stg(ptr %tag, ptr %ptr)
288 ; CHECK: stg x0, [x1]
291 define void @set_tag1stack(ptr %tag) {
293 ; CHECK-LABEL: set_tag1stack:
294 %s = alloca %struct.S8K, align 4
295 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
296 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %s)
297 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %tag)
299 ; CHECK: stg x0, [sp]
303 define void @set_tag2(ptr %tag, ptr %ptr) {
305 ; CHECK-LABEL: set_tag2:
306 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 4
307 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)
309 ; CHECK: stg x0, [x1, #16]
312 define void @set_tag2stack(ptr %tag, ptr %ptr) {
314 ; CHECK-LABEL: set_tag2stack:
315 %s = alloca %struct.S8K, align 4
316 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
317 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 4
318 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)
319 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
321 ; CHECK: stg x0, [sp, #16]
326 define void @set_tag3(ptr %tag, ptr %ptr) {
328 ; CHECK-LABEL: set_tag3:
329 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1020
330 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)
332 ; CHECK: stg x0, [x1, #4080]
335 define void @set_tag3stack(ptr %tag, ptr %ptr) {
337 ; CHECK-LABEL: set_tag3stack:
338 %s = alloca %struct.S8K, align 4
339 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
340 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1020
341 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)
342 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
344 ; CHECK: stg x0, [sp, #4080]
349 define void @set_tag4(ptr %tag, ptr %ptr) {
351 ; CHECK-LABEL: set_tag4:
352 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1024
353 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)
355 ; CHECK: add x[[T0:[0-9]+]], x1, #1, lsl #12
356 ; CHECK-NEXT: stg x0, [x[[T0]]]
359 define void @set_tag4stack(ptr %tag, ptr %ptr) {
361 ; CHECK-LABEL: set_tag4stack:
362 %s = alloca %struct.S8K, align 4
363 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
364 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1024
365 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)
366 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
368 ; CHECK: add x[[T0:[0-9]+]], {{.*}}, #1, lsl #12
369 ; CHECK-NEXT: stg x0, [x[[T0]]]
373 define void @set_tag5(ptr %tag, ptr %ptr) {
375 ; CHECK-LABEL: set_tag5:
376 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 5
377 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)
379 ; CHECK: add x[[T0:[0-9]+]], x1, #20
380 ; CHECK-NEXT: stg x0, [x[[T0]]]
383 define void @set_tag5stack(ptr %tag, ptr %ptr) {
385 ; CHECK-LABEL: set_tag5stack:
386 %s = alloca %struct.S8K, align 4
387 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)
388 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 5
389 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)
390 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)
392 ; CHECK: add x[[T0:[0-9]+]], {{.*}}, #20
393 ; CHECK-NEXT: stg x0, [x[[T0]]]
397 ; *********** __arm_mte_ptrdiff *************
398 define i64 @subtract_pointers(ptr %ptra, ptr %ptrb) {
400 ; CHECK-LABEL: subtract_pointers:
401 %0 = tail call i64 @llvm.aarch64.subp(ptr %ptra, ptr %ptrb)
403 ; CHECK: subp x0, x0, x1
406 declare ptr @llvm.aarch64.irg(ptr, i64)
407 declare ptr @llvm.aarch64.addg(ptr, i64)
408 declare i64 @llvm.aarch64.gmi(ptr, i64)
409 declare ptr @llvm.aarch64.ldg(ptr, ptr)
410 declare void @llvm.aarch64.stg(ptr, ptr)
411 declare i64 @llvm.aarch64.subp(ptr, ptr)
413 declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
414 declare void @llvm.lifetime.end.p0(i64, ptr nocapture)