Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / AArch64 / stack-tagging.ll
blob8759fb12bea7732fb8eee40631b9016e49b91554
1 ; RUN: opt < %s -aarch64-stack-tagging -S -o - | FileCheck %s --check-prefixes=CHECK,SSI
2 ; RUN: opt < %s -aarch64-stack-tagging -stack-tagging-use-stack-safety=0 -S -o - | FileCheck %s --check-prefixes=CHECK
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"
7 declare void @use8(ptr)
8 declare void @use32(ptr)
9 declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
10 declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
12 define dso_local void @noUse32(ptr) sanitize_memtag {
13 entry:
14   ret void
17 define void @OneVar() sanitize_memtag {
18 entry:
19   %x = alloca i32, align 4
20   call void @use32(ptr %x)
21   ret void
24 ; CHECK-LABEL: define void @OneVar(
25 ; CHECK:  [[BASE:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0)
26 ; CHECK:  [[X:%.*]] = alloca { i32, [12 x i8] }, align 16
27 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp.{{.*}}(ptr [[X]], ptr [[BASE]], i64 0)
28 ; CHECK:  call void @llvm.aarch64.settag(ptr [[TX]], i64 16)
29 ; CHECK:  call void @use32(ptr [[TX]])
30 ; CHECK:  call void @llvm.aarch64.settag(ptr [[X]], i64 16)
31 ; CHECK:  ret void
34 define void @ManyVars() sanitize_memtag {
35 entry:
36   %x1 = alloca i32, align 4
37   %x2 = alloca i8, align 4
38   %x3 = alloca i32, i32 11, align 4
39   %x4 = alloca i32, align 4
40   call void @use32(ptr %x1)
41   call void @use8(ptr %x2)
42   call void @use32(ptr %x3)
43   ret void
46 ; CHECK-LABEL: define void @ManyVars(
47 ; CHECK:  alloca { i32, [12 x i8] }, align 16
48 ; CHECK:  call ptr @llvm.aarch64.tagp.{{.*}}(ptr {{.*}}, i64 0)
49 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 16)
50 ; CHECK:  alloca { i8, [15 x i8] }, align 16
51 ; CHECK:  call ptr @llvm.aarch64.tagp.{{.*}}(ptr {{.*}}, i64 1)
52 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 16)
53 ; CHECK:  alloca { [11 x i32], [4 x i8] }, align 16
54 ; CHECK:  call ptr @llvm.aarch64.tagp.{{.*}}(ptr {{.*}}, i64 2)
55 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 48)
56 ; CHECK:  alloca i32, align 4
57 ; SSI-NOT: @llvm.aarch64.tagp
58 ; SSI-NOT: @llvm.aarch64.settag
60 ; CHECK:  call void @use32(
61 ; CHECK:  call void @use8(
62 ; CHECK:  call void @use32(
64 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 16)
65 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 16)
66 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 48)
67 ; CHECK-NEXT:  ret void
70 define void @Scope(i32 %b) sanitize_memtag {
71 entry:
72   %x = alloca i32, align 4
73   %tobool = icmp eq i32 %b, 0
74   br i1 %tobool, label %if.end, label %if.then
76 if.then:
77   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
78   call void @use8(ptr %x) #3
79   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
80   br label %if.end
82 if.end:
83   ret void
86 ; CHECK-LABEL: define void @Scope(
87 ; CHECK:  br i1
88 ; CHECK:  call void @llvm.lifetime.start.p0(
89 ; CHECK:  call void @llvm.aarch64.settag(
90 ; CHECK:  call void @use8(
91 ; CHECK:  call void @llvm.aarch64.settag(
92 ; CHECK:  call void @llvm.lifetime.end.p0(
93 ; CHECK:  br label
94 ; CHECK:  ret void
97 ; Spooked by the multiple lifetime ranges, StackTagging remove all of them and sets tags on entry and exit.
98 define void @BadScope(i32 %b) sanitize_memtag {
99 entry:
100   %x = alloca i32, align 4
101   %tobool = icmp eq i32 %b, 0
102   br i1 %tobool, label %if.end, label %if.then
104 if.then:
105   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
106   call void @use8(ptr %x) #3
107   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
109   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
110   call void @use8(ptr %x) #3
111   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
112   br label %if.end
114 if.end:
115   ret void
118 ; CHECK-LABEL: define void @BadScope(
119 ; CHECK:       call void @llvm.aarch64.settag(ptr {{.*}}, i64 16)
120 ; CHECK:       br i1
121 ; CHECK:       call void @use8(ptr
122 ; CHECK-NEXT:  call void @use8(ptr
123 ; CHECK:       br label
124 ; CHECK:       call void @llvm.aarch64.settag(ptr {{.*}}, i64 16)
125 ; CHECK-NEXT:  ret void
127 define void @DynamicAllocas(i32 %cnt) sanitize_memtag {
128 entry:
129   %x = alloca i32, i32 %cnt, align 4
130   br label %l
132   %y = alloca i32, align 4
133   call void @use32(ptr %x)
134   call void @use32(ptr %y)
135   ret void
138 ; CHECK-LABEL: define void @DynamicAllocas(
139 ; CHECK-NOT: @llvm.aarch64.irg.sp
140 ; CHECK:     %x = alloca i32, i32 %cnt, align 4
141 ; CHECK-NOT: @llvm.aarch64.irg.sp
142 ; CHECK:     alloca i32, align 4
143 ; CHECK-NOT: @llvm.aarch64.irg.sp
144 ; CHECK:     ret void
146 ; If we can't trace one of the lifetime markers to a single alloca, fall back
147 ; to poisoning all allocas at the beginning of the function.
148 ; Each alloca must be poisoned only once.
149 define void @UnrecognizedLifetime(i8 %v) sanitize_memtag {
150 entry:
151   %x = alloca i32, align 4
152   %y = alloca i32, align 4
153   %z = alloca i32, align 4
154   %tobool = icmp eq i8 %v, 0
155   %xy = select i1 %tobool, ptr %x, ptr %y
156   %cxcy = select i1 %tobool, ptr %x, ptr %y
157   br label %another_bb
159 another_bb:
160   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %z)
161   store i32 7, ptr %z
162   call void @noUse32(ptr %z)
163   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %z)
164   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %z)
165   store i32 7, ptr %z
166   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %z)
167   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %cxcy)
168   store i32 8, ptr %xy
169   call void @noUse32(ptr %x)
170   call void @noUse32(ptr %y)
171   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %cxcy)
172   ret void
175 ; CHECK-LABEL: define void @UnrecognizedLifetime(
176 ; CHECK: call ptr @llvm.aarch64.irg.sp(i64 0)
177 ; CHECK: alloca { i32, [12 x i8] }, align 16
178 ; CHECK: call ptr @llvm.aarch64.tagp
179 ; CHECK: call void @llvm.aarch64.settag(
180 ; CHECK: alloca { i32, [12 x i8] }, align 16
181 ; CHECK: call ptr @llvm.aarch64.tagp
182 ; CHECK: call void @llvm.aarch64.settag(
183 ; CHECK: alloca { i32, [12 x i8] }, align 16
184 ; CHECK: call ptr @llvm.aarch64.tagp
185 ; CHECK: call void @llvm.aarch64.settag(
186 ; CHECK: store i32
187 ; CHECK: call void @noUse32(ptr
188 ; CHECK: store i32
189 ; CHECK: store i32
190 ; CHECK: call void @noUse32(ptr
191 ; CHECK: call void @llvm.aarch64.settag(
192 ; CHECK: call void @llvm.aarch64.settag(
193 ; CHECK: call void @llvm.aarch64.settag(
194 ; CHECK: ret void
196 !0 = !{}