1 ; RUN: opt -S -aarch64-stack-tagging %s -o - | FileCheck %s
2 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
3 target triple = "aarch64-unknown-linux-android29"
5 @stackbuf = dso_local local_unnamed_addr global ptr null, align 8
6 @jbuf = dso_local global [32 x i64] zeroinitializer, align 8
8 declare void @may_jump()
10 define dso_local noundef i1 @_Z6targetv() sanitize_memtag {
12 %buf = alloca [4096 x i8], align 1
13 %call = call i32 @setjmp(ptr noundef @jbuf)
14 switch i32 %call, label %while.body [
19 sw.bb1: ; preds = %entry
22 while.body: ; preds = %entry
23 call void @llvm.lifetime.start.p0(i64 4096, ptr nonnull %buf) #10
24 store ptr %buf, ptr @stackbuf, align 8
25 ; may_jump may call longjmp, going back to the switch (and then the return),
26 ; bypassing the lifetime.end. This is why we need to untag on the return,
27 ; rather than the lifetime.end.
29 call void @llvm.lifetime.end.p0(i64 4096, ptr nonnull %buf) #10
32 ; CHECK-LABEL: return:
33 ; CHECK: call void @llvm.aarch64.settag
34 return: ; preds = %entry, %while.body, %sw.bb1
35 %retval.0 = phi i1 [ true, %while.body ], [ true, %sw.bb1 ], [ false, %entry ]
39 declare i32 @setjmp(ptr noundef) returns_twice
41 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
42 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)