[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / stack-tagging.ll
blob83fe4025ea0c9ffb283729ee23ec40e8e1a38473
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,NOSSI
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(i8*)
8 declare void @use32(i32*)
9 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
10 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
12 define dso_local void @noUse32(i32*) 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(i32* %x)
21   ret void
24 ; CHECK-LABEL: define void @OneVar(
25 ; CHECK:  [[BASE:%.*]] = call i8* @llvm.aarch64.irg.sp(i64 0)
26 ; CHECK:  [[X:%.*]] = alloca { i32, [12 x i8] }, align 16
27 ; CHECK:  [[TX:%.*]] = call { i32, [12 x i8] }* @llvm.aarch64.tagp.{{.*}}({ i32, [12 x i8] }* [[X]], i8* [[BASE]], i64 0)
28 ; CHECK:  [[TX8:%.*]] = bitcast { i32, [12 x i8] }* [[TX]] to i8*
29 ; CHECK:  call void @llvm.aarch64.settag(i8* [[TX8]], i64 16)
30 ; CHECK:  [[GEP32:%.*]] = bitcast { i32, [12 x i8] }* [[TX]] to i32*
31 ; CHECK:  call void @use32(i32* [[GEP32]])
32 ; CHECK:  [[GEP8:%.*]] = bitcast { i32, [12 x i8] }* [[X]] to i8*
33 ; CHECK:  call void @llvm.aarch64.settag(i8* [[GEP8]], i64 16)
34 ; CHECK:  ret void
37 define void @ManyVars() sanitize_memtag {
38 entry:
39   %x1 = alloca i32, align 4
40   %x2 = alloca i8, align 4
41   %x3 = alloca i32, i32 11, align 4
42   %x4 = alloca i32, align 4
43   call void @use32(i32* %x1)
44   call void @use8(i8* %x2)
45   call void @use32(i32* %x3)
46   ret void
49 ; CHECK-LABEL: define void @ManyVars(
50 ; CHECK:  alloca { i32, [12 x i8] }, align 16
51 ; CHECK:  call { i32, [12 x i8] }* @llvm.aarch64.tagp.{{.*}}({ i32, [12 x i8] }* {{.*}}, i64 0)
52 ; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
53 ; CHECK:  alloca { i8, [15 x i8] }, align 16
54 ; CHECK:  call { i8, [15 x i8] }* @llvm.aarch64.tagp.{{.*}}({ i8, [15 x i8] }* {{.*}}, i64 1)
55 ; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
56 ; CHECK:  alloca { [11 x i32], [4 x i8] }, align 16
57 ; CHECK:  call { [11 x i32], [4 x i8] }* @llvm.aarch64.tagp.{{.*}}({ [11 x i32], [4 x i8] }* {{.*}}, i64 2)
58 ; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 48)
59 ; SSI:    alloca i32, align 4
60 ; NOSSI:  alloca { i32, [12 x i8] }, align 16
61 ; NOSSI: @llvm.aarch64.tagp.
62 ; NOSSI: call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
63 ; SSI-NOT: @llvm.aarch64.tagp
64 ; SSI-NOT: @llvm.aarch64.settag
66 ; CHECK:  call void @use32(
67 ; CHECK:  call void @use8(
68 ; CHECK:  call void @use32(
70 ; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
71 ; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
72 ; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 48)
73 ; NOSSI:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
74 ; CHECK-NEXT:  ret void
77 define void @Scope(i32 %b) sanitize_memtag {
78 entry:
79   %x = alloca i32, align 4
80   %tobool = icmp eq i32 %b, 0
81   br i1 %tobool, label %if.end, label %if.then
83 if.then:
84   %0 = bitcast i32* %x to i8*
85   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0)
86   call void @use8(i8* %0) #3
87   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0)
88   br label %if.end
90 if.end:
91   ret void
94 ; CHECK-LABEL: define void @Scope(
95 ; CHECK:  br i1
96 ; CHECK:  call void @llvm.lifetime.start.p0i8(
97 ; CHECK:  call void @llvm.aarch64.settag(
98 ; CHECK:  call void @use8(
99 ; CHECK:  call void @llvm.aarch64.settag(
100 ; CHECK:  call void @llvm.lifetime.end.p0i8(
101 ; CHECK:  br label
102 ; CHECK:  ret void
105 ; Spooked by the multiple lifetime ranges, StackTagging remove all of them and sets tags on entry and exit.
106 define void @BadScope(i32 %b) sanitize_memtag {
107 entry:
108   %x = alloca i32, align 4
109   %tobool = icmp eq i32 %b, 0
110   br i1 %tobool, label %if.end, label %if.then
112 if.then:
113   %0 = bitcast i32* %x to i8*
114   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0)
115   call void @use8(i8* %0) #3
116   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0)
118   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0)
119   call void @use8(i8* %0) #3
120   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0)
121   br label %if.end
123 if.end:
124   ret void
127 ; CHECK-LABEL: define void @BadScope(
128 ; CHECK:       call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
129 ; CHECK:       br i1
130 ; CHECK:       call void @use8(i8*
131 ; CHECK-NEXT:  call void @use8(i8*
132 ; CHECK:       br label
133 ; CHECK:       call void @llvm.aarch64.settag(i8* {{.*}}, i64 16)
134 ; CHECK-NEXT:  ret void
136 define void @DynamicAllocas(i32 %cnt) sanitize_memtag {
137 entry:
138   %x = alloca i32, i32 %cnt, align 4
139   br label %l
141   %y = alloca i32, align 4
142   call void @use32(i32* %x)
143   call void @use32(i32* %y)
144   ret void
147 ; CHECK-LABEL: define void @DynamicAllocas(
148 ; CHECK-NOT: @llvm.aarch64.irg.sp
149 ; CHECK:     %x = alloca i32, i32 %cnt, align 4
150 ; CHECK-NOT: @llvm.aarch64.irg.sp
151 ; CHECK:     alloca i32, align 4
152 ; CHECK-NOT: @llvm.aarch64.irg.sp
153 ; CHECK:     ret void
155 ; If we can't trace one of the lifetime markers to a single alloca, fall back
156 ; to poisoning all allocas at the beginning of the function.
157 ; Each alloca must be poisoned only once.
158 define void @UnrecognizedLifetime(i8 %v) sanitize_memtag {
159 entry:
160   %x = alloca i32, align 4
161   %y = alloca i32, align 4
162   %z = alloca i32, align 4
163   %cx = bitcast i32* %x to i8*
164   %cy = bitcast i32* %y to i8*
165   %cz = bitcast i32* %z to i8*
166   %tobool = icmp eq i8 %v, 0
167   %xy = select i1 %tobool, i32* %x, i32* %y
168   %cxcy = select i1 %tobool, i8* %cx, i8* %cy
169   br label %another_bb
171 another_bb:
172   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %cz)
173   store i32 7, i32* %z
174   call void @noUse32(i32* %z)
175   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %cz)
176   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %cz)
177   store i32 7, i32* %z
178   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %cz)
179   call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %cxcy)
180   store i32 8, i32* %xy
181   call void @noUse32(i32* %x)
182   call void @noUse32(i32* %y)
183   call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %cxcy)
184   ret void
187 ; CHECK-LABEL: define void @UnrecognizedLifetime(
188 ; CHECK: call i8* @llvm.aarch64.irg.sp(i64 0)
189 ; CHECK: alloca { i32, [12 x i8] }, align 16
190 ; CHECK: call { i32, [12 x i8] }* @llvm.aarch64.tagp
191 ; CHECK: call void @llvm.aarch64.settag(
192 ; CHECK: alloca { i32, [12 x i8] }, align 16
193 ; CHECK: call { i32, [12 x i8] }* @llvm.aarch64.tagp
194 ; CHECK: call void @llvm.aarch64.settag(
195 ; CHECK: alloca { i32, [12 x i8] }, align 16
196 ; CHECK: call { i32, [12 x i8] }* @llvm.aarch64.tagp
197 ; CHECK: call void @llvm.aarch64.settag(
198 ; CHECK: store i32
199 ; CHECK: call void @noUse32(i32*
200 ; CHECK: store i32
201 ; CHECK: store i32
202 ; CHECK: call void @noUse32(i32*
203 ; CHECK: call void @llvm.aarch64.settag(
204 ; CHECK: call void @llvm.aarch64.settag(
205 ; CHECK: call void @llvm.aarch64.settag(
206 ; CHECK: ret void
208 !0 = !{}