1; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LOCAL 2; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7@sink = global i8* null, align 8 8 9declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile) 10declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile) 11declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile) 12declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile) 13 14; Address leaked. 15define void @LeakAddress() { 16; CHECK-LABEL: @LeakAddress dso_preemptable{{$}} 17; CHECK-NEXT: args uses: 18; CHECK-NEXT: allocas uses: 19; CHECK-NEXT: x[4]: full-set{{$}} 20; CHECK-EMPTY: 21entry: 22 %x = alloca i32, align 4 23 %x1 = bitcast i32* %x to i8* 24 store i8* %x1, i8** @sink, align 8 25 ret void 26} 27 28define void @StoreInBounds() { 29; CHECK-LABEL: @StoreInBounds dso_preemptable{{$}} 30; CHECK-NEXT: args uses: 31; CHECK-NEXT: allocas uses: 32; CHECK-NEXT: x[4]: [0,1){{$}} 33; CHECK-EMPTY: 34entry: 35 %x = alloca i32, align 4 36 %x1 = bitcast i32* %x to i8* 37 store i8 0, i8* %x1, align 1 38 ret void 39} 40 41define void @StoreInBounds2() { 42; CHECK-LABEL: @StoreInBounds2 dso_preemptable{{$}} 43; CHECK-NEXT: args uses: 44; CHECK-NEXT: allocas uses: 45; CHECK-NEXT: x[4]: [0,4){{$}} 46; CHECK-EMPTY: 47entry: 48 %x = alloca i32, align 4 49 store i32 0, i32* %x, align 4 50 ret void 51} 52 53define void @StoreInBounds3() { 54; CHECK-LABEL: @StoreInBounds3 dso_preemptable{{$}} 55; CHECK-NEXT: args uses: 56; CHECK-NEXT: allocas uses: 57; CHECK-NEXT: x[4]: [2,3){{$}} 58; CHECK-EMPTY: 59entry: 60 %x = alloca i32, align 4 61 %x1 = bitcast i32* %x to i8* 62 %x2 = getelementptr i8, i8* %x1, i64 2 63 store i8 0, i8* %x2, align 1 64 ret void 65} 66 67; FIXME: ScalarEvolution does not look through ptrtoint/inttoptr. 68define void @StoreInBounds4() { 69; CHECK-LABEL: @StoreInBounds4 dso_preemptable{{$}} 70; CHECK-NEXT: args uses: 71; CHECK-NEXT: allocas uses: 72; CHECK-NEXT: x[4]: full-set{{$}} 73; CHECK-EMPTY: 74entry: 75 %x = alloca i32, align 4 76 %x1 = ptrtoint i32* %x to i64 77 %x2 = add i64 %x1, 2 78 %x3 = inttoptr i64 %x2 to i8* 79 store i8 0, i8* %x3, align 1 80 ret void 81} 82 83define dso_local void @WriteMinMax(i8* %p) { 84; CHECK-LABEL: @WriteMinMax{{$}} 85; CHECK-NEXT: args uses: 86; CHECK-NEXT: p[]: full-set 87; CHECK-NEXT: allocas uses: 88; CHECK-EMPTY: 89entry: 90 %p1 = getelementptr i8, i8* %p, i64 9223372036854775805 91 store i8 0, i8* %p1, align 1 92 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775805 93 store i8 0, i8* %p2, align 1 94 ret void 95} 96 97define dso_local void @WriteMax(i8* %p) { 98; CHECK-LABEL: @WriteMax{{$}} 99; CHECK-NEXT: args uses: 100; CHECK-NEXT: p[]: [-9223372036854775807,9223372036854775806) 101; CHECK-NEXT: allocas uses: 102; CHECK-EMPTY: 103entry: 104 call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 0) 105 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775807 106 call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 0) 107 ret void 108} 109 110define void @StoreOutOfBounds() { 111; CHECK-LABEL: @StoreOutOfBounds dso_preemptable{{$}} 112; CHECK-NEXT: args uses: 113; CHECK-NEXT: allocas uses: 114; CHECK-NEXT: x[4]: [2,6){{$}} 115; CHECK-EMPTY: 116entry: 117 %x = alloca i32, align 4 118 %x1 = bitcast i32* %x to i8* 119 %x2 = getelementptr i8, i8* %x1, i64 2 120 %x3 = bitcast i8* %x2 to i32* 121 store i32 0, i32* %x3, align 1 122 ret void 123} 124 125; There is no difference in load vs store handling. 126define void @LoadInBounds() { 127; CHECK-LABEL: @LoadInBounds dso_preemptable{{$}} 128; CHECK-NEXT: args uses: 129; CHECK-NEXT: allocas uses: 130; CHECK-NEXT: x[4]: [0,1){{$}} 131; CHECK-EMPTY: 132entry: 133 %x = alloca i32, align 4 134 %x1 = bitcast i32* %x to i8* 135 %v = load i8, i8* %x1, align 1 136 ret void 137} 138 139define void @LoadOutOfBounds() { 140; CHECK-LABEL: @LoadOutOfBounds dso_preemptable{{$}} 141; CHECK-NEXT: args uses: 142; CHECK-NEXT: allocas uses: 143; CHECK-NEXT: x[4]: [2,6){{$}} 144; CHECK-EMPTY: 145entry: 146 %x = alloca i32, align 4 147 %x1 = bitcast i32* %x to i8* 148 %x2 = getelementptr i8, i8* %x1, i64 2 149 %x3 = bitcast i8* %x2 to i32* 150 %v = load i32, i32* %x3, align 1 151 ret void 152} 153 154; Leak through ret. 155define i8* @Ret() { 156; CHECK-LABEL: @Ret dso_preemptable{{$}} 157; CHECK-NEXT: args uses: 158; CHECK-NEXT: allocas uses: 159; CHECK-NEXT: x[4]: full-set{{$}} 160; CHECK-EMPTY: 161entry: 162 %x = alloca i32, align 4 163 %x1 = bitcast i32* %x to i8* 164 %x2 = getelementptr i8, i8* %x1, i64 2 165 ret i8* %x2 166} 167 168declare void @Foo(i16* %p) 169 170define void @DirectCall() { 171; CHECK-LABEL: @DirectCall dso_preemptable{{$}} 172; CHECK-NEXT: args uses: 173; CHECK-NEXT: allocas uses: 174; LOCAL-NEXT: x[8]: empty-set, @Foo(arg0, [2,3)){{$}} 175; GLOBAL-NEXT: x[8]: full-set, @Foo(arg0, [2,3)){{$}} 176; CHECK-EMPTY: 177entry: 178 %x = alloca i64, align 4 179 %x1 = bitcast i64* %x to i16* 180 %x2 = getelementptr i16, i16* %x1, i64 1 181 call void @Foo(i16* %x2); 182 ret void 183} 184 185; Indirect calls can not be analyzed (yet). 186; FIXME: %p[]: full-set looks invalid 187define void @IndirectCall(void (i8*)* %p) { 188; CHECK-LABEL: @IndirectCall dso_preemptable{{$}} 189; CHECK-NEXT: args uses: 190; CHECK-NEXT: p[]: full-set{{$}} 191; CHECK-NEXT: allocas uses: 192; CHECK-NEXT: x[4]: full-set{{$}} 193; CHECK-EMPTY: 194entry: 195 %x = alloca i32, align 4 196 %x1 = bitcast i32* %x to i8* 197 call void %p(i8* %x1); 198 ret void 199} 200 201define void @NonConstantOffset(i1 zeroext %z) { 202; CHECK-LABEL: @NonConstantOffset dso_preemptable{{$}} 203; CHECK-NEXT: args uses: 204; CHECK-NEXT: allocas uses: 205; FIXME: SCEV can't look through selects. 206; CHECK-NEXT: x[4]: [0,4){{$}} 207; CHECK-EMPTY: 208entry: 209 %x = alloca i32, align 4 210 %x1 = bitcast i32* %x to i8* 211 %idx = select i1 %z, i64 1, i64 2 212 %x2 = getelementptr i8, i8* %x1, i64 %idx 213 store i8 0, i8* %x2, align 1 214 ret void 215} 216 217define void @NegativeOffset() { 218; CHECK-LABEL: @NegativeOffset dso_preemptable{{$}} 219; CHECK-NEXT: args uses: 220; CHECK-NEXT: allocas uses: 221; CHECK-NEXT: x[40]: [-1600000000000,-1599999999996){{$}} 222; CHECK-EMPTY: 223entry: 224 %x = alloca i32, i32 10, align 4 225 %x2 = getelementptr i32, i32* %x, i64 -400000000000 226 store i32 0, i32* %x2, align 1 227 ret void 228} 229 230define void @PossiblyNegativeOffset(i16 %z) { 231; CHECK-LABEL: @PossiblyNegativeOffset dso_preemptable{{$}} 232; CHECK-NEXT: args uses: 233; CHECK-NEXT: allocas uses: 234; CHECK-NEXT: x[40]: [-131072,131072){{$}} 235; CHECK-EMPTY: 236entry: 237 %x = alloca i32, i32 10, align 4 238 %x2 = getelementptr i32, i32* %x, i16 %z 239 store i32 0, i32* %x2, align 1 240 ret void 241} 242 243define void @NonConstantOffsetOOB(i1 zeroext %z) { 244; CHECK-LABEL: @NonConstantOffsetOOB dso_preemptable{{$}} 245; CHECK-NEXT: args uses: 246; CHECK-NEXT: allocas uses: 247; CHECK-NEXT: x[4]: [0,6){{$}} 248; CHECK-EMPTY: 249entry: 250 %x = alloca i32, align 4 251 %x1 = bitcast i32* %x to i8* 252 %idx = select i1 %z, i64 1, i64 4 253 %x2 = getelementptr i8, i8* %x1, i64 %idx 254 store i8 0, i8* %x2, align 1 255 ret void 256} 257 258define void @ArrayAlloca() { 259; CHECK-LABEL: @ArrayAlloca dso_preemptable{{$}} 260; CHECK-NEXT: args uses: 261; CHECK-NEXT: allocas uses: 262; CHECK-NEXT: x[40]: [36,40){{$}} 263; CHECK-EMPTY: 264entry: 265 %x = alloca i32, i32 10, align 4 266 %x1 = bitcast i32* %x to i8* 267 %x2 = getelementptr i8, i8* %x1, i64 36 268 %x3 = bitcast i8* %x2 to i32* 269 store i32 0, i32* %x3, align 1 270 ret void 271} 272 273define void @ArrayAllocaOOB() { 274; CHECK-LABEL: @ArrayAllocaOOB dso_preemptable{{$}} 275; CHECK-NEXT: args uses: 276; CHECK-NEXT: allocas uses: 277; CHECK-NEXT: x[40]: [37,41){{$}} 278; CHECK-EMPTY: 279entry: 280 %x = alloca i32, i32 10, align 4 281 %x1 = bitcast i32* %x to i8* 282 %x2 = getelementptr i8, i8* %x1, i64 37 283 %x3 = bitcast i8* %x2 to i32* 284 store i32 0, i32* %x3, align 1 285 ret void 286} 287 288define void @DynamicAllocaUnused(i64 %size) { 289; CHECK-LABEL: @DynamicAllocaUnused dso_preemptable{{$}} 290; CHECK-NEXT: args uses: 291; CHECK-NEXT: allocas uses: 292; CHECK-NEXT: x[0]: empty-set{{$}} 293; CHECK-EMPTY: 294entry: 295 %x = alloca i32, i64 %size, align 16 296 ret void 297} 298 299; Dynamic alloca with unknown size. 300define void @DynamicAlloca(i64 %size) { 301; CHECK-LABEL: @DynamicAlloca dso_preemptable{{$}} 302; CHECK-NEXT: args uses: 303; CHECK-NEXT: allocas uses: 304; CHECK-NEXT: x[0]: [0,4){{$}} 305; CHECK-EMPTY: 306entry: 307 %x = alloca i32, i64 %size, align 16 308 store i32 0, i32* %x, align 1 309 ret void 310} 311 312; Dynamic alloca with limited size. 313; FIXME: could be proved safe. Implement. 314define void @DynamicAllocaFiniteSizeRange(i1 zeroext %z) { 315; CHECK-LABEL: @DynamicAllocaFiniteSizeRange dso_preemptable{{$}} 316; CHECK-NEXT: args uses: 317; CHECK-NEXT: allocas uses: 318; CHECK-NEXT: x[0]: [0,4){{$}} 319; CHECK-EMPTY: 320entry: 321 %size = select i1 %z, i64 3, i64 5 322 %x = alloca i32, i64 %size, align 16 323 store i32 0, i32* %x, align 1 324 ret void 325} 326 327define signext i8 @SimpleLoop() { 328; CHECK-LABEL: @SimpleLoop dso_preemptable{{$}} 329; CHECK-NEXT: args uses: 330; CHECK-NEXT: allocas uses: 331; CHECK-NEXT: x[10]: [0,10){{$}} 332; CHECK-EMPTY: 333entry: 334 %x = alloca [10 x i8], align 1 335 %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0 336 %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 10 337 br label %for.body 338 339for.body: 340 %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ] 341 %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ] 342 %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1 343 %1 = load volatile i8, i8* %p.09, align 1 344 %add = add i8 %1, %sum.010 345 %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit 346 br i1 %exitcond, label %for.cond.cleanup, label %for.body 347 348for.cond.cleanup: 349 ret i8 %add 350} 351 352; OOB in a loop. 353define signext i8 @SimpleLoopOOB() { 354; CHECK-LABEL: @SimpleLoopOOB dso_preemptable{{$}} 355; CHECK-NEXT: args uses: 356; CHECK-NEXT: allocas uses: 357; CHECK-NEXT: x[10]: [0,11){{$}} 358; CHECK-EMPTY: 359entry: 360 %x = alloca [10 x i8], align 1 361 %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0 362 ; 11 iterations 363 %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 11 364 br label %for.body 365 366for.body: 367 %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ] 368 %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ] 369 %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1 370 %1 = load volatile i8, i8* %p.09, align 1 371 %add = add i8 %1, %sum.010 372 %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit 373 br i1 %exitcond, label %for.cond.cleanup, label %for.body 374 375for.cond.cleanup: 376 ret i8 %add 377} 378 379define dso_local void @SizeCheck(i32 %sz) { 380; CHECK-LABEL: @SizeCheck{{$}} 381; CHECK-NEXT: args uses: 382; CHECK-NEXT: allocas uses: 383; CHECK-NEXT: x1[128]: [0,4294967295){{$}} 384; CHECK-EMPTY: 385entry: 386 %x1 = alloca [128 x i8], align 16 387 %x1.sub = getelementptr inbounds [128 x i8], [128 x i8]* %x1, i64 0, i64 0 388 %cmp = icmp slt i32 %sz, 129 389 br i1 %cmp, label %if.then, label %if.end 390 391if.then: 392 call void @llvm.memset.p0i8.i32(i8* nonnull align 16 %x1.sub, i8 0, i32 %sz, i1 false) 393 br label %if.end 394 395if.end: 396 ret void 397} 398 399; FIXME: scalable allocas are considered to be of size zero, and scalable accesses to be full-range. 400; This effectively disables safety analysis for scalable allocations. 401define void @Scalable(<vscale x 4 x i32>* %p, <vscale x 4 x i32>* %unused, <vscale x 4 x i32> %v) { 402; CHECK-LABEL: @Scalable dso_preemptable{{$}} 403; CHECK-NEXT: args uses: 404; CHECK-NEXT: p[]: full-set 405; CHECK-NEXT: unused[]: empty-set 406; CHECK-NEXT: allocas uses: 407; CHECK-NEXT: x[0]: [0,1){{$}} 408; CHECK-EMPTY: 409entry: 410 %x = alloca <vscale x 4 x i32>, align 4 411 %x1 = bitcast <vscale x 4 x i32>* %x to i8* 412 store i8 0, i8* %x1, align 1 413 store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4 414 ret void 415} 416 417%zerosize_type = type {} 418 419define void @ZeroSize(%zerosize_type *%p) { 420; CHECK-LABEL: @ZeroSize dso_preemptable{{$}} 421; CHECK-NEXT: args uses: 422; CHECK-NEXT: p[]: empty-set 423; CHECK-NEXT: allocas uses: 424; CHECK-NEXT: x[0]: empty-set 425; CHECK-EMPTY: 426entry: 427 %x = alloca %zerosize_type, align 4 428 store %zerosize_type undef, %zerosize_type* %x, align 4 429 store %zerosize_type undef, %zerosize_type* undef, align 4 430 %val = load %zerosize_type, %zerosize_type* %p, align 4 431 ret void 432} 433 434define void @OperandBundle() { 435; CHECK-LABEL: @OperandBundle dso_preemptable{{$}} 436; CHECK-NEXT: args uses: 437; CHECK-NEXT: allocas uses: 438; CHECK-NEXT: a[4]: full-set 439; CHECK-EMPTY: 440entry: 441 %a = alloca i32, align 4 442 call void @LeakAddress() ["unknown"(i32* %a)] 443 ret void 444} 445 446define void @ByVal(i16* byval(i16) %p) { 447 ; CHECK-LABEL: @ByVal dso_preemptable{{$}} 448 ; CHECK-NEXT: args uses: 449 ; CHECK-NEXT: allocas uses: 450 ; CHECK-EMPTY: 451entry: 452 ret void 453} 454 455define void @TestByVal() { 456; CHECK-LABEL: @TestByVal dso_preemptable{{$}} 457; CHECK-NEXT: args uses: 458; CHECK-NEXT: allocas uses: 459; CHECK-NEXT: x[2]: [0,2) 460; CHECK-NEXT: y[8]: [0,2) 461; CHECK-EMPTY: 462entry: 463 %x = alloca i16, align 4 464 call void @ByVal(i16* byval(i16) %x) 465 466 %y = alloca i64, align 4 467 %y1 = bitcast i64* %y to i16* 468 call void @ByVal(i16* byval(i16) %y1) 469 470 ret void 471} 472 473declare void @ByValArray([100000 x i64]* byval([100000 x i64]) %p) 474 475define void @TestByValArray() { 476; CHECK-LABEL: @TestByValArray dso_preemptable{{$}} 477; CHECK-NEXT: args uses: 478; CHECK-NEXT: allocas uses: 479; CHECK-NEXT: z[800000]: [500000,1300000) 480; CHECK-EMPTY: 481entry: 482 %z = alloca [100000 x i64], align 4 483 %z1 = bitcast [100000 x i64]* %z to i8* 484 %z2 = getelementptr i8, i8* %z1, i64 500000 485 %z3 = bitcast i8* %z2 to [100000 x i64]* 486 call void @ByValArray([100000 x i64]* byval([100000 x i64]) %z3) 487 ret void 488} 489 490define dso_local i8 @LoadMinInt64(i8* %p) { 491 ; CHECK-LABEL: @LoadMinInt64{{$}} 492 ; CHECK-NEXT: args uses: 493 ; CHECK-NEXT: p[]: [-9223372036854775808,-9223372036854775807){{$}} 494 ; CHECK-NEXT: allocas uses: 495 ; CHECK-EMPTY: 496 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775808 497 %v = load i8, i8* %p2, align 1 498 ret i8 %v 499} 500 501define void @Overflow() { 502; CHECK-LABEL: @Overflow dso_preemptable{{$}} 503; CHECK-NEXT: args uses: 504; CHECK-NEXT: allocas uses: 505; LOCAL-NEXT: x[1]: empty-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}} 506; GLOBAL-NEXT: x[1]: full-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}} 507; CHECK-EMPTY: 508entry: 509 %x = alloca i8, align 4 510 %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808 511 %v = call i8 @LoadMinInt64(i8* %x2) 512 ret void 513} 514 515define void @DeadBlock(i64* %p) { 516; CHECK-LABEL: @DeadBlock dso_preemptable{{$}} 517; CHECK-NEXT: args uses: 518; CHECK-NEXT: p[]: empty-set{{$}} 519; CHECK-NEXT: allocas uses: 520; CHECK-NEXT: x[1]: empty-set{{$}} 521; CHECK-EMPTY: 522entry: 523 %x = alloca i8, align 4 524 br label %end 525 526dead: 527 store i8 5, i8* %x 528 store i64 -5, i64* %p 529 br label %end 530 531end: 532 ret void 533} 534 535define void @LifeNotStarted() { 536; CHECK-LABEL: @LifeNotStarted dso_preemptable{{$}} 537; CHECK-NEXT: args uses: 538; CHECK-NEXT: allocas uses: 539; CHECK: x[1]: full-set{{$}} 540; CHECK: y[1]: full-set{{$}} 541; CHECK: z[1]: full-set{{$}} 542; CHECK-EMPTY: 543entry: 544 %x = alloca i8, align 4 545 %y = alloca i8, align 4 546 %z = alloca i8, align 4 547 548 store i8 5, i8* %x 549 %n = load i8, i8* %y 550 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 551 552 call void @llvm.lifetime.start.p0i8(i64 1, i8* %x) 553 call void @llvm.lifetime.start.p0i8(i64 1, i8* %y) 554 call void @llvm.lifetime.start.p0i8(i64 1, i8* %z) 555 556 ret void 557} 558 559define void @LifeOK() { 560; CHECK-LABEL: @LifeOK dso_preemptable{{$}} 561; CHECK-NEXT: args uses: 562; CHECK-NEXT: allocas uses: 563; CHECK: x[1]: [0,1){{$}} 564; CHECK: y[1]: [0,1){{$}} 565; CHECK: z[1]: [0,1){{$}} 566; CHECK-EMPTY: 567entry: 568 %x = alloca i8, align 4 569 %y = alloca i8, align 4 570 %z = alloca i8, align 4 571 572 call void @llvm.lifetime.start.p0i8(i64 1, i8* %x) 573 call void @llvm.lifetime.start.p0i8(i64 1, i8* %y) 574 call void @llvm.lifetime.start.p0i8(i64 1, i8* %z) 575 576 store i8 5, i8* %x 577 %n = load i8, i8* %y 578 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 579 580 ret void 581} 582 583define void @LifeEnded() { 584; CHECK-LABEL: @LifeEnded dso_preemptable{{$}} 585; CHECK-NEXT: args uses: 586; CHECK-NEXT: allocas uses: 587; CHECK: x[1]: full-set{{$}} 588; CHECK: y[1]: full-set{{$}} 589; CHECK: z[1]: full-set{{$}} 590; CHECK-EMPTY: 591entry: 592 %x = alloca i8, align 4 593 %y = alloca i8, align 4 594 %z = alloca i8, align 4 595 596 call void @llvm.lifetime.start.p0i8(i64 1, i8* %x) 597 call void @llvm.lifetime.start.p0i8(i64 1, i8* %y) 598 call void @llvm.lifetime.start.p0i8(i64 1, i8* %z) 599 600 call void @llvm.lifetime.end.p0i8(i64 1, i8* %x) 601 call void @llvm.lifetime.end.p0i8(i64 1, i8* %y) 602 call void @llvm.lifetime.end.p0i8(i64 1, i8* %z) 603 604 store i8 5, i8* %x 605 %n = load i8, i8* %y 606 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 607 608 ret void 609} 610 611declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) 612declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) 613