[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / stack-tagging-initializer-merge.ll
blobe449faba048d438398fdaca2446b91833f533439
1 ; RUN: opt < %s -aarch64-stack-tagging -S -o - | FileCheck %s
3 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4 target triple = "aarch64--linux-android"
6 declare void @use(ptr)
7 declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
8 declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
9 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
11 define void @OneVarNoInit() sanitize_memtag {
12 entry:
13   %x = alloca i32, align 4
14   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
15   call void @use(ptr nonnull %x)
16   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
17   ret void
20 ; CHECK-LABEL: define void @OneVarNoInit(
21 ; CHECK-DAG:  [[X:%.*]] = alloca { i32, [12 x i8] }, align 16
22 ; CHECK-DAG:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp.{{.*}}(ptr [[X]], {{.*}}, i64 0)
23 ; CHECK-DAG:  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[TX]])
24 ; CHECK-DAG:  call void @llvm.aarch64.settag(ptr [[TX]], i64 16)
25 ; CHECK-DAG:  call void @use(ptr nonnull [[TX]])
26 ; CHECK-DAG:  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[TX]])
28 define void @OneVarInitConst() sanitize_memtag {
29 entry:
30   %x = alloca i32, align 4
31   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
32   store i32 42, ptr %x, align 4
33   call void @use(ptr nonnull %x)
34   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
35   ret void
38 ; CHECK-LABEL: define void @OneVarInitConst(
39 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp
40 ; CHECK-NOT: aarch64.settag
41 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 42, i64 0)
42 ; Untagging before lifetime.end:
43 ; CHECK:  call void @llvm.aarch64.settag(
44 ; CHECK-NOT: aarch64.settag
45 ; CHECK:  ret void
47 define void @ArrayInitConst() sanitize_memtag {
48 entry:
49   %x = alloca i32, i32 16, align 4
50   call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x)
51   store i32 42, ptr %x, align 4
52   call void @use(ptr nonnull %x)
53   call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x)
54   ret void
57 ; CHECK-LABEL: define void @ArrayInitConst(
58 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp.
59 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 42, i64 0)
60 ; CHECK:  [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16
61 ; CHECK:  call void @llvm.aarch64.settag.zero(ptr [[TX8_16]], i64 48)
62 ; CHECK:  ret void
64 define void @ArrayInitConst2() sanitize_memtag {
65 entry:
66   %x = alloca i32, i32 16, align 4
67   call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x)
68   store i32 42, ptr %x, align 4
69   %0 = getelementptr i32, ptr %x, i32 1
70   store i32 43, ptr %0, align 4
71   %1 = getelementptr i32, ptr %x, i32 2
72   store i64 -1, ptr %1, align 4
73   call void @use(ptr nonnull %x)
74   call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x)
75   ret void
78 ; CHECK-LABEL: define void @ArrayInitConst2(
79 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp.
80 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 184683593770, i64 -1)
81 ; CHECK:  [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16
82 ; CHECK:  call void @llvm.aarch64.settag.zero(ptr [[TX8_16]], i64 48)
83 ; CHECK:  ret void
85 define void @ArrayInitConstSplit() sanitize_memtag {
86 entry:
87   %x = alloca i32, i32 16, align 4
88   call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x)
89   %0 = getelementptr i32, ptr %x, i32 1
90   store i64 -1, ptr %0, align 4
91   call void @use(ptr nonnull %x)
92   call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x)
93   ret void
96 ; CHECK-LABEL: define void @ArrayInitConstSplit(
97 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp.
98 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 -4294967296, i64 4294967295)
99 ; CHECK:  ret void
101 define void @ArrayInitConstWithHoles() sanitize_memtag {
102 entry:
103   %x = alloca i32, i32 32, align 4
104   call void @llvm.lifetime.start.p0(i64 128, ptr nonnull %x)
105   %0 = getelementptr i32, ptr %x, i32 5
106   store i32 42, ptr %0, align 4
107   %1 = getelementptr i32, ptr %x, i32 14
108   store i32 43, ptr %1, align 4
109   call void @use(ptr nonnull %x)
110   call void @llvm.lifetime.end.p0(i64 128, ptr nonnull %x)
111   ret void
114 ; CHECK-LABEL: define void @ArrayInitConstWithHoles(
115 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp.
116 ; CHECK:  call void @llvm.aarch64.settag.zero(ptr [[TX]], i64 16)
117 ; CHECK:  [[TX8_16:%.*]] = getelementptr i8, ptr %x.tag, i32 16
118 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX8_16]], i64 180388626432, i64 0)
119 ; CHECK:  [[TX8_32:%.*]] = getelementptr i8, ptr %x.tag, i32 32
120 ; CHECK:  call void @llvm.aarch64.settag.zero(ptr [[TX8_32]], i64 16)
121 ; CHECK:  [[TX8_48:%.*]] = getelementptr i8, ptr %x.tag, i32 48
122 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX8_48]], i64 0, i64 43)
123 ; CHECK:  [[TX8_64:%.*]] = getelementptr i8, ptr %x.tag, i32 64
124 ; CHECK:  call void @llvm.aarch64.settag.zero(ptr [[TX8_64]], i64 64)
125 ; CHECK:  ret void
127 define void @InitNonConst(i32 %v) sanitize_memtag {
128 entry:
129   %x = alloca i32, align 4
130   call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x)
131   store i32 %v, ptr %x, align 4
132   call void @use(ptr nonnull %x)
133   call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x)
134   ret void
137 ; CHECK-LABEL: define void @InitNonConst(
138 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp
139 ; CHECK:  [[V:%.*]] = zext i32 %v to i64
140 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 [[V]], i64 0)
141 ; CHECK:  ret void
143 define void @InitNonConst2(i32 %v, i32 %w) sanitize_memtag {
144 entry:
145   %x = alloca i32, i32 4, align 4
146   call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x)
147   store i32 %v, ptr %x, align 4
148   %0 = getelementptr i32, ptr %x, i32 1
149   store i32 %w, ptr %0, align 4
150   call void @use(ptr nonnull %x)
151   call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x)
152   ret void
155 ; CHECK-LABEL: define void @InitNonConst2(
156 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp
157 ; CHECK:  [[V:%.*]] = zext i32 %v to i64
158 ; CHECK:  [[W:%.*]] = zext i32 %w to i64
159 ; CHECK:  [[WS:%.*]] = shl i64 [[W]], 32
160 ; CHECK:  [[VW:%.*]] = or i64 [[V]], [[WS]]
161 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 [[VW]], i64 0)
162 ; CHECK:  ret void
164 define void @InitVector() sanitize_memtag {
165 entry:
166   %x = alloca i32, i32 4, align 4
167   call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x)
168   store <2 x i32> <i32 1, i32 2>, ptr %x, align 4
169   call void @use(ptr nonnull %x)
170   call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x)
171   ret void
174 ; CHECK-LABEL: define void @InitVector(
175 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp
176 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), i64 0)
177 ; CHECK:  ret void
179 define void @InitVectorPtr(ptr %p) sanitize_memtag {
180 entry:
181   %s = alloca <4 x ptr>, align 8
182   %v0 = insertelement <4 x ptr> undef, ptr %p, i32 0
183   %v1 = shufflevector <4 x ptr> %v0, <4 x ptr> undef, <4 x i32> zeroinitializer
184   store <4 x ptr> %v1, ptr %s
185   call void @use(ptr nonnull %s)
186   ret void
189 ; CHECK-LABEL: define void @InitVectorPtr(
190 ; CHECK:  call ptr @llvm.aarch64.tagp
191 ; CHECK:  [[V1:%.*]] = shufflevector
192 ; CHECK:  [[V2:%.*]] = ptrtoint <4 x ptr> [[V1]] to <4 x i64>
193 ; CHECK:  [[V3:%.*]] = bitcast <4 x i64> [[V2]] to i256
194 ; CHECK:  [[A1:%.*]] = trunc i256 [[V3]] to i64
195 ; CHECK:  [[A2_:%.*]] = lshr i256 [[V3]], 64
196 ; CHECK:  [[A2:%.*]] = trunc i256 [[A2_]] to i64
197 ; CHECK:  [[A3_:%.*]] = lshr i256 [[V3]], 128
198 ; CHECK:  [[A3:%.*]] = trunc i256 [[A3_]] to i64
199 ; CHECK:  [[A4_:%.*]] = lshr i256 [[V3]], 192
200 ; CHECK:  [[A4:%.*]] = trunc i256 [[A4_]] to i64
201 ; CHECK:  call void @llvm.aarch64.stgp({{.*}}, i64 [[A1]], i64 [[A2]])
202 ; CHECK:  call void @llvm.aarch64.stgp({{.*}}, i64 [[A3]], i64 [[A4]])
203 ; CHECK:  ret void
205 define void @InitVectorSplit() sanitize_memtag {
206 entry:
207   %x = alloca i32, i32 4, align 4
208   call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x)
209   %0 = getelementptr i32, ptr %x, i32 1
210   store <2 x i32> <i32 1, i32 2>, ptr %0, align 4
211   call void @use(ptr nonnull %x)
212   call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x)
213   ret void
216 ; CHECK-LABEL: define void @InitVectorSplit(
217 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp
218 ; CHECK:  call void @llvm.aarch64.stgp(ptr [[TX]], i64 shl (i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), i64 32), i64 lshr (i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), i64 32))
219 ; CHECK:  ret void
221 define void @MemSetZero() sanitize_memtag {
222 entry:
223   %x = alloca i32, i32 8, align 16
224   call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 0, i64 32, i1 false)
225   call void @use(ptr nonnull %x)
226   ret void
229 ; CHECK-LABEL: define void @MemSetZero(
230 ; CHECK:  [[TX:%.*]] = call ptr @llvm.aarch64.tagp
231 ; CHECK:  call void @llvm.aarch64.settag.zero(ptr [[TX]], i64 32)
232 ; CHECK:  ret void
235 define void @MemSetNonZero() sanitize_memtag {
236 entry:
237   %x = alloca i32, i32 8, align 16
238   call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 42, i64 32, i1 false)
239   call void @use(ptr nonnull %x)
240   ret void
243 ; CHECK-LABEL: define void @MemSetNonZero(
244 ; CHECK:  call void @llvm.aarch64.stgp(ptr {{.*}}, i64 3038287259199220266, i64 3038287259199220266)
245 ; CHECK:  call void @llvm.aarch64.stgp(ptr {{.*}}, i64 3038287259199220266, i64 3038287259199220266)
246 ; CHECK:  ret void
249 define void @MemSetNonZero2() sanitize_memtag {
250 entry:
251   %x = alloca [32 x i8], align 16
252   %0 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 2
253   call void @llvm.memset.p0.i64(ptr nonnull %0, i8 42, i64 28, i1 false)
254   call void @use(ptr nonnull %0)
255   ret void
258 ; CHECK-LABEL: define void @MemSetNonZero2(
259 ; CHECK:  call void @llvm.aarch64.stgp(ptr {{.*}}, i64 3038287259199209472, i64 3038287259199220266)
260 ; CHECK:  call void @llvm.aarch64.stgp(ptr {{.*}}, i64 3038287259199220266, i64 46360584399402)
261 ; CHECK:  ret void
263 define void @MemSetNonZero3() sanitize_memtag {
264 entry:
265   %x = alloca [32 x i8], align 16
266   %0 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 2
267   call void @llvm.memset.p0.i64(ptr nonnull %0, i8 42, i64 4, i1 false)
268   %1 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 24
269   call void @llvm.memset.p0.i64(ptr nonnull %1, i8 42, i64 8, i1 false)
270   call void @use(ptr nonnull %0)
271   ret void
274 ; CHECK-LABEL: define void @MemSetNonZero3(
275 ; CHECK:  call void @llvm.aarch64.stgp(ptr {{.*}}, i64 46360584388608, i64 0)
276 ; CHECK:  call void @llvm.aarch64.stgp(ptr {{.*}}, i64 0, i64 3038287259199220266)
277 ; CHECK:  ret void
279 define void @LargeAlloca() sanitize_memtag {
280 entry:
281   %x = alloca i32, i32 256, align 16
282   call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 42, i64 256, i1 false)
283   call void @use(ptr nonnull %x)
284   ret void
287 ; CHECK-LABEL: define void @LargeAlloca(
288 ; CHECK:  call void @llvm.aarch64.settag(ptr {{.*}}, i64 1024)
289 ; CHECK:  call void @llvm.memset.p0.i64(ptr {{.*}}, i8 42, i64 256,
290 ; CHECK:  ret void