1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt < %s -aarch64-stack-tagging -S -o - | FileCheck %s 3 4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 5target triple = "aarch64--linux-android" 6 7declare void @use(ptr) 8declare void @llvm.lifetime.start.p0(i64, ptr nocapture) 9declare void @llvm.lifetime.end.p0(i64, ptr nocapture) 10declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) 11 12define void @OneVarNoInit() sanitize_memtag { 13; CHECK-LABEL: define void @OneVarNoInit( 14; CHECK-SAME: ) #[[ATTR2:[0-9]+]] { 15; CHECK-NEXT: [[ENTRY:.*:]] 16; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 17; CHECK-NEXT: [[X:%.*]] = alloca { i32, [12 x i8] }, align 16 18; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 19; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]]) 20; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[TX]], i64 16) 21; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 22; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16) 23; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]]) 24; CHECK-NEXT: ret void 25; 26entry: 27 %x = alloca i32, align 4 28 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x) 29 call void @use(ptr nonnull %x) 30 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x) 31 ret void 32} 33 34 35define void @OneVarInitConst() sanitize_memtag { 36; CHECK-LABEL: define void @OneVarInitConst( 37; CHECK-SAME: ) #[[ATTR2]] { 38; CHECK-NEXT: [[ENTRY:.*:]] 39; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 40; CHECK-NEXT: [[X:%.*]] = alloca { i32, [12 x i8] }, align 16 41; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 42; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]]) 43; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 42, i64 0) 44; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 45; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16) 46; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]]) 47; CHECK-NEXT: ret void 48; 49entry: 50 %x = alloca i32, align 4 51 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x) 52 store i32 42, ptr %x, align 4 53 call void @use(ptr nonnull %x) 54 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x) 55 ret void 56} 57 58; Untagging before lifetime.end: 59 60define void @ArrayInitConst() sanitize_memtag { 61; CHECK-LABEL: define void @ArrayInitConst( 62; CHECK-SAME: ) #[[ATTR2]] { 63; CHECK-NEXT: [[ENTRY:.*:]] 64; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 65; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 16, align 16 66; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 67; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr nonnull [[X]]) 68; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 42, i64 0) 69; CHECK-NEXT: [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16 70; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_16]], i64 48) 71; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 72; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 64) 73; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr nonnull [[X]]) 74; CHECK-NEXT: ret void 75; 76entry: 77 %x = alloca i32, i32 16, align 4 78 call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x) 79 store i32 42, ptr %x, align 4 80 call void @use(ptr nonnull %x) 81 call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x) 82 ret void 83} 84 85 86define void @ArrayInitConst2() sanitize_memtag { 87; CHECK-LABEL: define void @ArrayInitConst2( 88; CHECK-SAME: ) #[[ATTR2]] { 89; CHECK-NEXT: [[ENTRY:.*:]] 90; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 91; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 16, align 16 92; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 93; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr nonnull [[X]]) 94; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 1 95; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[TX]], i32 2 96; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 184683593770, i64 -1) 97; CHECK-NEXT: [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16 98; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_16]], i64 48) 99; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 100; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 64) 101; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr nonnull [[X]]) 102; CHECK-NEXT: ret void 103; 104entry: 105 %x = alloca i32, i32 16, align 4 106 call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x) 107 store i32 42, ptr %x, align 4 108 %0 = getelementptr i32, ptr %x, i32 1 109 store i32 43, ptr %0, align 4 110 %1 = getelementptr i32, ptr %x, i32 2 111 store i64 -1, ptr %1, align 4 112 call void @use(ptr nonnull %x) 113 call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x) 114 ret void 115} 116 117 118define void @ArrayInitConstSplit() sanitize_memtag { 119; CHECK-LABEL: define void @ArrayInitConstSplit( 120; CHECK-SAME: ) #[[ATTR2]] { 121; CHECK-NEXT: [[ENTRY:.*:]] 122; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 123; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 16, align 16 124; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 125; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr nonnull [[X]]) 126; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 1 127; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 -4294967296, i64 4294967295) 128; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TX]], i32 16 129; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TMP1]], i64 48) 130; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 131; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 64) 132; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr nonnull [[X]]) 133; CHECK-NEXT: ret void 134; 135entry: 136 %x = alloca i32, i32 16, align 4 137 call void @llvm.lifetime.start.p0(i64 64, ptr nonnull %x) 138 %0 = getelementptr i32, ptr %x, i32 1 139 store i64 -1, ptr %0, align 4 140 call void @use(ptr nonnull %x) 141 call void @llvm.lifetime.end.p0(i64 64, ptr nonnull %x) 142 ret void 143} 144 145 146define void @ArrayInitConstWithHoles() sanitize_memtag { 147; CHECK-LABEL: define void @ArrayInitConstWithHoles( 148; CHECK-SAME: ) #[[ATTR2]] { 149; CHECK-NEXT: [[ENTRY:.*:]] 150; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 151; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 32, align 16 152; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 153; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 128, ptr nonnull [[X]]) 154; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 5 155; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[TX]], i32 14 156; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX]], i64 16) 157; CHECK-NEXT: [[TX8_16:%.*]] = getelementptr i8, ptr [[TX]], i32 16 158; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX8_16]], i64 180388626432, i64 0) 159; CHECK-NEXT: [[TX8_32:%.*]] = getelementptr i8, ptr [[TX]], i32 32 160; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_32]], i64 16) 161; CHECK-NEXT: [[TX8_48:%.*]] = getelementptr i8, ptr [[TX]], i32 48 162; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX8_48]], i64 0, i64 43) 163; CHECK-NEXT: [[TX8_64:%.*]] = getelementptr i8, ptr [[TX]], i32 64 164; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX8_64]], i64 64) 165; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 166; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 128) 167; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 128, ptr nonnull [[X]]) 168; CHECK-NEXT: ret void 169; 170entry: 171 %x = alloca i32, i32 32, align 4 172 call void @llvm.lifetime.start.p0(i64 128, ptr nonnull %x) 173 %0 = getelementptr i32, ptr %x, i32 5 174 store i32 42, ptr %0, align 4 175 %1 = getelementptr i32, ptr %x, i32 14 176 store i32 43, ptr %1, align 4 177 call void @use(ptr nonnull %x) 178 call void @llvm.lifetime.end.p0(i64 128, ptr nonnull %x) 179 ret void 180} 181 182 183define void @InitNonConst(i32 %v) sanitize_memtag { 184; CHECK-LABEL: define void @InitNonConst( 185; CHECK-SAME: i32 [[V:%.*]]) #[[ATTR2]] { 186; CHECK-NEXT: [[ENTRY:.*:]] 187; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 188; CHECK-NEXT: [[X:%.*]] = alloca { i32, [12 x i8] }, align 16 189; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 190; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]]) 191; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[V]] to i64 192; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 [[TMP0]], i64 0) 193; CHECK-NEXT: call void @use(ptr nonnull [[X_TAG]]) 194; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16) 195; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]]) 196; CHECK-NEXT: ret void 197; 198entry: 199 %x = alloca i32, align 4 200 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x) 201 store i32 %v, ptr %x, align 4 202 call void @use(ptr nonnull %x) 203 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x) 204 ret void 205} 206 207 208define void @InitNonConst2(i32 %v, i32 %w) sanitize_memtag { 209; CHECK-LABEL: define void @InitNonConst2( 210; CHECK-SAME: i32 [[V:%.*]], i32 [[W:%.*]]) #[[ATTR2]] { 211; CHECK-NEXT: [[ENTRY:.*:]] 212; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 213; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 4, align 16 214; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 215; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[X]]) 216; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[V]] to i64 217; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[TX]], i32 1 218; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[W]] to i64 219; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[TMP2]], 32 220; CHECK-NEXT: [[VW:%.*]] = or i64 [[TMP0]], [[TMP3]] 221; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 [[VW]], i64 0) 222; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 223; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16) 224; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[X]]) 225; CHECK-NEXT: ret void 226; 227entry: 228 %x = alloca i32, i32 4, align 4 229 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x) 230 store i32 %v, ptr %x, align 4 231 %0 = getelementptr i32, ptr %x, i32 1 232 store i32 %w, ptr %0, align 4 233 call void @use(ptr nonnull %x) 234 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x) 235 ret void 236} 237 238 239define void @InitVector() sanitize_memtag { 240; CHECK-LABEL: define void @InitVector( 241; CHECK-SAME: ) #[[ATTR2]] { 242; CHECK-NEXT: [[ENTRY:.*:]] 243; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 244; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 4, align 16 245; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 246; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[X]]) 247; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), i64 0) 248; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 249; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16) 250; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[X]]) 251; CHECK-NEXT: ret void 252; 253entry: 254 %x = alloca i32, i32 4, align 4 255 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x) 256 store <2 x i32> <i32 1, i32 2>, ptr %x, align 4 257 call void @use(ptr nonnull %x) 258 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x) 259 ret void 260} 261 262 263define void @InitVectorPtr(ptr %p) sanitize_memtag { 264; CHECK-LABEL: define void @InitVectorPtr( 265; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR2]] { 266; CHECK-NEXT: [[ENTRY:.*:]] 267; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 268; CHECK-NEXT: [[S:%.*]] = alloca <4 x ptr>, align 16 269; CHECK-NEXT: [[S_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[S]], ptr [[BASETAG]], i64 0) 270; CHECK-NEXT: [[V0:%.*]] = insertelement <4 x ptr> undef, ptr [[P]], i32 0 271; CHECK-NEXT: [[V1:%.*]] = shufflevector <4 x ptr> [[V0]], <4 x ptr> undef, <4 x i32> zeroinitializer 272; CHECK-NEXT: [[V2:%.*]] = ptrtoint <4 x ptr> [[V1]] to <4 x i64> 273; CHECK-NEXT: [[V3:%.*]] = bitcast <4 x i64> [[V2]] to i256 274; CHECK-NEXT: [[A1:%.*]] = trunc i256 [[V3]] to i64 275; CHECK-NEXT: [[A2_:%.*]] = lshr i256 [[V3]], 64 276; CHECK-NEXT: [[A2:%.*]] = trunc i256 [[A2_]] to i64 277; CHECK-NEXT: [[A3_:%.*]] = lshr i256 [[V3]], 128 278; CHECK-NEXT: [[A3:%.*]] = trunc i256 [[A3_]] to i64 279; CHECK-NEXT: [[A4_:%.*]] = lshr i256 [[V3]], 192 280; CHECK-NEXT: [[A4:%.*]] = trunc i256 [[A4_]] to i64 281; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[S_TAG]], i64 [[A1]], i64 [[A2]]) 282; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[S_TAG]], i32 16 283; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP9]], i64 [[A3]], i64 [[A4]]) 284; CHECK-NEXT: call void @use(ptr nonnull [[S_TAG]]) 285; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[S]], i64 32) 286; CHECK-NEXT: ret void 287; 288entry: 289 %s = alloca <4 x ptr>, align 8 290 %v0 = insertelement <4 x ptr> undef, ptr %p, i32 0 291 %v1 = shufflevector <4 x ptr> %v0, <4 x ptr> undef, <4 x i32> zeroinitializer 292 store <4 x ptr> %v1, ptr %s 293 call void @use(ptr nonnull %s) 294 ret void 295} 296 297 298define void @InitVectorSplit() sanitize_memtag { 299; CHECK-LABEL: define void @InitVectorSplit( 300; CHECK-SAME: ) #[[ATTR2]] { 301; CHECK-NEXT: [[ENTRY:.*:]] 302; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 303; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 4, align 16 304; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 305; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[X]]) 306; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[TX]], i32 1 307; CHECK-NEXT: [[TMP1:%.*]] = shl i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), 32 308; CHECK-NEXT: [[LSHR:%.*]] = lshr i64 bitcast (<2 x i32> <i32 1, i32 2> to i64), 32 309; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TX]], i64 [[TMP1]], i64 [[LSHR]]) 310; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 311; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 16) 312; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[X]]) 313; CHECK-NEXT: ret void 314; 315entry: 316 %x = alloca i32, i32 4, align 4 317 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %x) 318 %0 = getelementptr i32, ptr %x, i32 1 319 store <2 x i32> <i32 1, i32 2>, ptr %0, align 4 320 call void @use(ptr nonnull %x) 321 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %x) 322 ret void 323} 324 325 326define void @MemSetZero() sanitize_memtag { 327; CHECK-LABEL: define void @MemSetZero( 328; CHECK-SAME: ) #[[ATTR2]] { 329; CHECK-NEXT: [[ENTRY:.*:]] 330; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 331; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 8, align 16 332; CHECK-NEXT: [[TX:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 333; CHECK-NEXT: call void @llvm.aarch64.settag.zero(ptr [[TX]], i64 32) 334; CHECK-NEXT: call void @use(ptr nonnull [[TX]]) 335; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32) 336; CHECK-NEXT: ret void 337; 338entry: 339 %x = alloca i32, i32 8, align 16 340 call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 0, i64 32, i1 false) 341 call void @use(ptr nonnull %x) 342 ret void 343} 344 345 346 347define void @MemSetNonZero() sanitize_memtag { 348; CHECK-LABEL: define void @MemSetNonZero( 349; CHECK-SAME: ) #[[ATTR2]] { 350; CHECK-NEXT: [[ENTRY:.*:]] 351; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 352; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 8, align 16 353; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 354; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 3038287259199220266, i64 3038287259199220266) 355; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[X_TAG]], i32 16 356; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP0]], i64 3038287259199220266, i64 3038287259199220266) 357; CHECK-NEXT: call void @use(ptr nonnull [[X_TAG]]) 358; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32) 359; CHECK-NEXT: ret void 360; 361entry: 362 %x = alloca i32, i32 8, align 16 363 call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 42, i64 32, i1 false) 364 call void @use(ptr nonnull %x) 365 ret void 366} 367 368 369 370define void @MemSetNonZero2() sanitize_memtag { 371; CHECK-LABEL: define void @MemSetNonZero2( 372; CHECK-SAME: ) #[[ATTR2]] { 373; CHECK-NEXT: [[ENTRY:.*:]] 374; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 375; CHECK-NEXT: [[X:%.*]] = alloca [32 x i8], align 16 376; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 377; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [32 x i8], ptr [[X_TAG]], i64 0, i64 2 378; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 3038287259199209472, i64 3038287259199220266) 379; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[X_TAG]], i32 16 380; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP1]], i64 3038287259199220266, i64 46360584399402) 381; CHECK-NEXT: call void @use(ptr nonnull [[TMP0]]) 382; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32) 383; CHECK-NEXT: ret void 384; 385entry: 386 %x = alloca [32 x i8], align 16 387 %0 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 2 388 call void @llvm.memset.p0.i64(ptr nonnull %0, i8 42, i64 28, i1 false) 389 call void @use(ptr nonnull %0) 390 ret void 391} 392 393 394define void @MemSetNonZero3() sanitize_memtag { 395; CHECK-LABEL: define void @MemSetNonZero3( 396; CHECK-SAME: ) #[[ATTR2]] { 397; CHECK-NEXT: [[ENTRY:.*:]] 398; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 399; CHECK-NEXT: [[X:%.*]] = alloca [32 x i8], align 16 400; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 401; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds [32 x i8], ptr [[X_TAG]], i64 0, i64 2 402; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [32 x i8], ptr [[X_TAG]], i64 0, i64 24 403; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[X_TAG]], i64 46360584388608, i64 0) 404; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[X_TAG]], i32 16 405; CHECK-NEXT: call void @llvm.aarch64.stgp(ptr [[TMP2]], i64 0, i64 3038287259199220266) 406; CHECK-NEXT: call void @use(ptr nonnull [[TMP0]]) 407; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 32) 408; CHECK-NEXT: ret void 409; 410entry: 411 %x = alloca [32 x i8], align 16 412 %0 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 2 413 call void @llvm.memset.p0.i64(ptr nonnull %0, i8 42, i64 4, i1 false) 414 %1 = getelementptr inbounds [32 x i8], ptr %x, i64 0, i64 24 415 call void @llvm.memset.p0.i64(ptr nonnull %1, i8 42, i64 8, i1 false) 416 call void @use(ptr nonnull %0) 417 ret void 418} 419 420 421define void @LargeAlloca() sanitize_memtag { 422; CHECK-LABEL: define void @LargeAlloca( 423; CHECK-SAME: ) #[[ATTR2]] { 424; CHECK-NEXT: [[ENTRY:.*:]] 425; CHECK-NEXT: [[BASETAG:%.*]] = call ptr @llvm.aarch64.irg.sp(i64 0) 426; CHECK-NEXT: [[X:%.*]] = alloca i32, i32 256, align 16 427; CHECK-NEXT: [[X_TAG:%.*]] = call ptr @llvm.aarch64.tagp.p0(ptr [[X]], ptr [[BASETAG]], i64 0) 428; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X_TAG]], i64 1024) 429; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr nonnull align 16 [[X_TAG]], i8 42, i64 256, i1 false) 430; CHECK-NEXT: call void @use(ptr nonnull [[X_TAG]]) 431; CHECK-NEXT: call void @llvm.aarch64.settag(ptr [[X]], i64 1024) 432; CHECK-NEXT: ret void 433; 434entry: 435 %x = alloca i32, i32 256, align 16 436 call void @llvm.memset.p0.i64(ptr nonnull align 16 %x, i8 42, i64 256, i1 false) 437 call void @use(ptr nonnull %x) 438 ret void 439} 440 441