415 lines · plain
1; RUN: llc < %s -mtriple=arm64-eabi -mattr=+mte | FileCheck %s2 3; test create_tag4define ptr @create_tag(ptr %ptr, i32 %m) {5entry:6; CHECK-LABEL: create_tag:7 %0 = zext i32 %m to i648 %1 = tail call ptr @llvm.aarch64.irg(ptr %ptr, i64 %0)9 ret ptr %110;CHECK: irg x0, x0, {{x[0-9]+}}11}12 13; *********** __arm_mte_increment_tag *************14; test increment_tag115define ptr @increment_tag1(ptr %ptr) {16entry:17; CHECK-LABEL: increment_tag1:18 %0 = tail call ptr @llvm.aarch64.addg(ptr %ptr, i64 7)19 ret ptr %020; CHECK: addg x0, x0, #0, #721}22 23%struct.S2K = type { [512 x i32] }24define ptr @increment_tag1stack(ptr %ptr) {25entry:26; CHECK-LABEL: increment_tag1stack:27 %s = alloca %struct.S2K, align 428 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)31 ret ptr %032; CHECK: addg x0, sp, #0, #733}34 35 36define ptr @increment_tag2(ptr %ptr) {37entry:38; CHECK-LABEL: increment_tag2:39 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 440 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)41 ret ptr %042; CHECK: addg x0, x0, #16, #743}44 45define ptr @increment_tag2stack(ptr %ptr) {46entry:47; CHECK-LABEL: increment_tag2stack:48 %s = alloca %struct.S2K, align 449 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)50 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 451 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)52 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)53 ret ptr %054; CHECK: addg x0, sp, #16, #755}56 57define ptr @increment_tag3(ptr %ptr) {58entry:59; CHECK-LABEL: increment_tag3:60 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 25261 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)62 ret ptr %063; CHECK: addg x0, x0, #1008, #764}65 66define ptr @increment_tag3stack(ptr %ptr) {67entry:68; CHECK-LABEL: increment_tag3stack:69 %s = alloca %struct.S2K, align 470 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)71 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 25272 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)73 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)74 ret ptr %075; CHECK: addg x0, sp, #1008, #776}77 78 79define ptr @increment_tag4(ptr %ptr) {80entry:81; CHECK-LABEL: increment_tag4:82 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 25683 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)84 ret ptr %085; CHECK: add [[T0:x[0-9]+]], x0, #102486; CHECK-NEXT: addg x0, [[T0]], #0, #787}88 89define ptr @increment_tag4stack(ptr %ptr) {90entry:91; CHECK-LABEL: increment_tag4stack:92 %s = alloca %struct.S2K, align 493 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)94 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 25695 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)96 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)97 ret ptr %098; CHECK: add [[T0:x[0-9]+]], {{.*}}, #102499; CHECK-NEXT: addg x0, [[T0]], #0, #7100}101 102 103define ptr @increment_tag5(ptr %ptr) {104entry:105; CHECK-LABEL: increment_tag5:106 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 5107 %0 = tail call ptr @llvm.aarch64.addg(ptr nonnull %add.ptr, i64 7)108 ret ptr %0109; CHECK: add [[T0:x[0-9]+]], x0, #20110; CHECK-NEXT: addg x0, [[T0]], #0, #7111}112 113define ptr @increment_tag5stack(ptr %ptr) {114entry:115; CHECK-LABEL: increment_tag5stack:116 %s = alloca %struct.S2K, align 4117 call void @llvm.lifetime.start.p0(i64 2048, ptr nonnull %s)118 %arrayidx = getelementptr inbounds %struct.S2K, ptr %s, i64 0, i32 0, i64 5119 %0 = call ptr @llvm.aarch64.addg(ptr nonnull %arrayidx, i64 7)120 call void @llvm.lifetime.end.p0(i64 2048, ptr nonnull %s)121 ret ptr %0122; CHECK: add [[T0:x[0-9]+]], {{.*}}, #20123; CHECK-NEXT: addg x0, [[T0]], #0, #7124}125 126 127; *********** __arm_mte_exclude_tag *************128; test exclude_tag129define i32 @exclude_tag(ptr %ptr, i32 %m) local_unnamed_addr #0 {130entry:131;CHECK-LABEL: exclude_tag:132 %0 = zext i32 %m to i64133 %1 = tail call i64 @llvm.aarch64.gmi(ptr %ptr, i64 %0)134 %conv = trunc i64 %1 to i32135 ret i32 %conv136; CHECK: gmi x0, x0, {{x[0-9]+}}137}138 139 140; *********** __arm_mte_get_tag *************141%struct.S8K = type { [2048 x i32] }142define ptr @get_tag1(ptr %ptr) {143entry:144; CHECK-LABEL: get_tag1:145 %0 = tail call ptr @llvm.aarch64.ldg(ptr %ptr, ptr %ptr)146 ret ptr %0147; CHECK: ldg x0, [x0]148}149 150define ptr @get_tag1_two_parm(ptr %ret_ptr, ptr %ptr) {151entry:152; CHECK-LABEL: get_tag1_two_parm:153 %0 = tail call ptr @llvm.aarch64.ldg(ptr %ret_ptr, ptr %ptr)154 ret ptr %0155; CHECK: ldg x0, [x1]156}157 158define ptr @get_tag1stack() {159entry:160; CHECK-LABEL: get_tag1stack:161 %s = alloca %struct.S8K, align 4162 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)165 ret ptr %0166; CHECK: mov [[T0:x[0-9]+]], sp167; CHECK: ldg [[T0]], [sp]168}169 170define ptr @get_tag1stack_two_param(ptr %ret_ptr) {171entry:172; CHECK-LABEL: get_tag1stack_two_param:173 %s = alloca %struct.S8K, align 4174 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)177 ret ptr %0178; CHECK-NOT: mov {{.*}}, sp179; CHECK: ldg x0, [sp]180}181 182 183define ptr @get_tag2(ptr %ptr) {184entry:185; CHECK-LABEL: get_tag2:186 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 4187 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)188 ret ptr %0189; CHECK: add [[T0:x[0-9]+]], x0, #16190; CHECK: ldg [[T0]], [x0, #16]191}192 193define ptr @get_tag2stack() {194entry:195; CHECK-LABEL: get_tag2stack:196 %s = alloca %struct.S8K, align 4197 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)198 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 4199 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)200 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)201 ret ptr %0202; CHECK: mov [[T0:x[0-9]+]], sp203; CHECK: add x0, [[T0]], #16204; CHECK: ldg x0, [sp, #16]205}206 207 208define ptr @get_tag3(ptr %ptr) {209entry:210; CHECK-LABEL: get_tag3:211 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1020212 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)213 ret ptr %0214; CHECK: add [[T0:x[0-8]+]], x0, #4080215; CHECK: ldg [[T0]], [x0, #4080]216}217 218define ptr @get_tag3stack() {219entry:220; CHECK-LABEL: get_tag3stack:221 %s = alloca %struct.S8K, align 4222 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)223 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1020224 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)225 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)226 ret ptr %0227; CHECK: mov [[T0:x[0-9]+]], sp228; CHECK: add x0, [[T0]], #4080229; CHECK: ldg x0, [sp, #4080]230}231 232 233define ptr @get_tag4(ptr %ptr) {234entry:235; CHECK-LABEL: get_tag4:236 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1024237 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)238 ret ptr %0239; CHECK: add x0, x0, #1, lsl #12240; CHECK-NEXT: ldg x0, [x0]241}242 243define ptr @get_tag4stack() {244entry:245; CHECK-LABEL: get_tag4stack:246 %s = alloca %struct.S8K, align 4247 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)248 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1024249 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)250 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)251 ret ptr %0252; CHECK: mov [[T0:x[0-9]+]], sp253; CHECK-NEXT: add x[[T1:[0-9]+]], [[T0]], #1, lsl #12254; CHECK-NEXT: ldg x[[T1]], [x[[T1]]]255}256 257define ptr @get_tag5(ptr %ptr) {258entry:259; CHECK-LABEL: get_tag5:260 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 5261 %0 = tail call ptr @llvm.aarch64.ldg(ptr nonnull %add.ptr, ptr nonnull %add.ptr)262 ret ptr %0263; CHECK: add x0, x0, #20264; CHECK-NEXT: ldg x0, [x0]265}266 267define ptr @get_tag5stack() {268entry:269; CHECK-LABEL: get_tag5stack:270 %s = alloca %struct.S8K, align 4271 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)272 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 5273 %0 = call ptr @llvm.aarch64.ldg(ptr nonnull %arrayidx, ptr nonnull %arrayidx)274 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)275 ret ptr %0276; CHECK: mov [[T0:x[0-9]+]], sp277; CHECK: add x[[T1:[0-9]+]], [[T0]], #20278; CHECK-NEXT: ldg x[[T1]], [x[[T1]]]279}280 281 282; *********** __arm_mte_set_tag *************283define void @set_tag1(ptr %tag, ptr %ptr) {284entry:285; CHECK-LABEL: set_tag1:286 tail call void @llvm.aarch64.stg(ptr %tag, ptr %ptr)287 ret void288; CHECK: stg x0, [x1]289}290 291define void @set_tag1stack(ptr %tag) {292entry:293; CHECK-LABEL: set_tag1stack:294 %s = alloca %struct.S8K, align 4295 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)298 ret void299; CHECK: stg x0, [sp]300}301 302 303define void @set_tag2(ptr %tag, ptr %ptr) {304entry:305; CHECK-LABEL: set_tag2:306 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 4307 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)308 ret void309; CHECK: stg x0, [x1, #16]310}311 312define void @set_tag2stack(ptr %tag, ptr %ptr) {313entry:314; CHECK-LABEL: set_tag2stack:315 %s = alloca %struct.S8K, align 4316 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)317 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 4318 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)319 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)320 ret void321; CHECK: stg x0, [sp, #16]322}323 324 325 326define void @set_tag3(ptr %tag, ptr %ptr) {327entry:328; CHECK-LABEL: set_tag3:329 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1020330 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)331 ret void332; CHECK: stg x0, [x1, #4080]333}334 335define void @set_tag3stack(ptr %tag, ptr %ptr) {336entry:337; CHECK-LABEL: set_tag3stack:338 %s = alloca %struct.S8K, align 4339 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)340 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1020341 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)342 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)343 ret void344; CHECK: stg x0, [sp, #4080]345}346 347 348 349define void @set_tag4(ptr %tag, ptr %ptr) {350entry:351; CHECK-LABEL: set_tag4:352 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 1024353 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)354 ret void355; CHECK: add x[[T0:[0-9]+]], x1, #1, lsl #12356; CHECK-NEXT: stg x0, [x[[T0]]]357}358 359define void @set_tag4stack(ptr %tag, ptr %ptr) {360entry:361; CHECK-LABEL: set_tag4stack:362 %s = alloca %struct.S8K, align 4363 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)364 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 1024365 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)366 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)367 ret void368; CHECK: add x[[T0:[0-9]+]], {{.*}}, #1, lsl #12369; CHECK-NEXT: stg x0, [x[[T0]]]370}371 372 373define void @set_tag5(ptr %tag, ptr %ptr) {374entry:375; CHECK-LABEL: set_tag5:376 %add.ptr = getelementptr inbounds i32, ptr %ptr, i64 5377 tail call void @llvm.aarch64.stg(ptr %tag, ptr %add.ptr)378 ret void379; CHECK: add x[[T0:[0-9]+]], x1, #20380; CHECK-NEXT: stg x0, [x[[T0]]]381}382 383define void @set_tag5stack(ptr %tag, ptr %ptr) {384entry:385; CHECK-LABEL: set_tag5stack:386 %s = alloca %struct.S8K, align 4387 call void @llvm.lifetime.start.p0(i64 8192, ptr nonnull %s)388 %arrayidx = getelementptr inbounds %struct.S8K, ptr %s, i64 0, i32 0, i64 5389 call void @llvm.aarch64.stg(ptr %tag, ptr nonnull %arrayidx)390 call void @llvm.lifetime.end.p0(i64 8192, ptr nonnull %s)391 ret void392; CHECK: add x[[T0:[0-9]+]], {{.*}}, #20393; CHECK-NEXT: stg x0, [x[[T0]]]394}395 396 397; *********** __arm_mte_ptrdiff *************398define i64 @subtract_pointers(ptr %ptra, ptr %ptrb) {399entry:400; CHECK-LABEL: subtract_pointers:401 %0 = tail call i64 @llvm.aarch64.subp(ptr %ptra, ptr %ptrb)402 ret i64 %0403; CHECK: subp x0, x0, x1404}405 406declare ptr @llvm.aarch64.irg(ptr, i64)407declare ptr @llvm.aarch64.addg(ptr, i64)408declare i64 @llvm.aarch64.gmi(ptr, i64)409declare ptr @llvm.aarch64.ldg(ptr, ptr)410declare void @llvm.aarch64.stg(ptr, ptr)411declare i64 @llvm.aarch64.subp(ptr, ptr)412 413declare void @llvm.lifetime.start.p0(i64, ptr nocapture)414declare void @llvm.lifetime.end.p0(i64, ptr nocapture)415