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 14declare void @unknown_call(i8* %dest) 15declare i8* @retptr(i8* returned) 16 17; Address leaked. 18define void @LeakAddress() { 19; CHECK-LABEL: @LeakAddress dso_preemptable{{$}} 20; CHECK-NEXT: args uses: 21; CHECK-NEXT: allocas uses: 22; CHECK-NEXT: x[4]: full-set{{$}} 23; GLOBAL-NEXT: safe accesses: 24; CHECK-EMPTY: 25entry: 26 %x = alloca i32, align 4 27 %x1 = bitcast i32* %x to i8* 28 store i8* %x1, i8** @sink, align 8 29 ret void 30} 31 32define void @StoreInBounds() { 33; CHECK-LABEL: @StoreInBounds dso_preemptable{{$}} 34; CHECK-NEXT: args uses: 35; CHECK-NEXT: allocas uses: 36; CHECK-NEXT: x[4]: [0,1){{$}} 37; GLOBAL-NEXT: safe accesses: 38; GLOBAL-NEXT: store i8 0, i8* %x1, align 1 39; CHECK-EMPTY: 40entry: 41 %x = alloca i32, align 4 42 %x1 = bitcast i32* %x to i8* 43 store i8 0, i8* %x1, align 1 44 ret void 45} 46 47define void @StoreInBoundsCond(i64 %i) { 48; CHECK-LABEL: @StoreInBoundsCond dso_preemptable{{$}} 49; CHECK-NEXT: args uses: 50; CHECK-NEXT: allocas uses: 51; CHECK-NEXT: x[4]: full-set{{$}} 52; GLOBAL-NEXT: safe accesses: 53; GLOBAL-NEXT: store i8 0, i8* %x2, align 1 54; CHECK-EMPTY: 55entry: 56 %x = alloca i32, align 4 57 %x1 = bitcast i32* %x to i8* 58 %c1 = icmp sge i64 %i, 0 59 %c2 = icmp slt i64 %i, 4 60 br i1 %c1, label %c1.true, label %false 61 62c1.true: 63 br i1 %c2, label %c2.true, label %false 64 65c2.true: 66 %x2 = getelementptr i8, i8* %x1, i64 %i 67 store i8 0, i8* %x2, align 1 68 br label %false 69 70false: 71 ret void 72} 73 74define void @StoreInBoundsMinMax(i64 %i) { 75; CHECK-LABEL: @StoreInBoundsMinMax dso_preemptable{{$}} 76; CHECK-NEXT: args uses: 77; CHECK-NEXT: allocas uses: 78; CHECK-NEXT: x[4]: [0,4){{$}} 79; GLOBAL-NEXT: safe accesses: 80; GLOBAL-NEXT: store i8 0, i8* %x2, align 1 81; CHECK-EMPTY: 82entry: 83 %x = alloca i32, align 4 84 %x1 = bitcast i32* %x to i8* 85 %c1 = icmp sge i64 %i, 0 86 %i1 = select i1 %c1, i64 %i, i64 0 87 %c2 = icmp slt i64 %i1, 3 88 %i2 = select i1 %c2, i64 %i1, i64 3 89 %x2 = getelementptr i8, i8* %x1, i64 %i2 90 store i8 0, i8* %x2, align 1 91 ret void 92} 93 94define void @StoreInBounds2() { 95; CHECK-LABEL: @StoreInBounds2 dso_preemptable{{$}} 96; CHECK-NEXT: args uses: 97; CHECK-NEXT: allocas uses: 98; CHECK-NEXT: x[4]: [0,4){{$}} 99; GLOBAL-NEXT: safe accesses: 100; GLOBAL-NEXT: store i32 0, i32* %x, align 4 101; CHECK-EMPTY: 102entry: 103 %x = alloca i32, align 4 104 store i32 0, i32* %x, align 4 105 ret void 106} 107 108define void @StoreInBounds3() { 109; CHECK-LABEL: @StoreInBounds3 dso_preemptable{{$}} 110; CHECK-NEXT: args uses: 111; CHECK-NEXT: allocas uses: 112; CHECK-NEXT: x[4]: [2,3){{$}} 113; GLOBAL-NEXT: safe accesses: 114; GLOBAL-NEXT: store i8 0, i8* %x2, align 1 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 store i8 0, i8* %x2, align 1 121 ret void 122} 123 124; FIXME: ScalarEvolution does not look through ptrtoint/inttoptr. 125define void @StoreInBounds4() { 126; CHECK-LABEL: @StoreInBounds4 dso_preemptable{{$}} 127; CHECK-NEXT: args uses: 128; CHECK-NEXT: allocas uses: 129; CHECK-NEXT: x[4]: full-set{{$}} 130; GLOBAL-NEXT: safe accesses: 131; CHECK-EMPTY: 132entry: 133 %x = alloca i32, align 4 134 %x1 = ptrtoint i32* %x to i64 135 %x2 = add i64 %x1, 2 136 %x3 = inttoptr i64 %x2 to i8* 137 store i8 0, i8* %x3, align 1 138 ret void 139} 140 141define void @StoreInBounds6() { 142; CHECK-LABEL: @StoreInBounds6 dso_preemptable{{$}} 143; CHECK-NEXT: args uses: 144; CHECK-NEXT: allocas uses: 145; GLOBAL-NEXT: x[4]: full-set, @retptr(arg0, [0,1)){{$}} 146; LOCAL-NEXT: x[4]: [0,1), @retptr(arg0, [0,1)){{$}} 147; GLOBAL-NEXT: safe accesses: 148; GLOBAL-NEXT: store i8 0, i8* %x2, align 1 149; CHECK-EMPTY: 150entry: 151 %x = alloca i32, align 4 152 %x1 = bitcast i32* %x to i8* 153 %x2 = call i8* @retptr(i8* %x1) 154 store i8 0, i8* %x2, align 1 155 ret void 156} 157 158define dso_local void @WriteMinMax(i8* %p) { 159; CHECK-LABEL: @WriteMinMax{{$}} 160; CHECK-NEXT: args uses: 161; CHECK-NEXT: p[]: full-set 162; CHECK-NEXT: allocas uses: 163; GLOBAL-NEXT: safe accesses: 164; GLOBAL-NEXT: store i8 0, i8* %p1, align 1 165; GLOBAL-NEXT: store i8 0, i8* %p2, align 1 166; CHECK-EMPTY: 167entry: 168 %p1 = getelementptr i8, i8* %p, i64 9223372036854775805 169 store i8 0, i8* %p1, align 1 170 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775805 171 store i8 0, i8* %p2, align 1 172 ret void 173} 174 175define dso_local void @WriteMax(i8* %p) { 176; CHECK-LABEL: @WriteMax{{$}} 177; CHECK-NEXT: args uses: 178; CHECK-NEXT: p[]: [-9223372036854775807,9223372036854775806) 179; CHECK-NEXT: allocas uses: 180; GLOBAL-NEXT: safe accesses: 181; GLOBAL-NEXT: call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 false) 182; GLOBAL-NEXT: call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 false) 183; CHECK-EMPTY: 184entry: 185 call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 0) 186 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775807 187 call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 0) 188 ret void 189} 190 191define void @StoreOutOfBounds() { 192; CHECK-LABEL: @StoreOutOfBounds dso_preemptable{{$}} 193; CHECK-NEXT: args uses: 194; CHECK-NEXT: allocas uses: 195; CHECK-NEXT: x[4]: [2,6){{$}} 196; GLOBAL-NEXT: safe accesses: 197; CHECK-EMPTY: 198entry: 199 %x = alloca i32, align 4 200 %x1 = bitcast i32* %x to i8* 201 %x2 = getelementptr i8, i8* %x1, i64 2 202 %x3 = bitcast i8* %x2 to i32* 203 store i32 0, i32* %x3, align 1 204 ret void 205} 206 207define void @StoreOutOfBoundsCond(i64 %i) { 208; CHECK-LABEL: @StoreOutOfBoundsCond dso_preemptable{{$}} 209; CHECK-NEXT: args uses: 210; CHECK-NEXT: allocas uses: 211; CHECK-NEXT: x[4]: full-set{{$}} 212; GLOBAL-NEXT: safe accesses: 213; CHECK-EMPTY: 214entry: 215 %x = alloca i32, align 4 216 %x1 = bitcast i32* %x to i8* 217 %c1 = icmp sge i64 %i, 0 218 %c2 = icmp slt i64 %i, 5 219 br i1 %c1, label %c1.true, label %false 220 221c1.true: 222 br i1 %c2, label %c2.true, label %false 223 224c2.true: 225 %x2 = getelementptr i8, i8* %x1, i64 %i 226 store i8 0, i8* %x2, align 1 227 br label %false 228 229false: 230 ret void 231} 232 233define void @StoreOutOfBoundsCond2(i64 %i) { 234; CHECK-LABEL: @StoreOutOfBoundsCond2 dso_preemptable{{$}} 235; CHECK-NEXT: args uses: 236; CHECK-NEXT: allocas uses: 237; CHECK-NEXT: x[4]: full-set{{$}} 238; GLOBAL-NEXT: safe accesses: 239; CHECK-EMPTY: 240entry: 241 %x = alloca i32, align 4 242 %x1 = bitcast i32* %x to i8* 243 %c2 = icmp slt i64 %i, 5 244 br i1 %c2, label %c2.true, label %false 245 246c2.true: 247 %x2 = getelementptr i8, i8* %x1, i64 %i 248 store i8 0, i8* %x2, align 1 249 br label %false 250 251false: 252 ret void 253} 254 255define void @StoreOutOfBounds2() { 256; CHECK-LABEL: @StoreOutOfBounds2 dso_preemptable{{$}} 257; CHECK-NEXT: args uses: 258; CHECK-NEXT: allocas uses: 259; GLOBAL-NEXT: x[4]: full-set, @retptr(arg0, [2,3)){{$}} 260; LOCAL-NEXT: x[4]: [2,6), @retptr(arg0, [2,3)){{$}} 261; GLOBAL-NEXT: safe accesses: 262; CHECK-EMPTY: 263entry: 264 %x = alloca i32, align 4 265 %x1 = bitcast i32* %x to i8* 266 %x2 = getelementptr i8, i8* %x1, i64 2 267 %x3 = call i8* @retptr(i8* %x2) 268 %x4 = bitcast i8* %x3 to i32* 269 store i32 0, i32* %x4, align 1 270 ret void 271} 272 273; There is no difference in load vs store handling. 274define void @LoadInBounds() { 275; CHECK-LABEL: @LoadInBounds dso_preemptable{{$}} 276; CHECK-NEXT: args uses: 277; CHECK-NEXT: allocas uses: 278; CHECK-NEXT: x[4]: [0,1){{$}} 279; GLOBAL-NEXT: safe accesses: 280; GLOBAL-NEXT: %v = load i8, i8* %x1, align 1 281; CHECK-EMPTY: 282entry: 283 %x = alloca i32, align 4 284 %x1 = bitcast i32* %x to i8* 285 %v = load i8, i8* %x1, align 1 286 ret void 287} 288 289define void @LoadOutOfBounds() { 290; CHECK-LABEL: @LoadOutOfBounds dso_preemptable{{$}} 291; CHECK-NEXT: args uses: 292; CHECK-NEXT: allocas uses: 293; CHECK-NEXT: x[4]: [2,6){{$}} 294; GLOBAL-NEXT: safe accesses: 295; CHECK-EMPTY: 296entry: 297 %x = alloca i32, align 4 298 %x1 = bitcast i32* %x to i8* 299 %x2 = getelementptr i8, i8* %x1, i64 2 300 %x3 = bitcast i8* %x2 to i32* 301 %v = load i32, i32* %x3, align 1 302 ret void 303} 304 305; Leak through ret. 306define i8* @Ret() { 307; CHECK-LABEL: @Ret dso_preemptable{{$}} 308; CHECK-NEXT: args uses: 309; CHECK-NEXT: allocas uses: 310; CHECK-NEXT: x[4]: full-set{{$}} 311; GLOBAL-NEXT: safe accesses: 312; CHECK-EMPTY: 313entry: 314 %x = alloca i32, align 4 315 %x1 = bitcast i32* %x to i8* 316 %x2 = getelementptr i8, i8* %x1, i64 2 317 ret i8* %x2 318} 319 320declare void @Foo(i16* %p) 321 322define void @DirectCall() { 323; CHECK-LABEL: @DirectCall dso_preemptable{{$}} 324; CHECK-NEXT: args uses: 325; CHECK-NEXT: allocas uses: 326; LOCAL-NEXT: x[8]: empty-set, @Foo(arg0, [2,3)){{$}} 327; GLOBAL-NEXT: x[8]: full-set, @Foo(arg0, [2,3)){{$}} 328; GLOBAL-NEXT: safe accesses: 329; CHECK-EMPTY: 330entry: 331 %x = alloca i64, align 4 332 %x1 = bitcast i64* %x to i16* 333 %x2 = getelementptr i16, i16* %x1, i64 1 334 call void @Foo(i16* %x2); 335 ret void 336} 337 338; Indirect calls can not be analyzed (yet). 339; FIXME: %p[]: full-set looks invalid 340define void @IndirectCall(void (i8*)* %p) { 341; CHECK-LABEL: @IndirectCall dso_preemptable{{$}} 342; CHECK-NEXT: args uses: 343; CHECK-NEXT: p[]: full-set{{$}} 344; CHECK-NEXT: allocas uses: 345; CHECK-NEXT: x[4]: full-set{{$}} 346; GLOBAL-NEXT: safe accesses: 347; CHECK-EMPTY: 348entry: 349 %x = alloca i32, align 4 350 %x1 = bitcast i32* %x to i8* 351 call void %p(i8* %x1); 352 ret void 353} 354 355define void @NonConstantOffset(i1 zeroext %z) { 356; CHECK-LABEL: @NonConstantOffset dso_preemptable{{$}} 357; CHECK-NEXT: args uses: 358; CHECK-NEXT: allocas uses: 359; FIXME: SCEV can't look through selects. 360; CHECK-NEXT: x[4]: [0,4){{$}} 361; GLOBAL-NEXT: safe accesses: 362; GLOBAL-NEXT: store i8 0, i8* %x2, align 1 363; CHECK-EMPTY: 364entry: 365 %x = alloca i32, align 4 366 %x1 = bitcast i32* %x to i8* 367 %idx = select i1 %z, i64 1, i64 2 368 %x2 = getelementptr i8, i8* %x1, i64 %idx 369 store i8 0, i8* %x2, align 1 370 ret void 371} 372 373define void @NegativeOffset() { 374; CHECK-LABEL: @NegativeOffset dso_preemptable{{$}} 375; CHECK-NEXT: args uses: 376; CHECK-NEXT: allocas uses: 377; CHECK-NEXT: x[40]: [-1600000000000,-1599999999996){{$}} 378; GLOBAL-NEXT: safe accesses: 379; CHECK-EMPTY: 380entry: 381 %x = alloca i32, i32 10, align 4 382 %x2 = getelementptr i32, i32* %x, i64 -400000000000 383 store i32 0, i32* %x2, align 1 384 ret void 385} 386 387define void @PossiblyNegativeOffset(i16 %z) { 388; CHECK-LABEL: @PossiblyNegativeOffset dso_preemptable{{$}} 389; CHECK-NEXT: args uses: 390; CHECK-NEXT: allocas uses: 391; CHECK-NEXT: x[40]: [-131072,131072){{$}} 392; GLOBAL-NEXT: safe accesses: 393; CHECK-EMPTY: 394entry: 395 %x = alloca i32, i32 10, align 4 396 %x2 = getelementptr i32, i32* %x, i16 %z 397 store i32 0, i32* %x2, align 1 398 ret void 399} 400 401define void @NonConstantOffsetOOB(i1 zeroext %z) { 402; CHECK-LABEL: @NonConstantOffsetOOB dso_preemptable{{$}} 403; CHECK-NEXT: args uses: 404; CHECK-NEXT: allocas uses: 405; CHECK-NEXT: x[4]: [0,6){{$}} 406; GLOBAL-NEXT: safe accesses: 407; CHECK-EMPTY: 408entry: 409 %x = alloca i32, align 4 410 %x1 = bitcast i32* %x to i8* 411 %idx = select i1 %z, i64 1, i64 4 412 %x2 = getelementptr i8, i8* %x1, i64 %idx 413 store i8 0, i8* %x2, align 1 414 ret void 415} 416 417define void @ArrayAlloca() { 418; CHECK-LABEL: @ArrayAlloca dso_preemptable{{$}} 419; CHECK-NEXT: args uses: 420; CHECK-NEXT: allocas uses: 421; CHECK-NEXT: x[40]: [36,40){{$}} 422; GLOBAL-NEXT: safe accesses: 423; GLOBAL-NEXT: store i32 0, i32* %x3, align 1 424; CHECK-EMPTY: 425entry: 426 %x = alloca i32, i32 10, align 4 427 %x1 = bitcast i32* %x to i8* 428 %x2 = getelementptr i8, i8* %x1, i64 36 429 %x3 = bitcast i8* %x2 to i32* 430 store i32 0, i32* %x3, align 1 431 ret void 432} 433 434define void @ArrayAllocaOOB() { 435; CHECK-LABEL: @ArrayAllocaOOB dso_preemptable{{$}} 436; CHECK-NEXT: args uses: 437; CHECK-NEXT: allocas uses: 438; CHECK-NEXT: x[40]: [37,41){{$}} 439; GLOBAL-NEXT: safe accesses: 440; CHECK-EMPTY: 441entry: 442 %x = alloca i32, i32 10, align 4 443 %x1 = bitcast i32* %x to i8* 444 %x2 = getelementptr i8, i8* %x1, i64 37 445 %x3 = bitcast i8* %x2 to i32* 446 store i32 0, i32* %x3, align 1 447 ret void 448} 449 450define void @DynamicAllocaUnused(i64 %size) { 451; CHECK-LABEL: @DynamicAllocaUnused dso_preemptable{{$}} 452; CHECK-NEXT: args uses: 453; CHECK-NEXT: allocas uses: 454; CHECK-NEXT: x[0]: empty-set{{$}} 455; GLOBAL-NEXT: safe accesses: 456; CHECK-EMPTY: 457entry: 458 %x = alloca i32, i64 %size, align 16 459 ret void 460} 461 462; Dynamic alloca with unknown size. 463define void @DynamicAlloca(i64 %size) { 464; CHECK-LABEL: @DynamicAlloca dso_preemptable{{$}} 465; CHECK-NEXT: args uses: 466; CHECK-NEXT: allocas uses: 467; CHECK-NEXT: x[0]: [0,4){{$}} 468; GLOBAL-NEXT: safe accesses: 469; CHECK-EMPTY: 470entry: 471 %x = alloca i32, i64 %size, align 16 472 store i32 0, i32* %x, align 1 473 ret void 474} 475 476; Dynamic alloca with limited size. 477; FIXME: could be proved safe. Implement. 478define void @DynamicAllocaFiniteSizeRange(i1 zeroext %z) { 479; CHECK-LABEL: @DynamicAllocaFiniteSizeRange dso_preemptable{{$}} 480; CHECK-NEXT: args uses: 481; CHECK-NEXT: allocas uses: 482; CHECK-NEXT: x[0]: [0,4){{$}} 483; GLOBAL-NEXT: safe accesses: 484; CHECK-EMPTY: 485entry: 486 %size = select i1 %z, i64 3, i64 5 487 %x = alloca i32, i64 %size, align 16 488 store i32 0, i32* %x, align 1 489 ret void 490} 491 492define signext i8 @SimpleLoop() { 493; CHECK-LABEL: @SimpleLoop dso_preemptable{{$}} 494; CHECK-NEXT: args uses: 495; CHECK-NEXT: allocas uses: 496; CHECK-NEXT: x[10]: [0,10){{$}} 497; GLOBAL-NEXT: safe accesses: 498; GLOBAL-NEXT: %1 = load volatile i8, i8* %p.09, align 1 499; CHECK-EMPTY: 500entry: 501 %x = alloca [10 x i8], align 1 502 %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0 503 %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 10 504 br label %for.body 505 506for.body: 507 %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ] 508 %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ] 509 %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1 510 %1 = load volatile i8, i8* %p.09, align 1 511 %add = add i8 %1, %sum.010 512 %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit 513 br i1 %exitcond, label %for.cond.cleanup, label %for.body 514 515for.cond.cleanup: 516 ret i8 %add 517} 518 519; OOB in a loop. 520define signext i8 @SimpleLoopOOB() { 521; CHECK-LABEL: @SimpleLoopOOB dso_preemptable{{$}} 522; CHECK-NEXT: args uses: 523; CHECK-NEXT: allocas uses: 524; CHECK-NEXT: x[10]: [0,11){{$}} 525; GLOBAL-NEXT: safe accesses: 526; CHECK-EMPTY: 527entry: 528 %x = alloca [10 x i8], align 1 529 %0 = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 0 530 ; 11 iterations 531 %lftr.limit = getelementptr inbounds [10 x i8], [10 x i8]* %x, i64 0, i64 11 532 br label %for.body 533 534for.body: 535 %sum.010 = phi i8 [ 0, %entry ], [ %add, %for.body ] 536 %p.09 = phi i8* [ %0, %entry ], [ %incdec.ptr, %for.body ] 537 %incdec.ptr = getelementptr inbounds i8, i8* %p.09, i64 1 538 %1 = load volatile i8, i8* %p.09, align 1 539 %add = add i8 %1, %sum.010 540 %exitcond = icmp eq i8* %incdec.ptr, %lftr.limit 541 br i1 %exitcond, label %for.cond.cleanup, label %for.body 542 543for.cond.cleanup: 544 ret i8 %add 545} 546 547define dso_local void @SizeCheck(i32 %sz) { 548; CHECK-LABEL: @SizeCheck{{$}} 549; CHECK-NEXT: args uses: 550; CHECK-NEXT: allocas uses: 551; CHECK-NEXT: x1[128]: [0,4294967295){{$}} 552; GLOBAL-NEXT: safe accesses: 553; CHECK-EMPTY: 554entry: 555 %x1 = alloca [128 x i8], align 16 556 %x1.sub = getelementptr inbounds [128 x i8], [128 x i8]* %x1, i64 0, i64 0 557 %cmp = icmp slt i32 %sz, 129 558 br i1 %cmp, label %if.then, label %if.end 559 560if.then: 561 call void @llvm.memset.p0i8.i32(i8* nonnull align 16 %x1.sub, i8 0, i32 %sz, i1 false) 562 br label %if.end 563 564if.end: 565 ret void 566} 567 568; FIXME: scalable allocas are considered to be of size zero, and scalable accesses to be full-range. 569; This effectively disables safety analysis for scalable allocations. 570define void @Scalable(<vscale x 4 x i32>* %p, <vscale x 4 x i32>* %unused, <vscale x 4 x i32> %v) { 571; CHECK-LABEL: @Scalable dso_preemptable{{$}} 572; CHECK-NEXT: args uses: 573; CHECK-NEXT: p[]: full-set 574; CHECK-NEXT: unused[]: empty-set 575; CHECK-NEXT: allocas uses: 576; CHECK-NEXT: x[0]: [0,1){{$}} 577; GLOBAL-NEXT: safe accesses: 578; GLOBAL-NEXT: store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4 579; CHECK-EMPTY: 580entry: 581 %x = alloca <vscale x 4 x i32>, align 4 582 %x1 = bitcast <vscale x 4 x i32>* %x to i8* 583 store i8 0, i8* %x1, align 1 584 store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4 585 ret void 586} 587 588%zerosize_type = type {} 589 590define void @ZeroSize(%zerosize_type *%p) { 591; CHECK-LABEL: @ZeroSize dso_preemptable{{$}} 592; CHECK-NEXT: args uses: 593; CHECK-NEXT: p[]: empty-set 594; CHECK-NEXT: allocas uses: 595; CHECK-NEXT: x[0]: empty-set 596; GLOBAL-NEXT: safe accesses: 597; GLOBAL-NEXT: store %zerosize_type undef, %zerosize_type* %x, align 4 598; GLOBAL-NEXT: store %zerosize_type undef, %zerosize_type* undef, align 4 599; GLOBAL-NEXT: load %zerosize_type, %zerosize_type* %p, align 600; CHECK-EMPTY: 601entry: 602 %x = alloca %zerosize_type, align 4 603 store %zerosize_type undef, %zerosize_type* %x, align 4 604 store %zerosize_type undef, %zerosize_type* undef, align 4 605 %val = load %zerosize_type, %zerosize_type* %p, align 4 606 ret void 607} 608 609define void @OperandBundle() { 610; CHECK-LABEL: @OperandBundle dso_preemptable{{$}} 611; CHECK-NEXT: args uses: 612; CHECK-NEXT: allocas uses: 613; CHECK-NEXT: a[4]: full-set 614; GLOBAL-NEXT: safe accesses: 615; CHECK-EMPTY: 616entry: 617 %a = alloca i32, align 4 618 call void @LeakAddress() ["unknown"(i32* %a)] 619 ret void 620} 621 622define void @ByVal(i16* byval(i16) %p) { 623 ; CHECK-LABEL: @ByVal dso_preemptable{{$}} 624 ; CHECK-NEXT: args uses: 625 ; CHECK-NEXT: allocas uses: 626 ; GLOBAL-NEXT: safe accesses: 627 ; CHECK-EMPTY: 628entry: 629 ret void 630} 631 632define void @TestByVal() { 633; CHECK-LABEL: @TestByVal dso_preemptable{{$}} 634; CHECK-NEXT: args uses: 635; CHECK-NEXT: allocas uses: 636; CHECK-NEXT: x[2]: [0,2) 637; CHECK-NEXT: y[8]: [0,2) 638; GLOBAL-NEXT: safe accesses: 639; GLOBAL-NEXT: call void @ByVal(i16* byval(i16) %x) 640; GLOBAL-NEXT: call void @ByVal(i16* byval(i16) %y1) 641; CHECK-EMPTY: 642entry: 643 %x = alloca i16, align 4 644 call void @ByVal(i16* byval(i16) %x) 645 646 %y = alloca i64, align 4 647 %y1 = bitcast i64* %y to i16* 648 call void @ByVal(i16* byval(i16) %y1) 649 650 ret void 651} 652 653declare void @ByValArray([100000 x i64]* byval([100000 x i64]) %p) 654 655define void @TestByValArray() { 656; CHECK-LABEL: @TestByValArray dso_preemptable{{$}} 657; CHECK-NEXT: args uses: 658; CHECK-NEXT: allocas uses: 659; CHECK-NEXT: z[800000]: [500000,1300000) 660; GLOBAL-NEXT: safe accesses: 661; CHECK-EMPTY: 662entry: 663 %z = alloca [100000 x i64], align 4 664 %z1 = bitcast [100000 x i64]* %z to i8* 665 %z2 = getelementptr i8, i8* %z1, i64 500000 666 %z3 = bitcast i8* %z2 to [100000 x i64]* 667 call void @ByValArray([100000 x i64]* byval([100000 x i64]) %z3) 668 ret void 669} 670 671define dso_local i8 @LoadMinInt64(i8* %p) { 672 ; CHECK-LABEL: @LoadMinInt64{{$}} 673 ; CHECK-NEXT: args uses: 674 ; CHECK-NEXT: p[]: [-9223372036854775808,-9223372036854775807){{$}} 675 ; CHECK-NEXT: allocas uses: 676 ; GLOBAL-NEXT: safe accesses: 677 ; GLOBAL-NEXT: load i8, i8* %p2, align 1 678 ; CHECK-EMPTY: 679 %p2 = getelementptr i8, i8* %p, i64 -9223372036854775808 680 %v = load i8, i8* %p2, align 1 681 ret i8 %v 682} 683 684define void @Overflow() { 685; CHECK-LABEL: @Overflow dso_preemptable{{$}} 686; CHECK-NEXT: args uses: 687; CHECK-NEXT: allocas uses: 688; LOCAL-NEXT: x[1]: empty-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}} 689; GLOBAL-NEXT: x[1]: full-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}} 690; GLOBAL-NEXT: safe accesses: 691; CHECK-EMPTY: 692entry: 693 %x = alloca i8, align 4 694 %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808 695 %v = call i8 @LoadMinInt64(i8* %x2) 696 ret void 697} 698 699define void @DeadBlock(i64* %p) { 700; CHECK-LABEL: @DeadBlock dso_preemptable{{$}} 701; CHECK-NEXT: args uses: 702; CHECK-NEXT: p[]: empty-set{{$}} 703; CHECK-NEXT: allocas uses: 704; CHECK-NEXT: x[1]: empty-set{{$}} 705; GLOBAL-NEXT: safe accesses: 706; GLOBAL-NEXT: store i8 5, i8* %x 707; GLOBAL-NEXT: store i64 -5, i64* %p 708; CHECK-EMPTY: 709entry: 710 %x = alloca i8, align 4 711 br label %end 712 713dead: 714 store i8 5, i8* %x 715 store i64 -5, i64* %p 716 br label %end 717 718end: 719 ret void 720} 721 722define void @LifeNotStarted() { 723; CHECK-LABEL: @LifeNotStarted dso_preemptable{{$}} 724; CHECK-NEXT: args uses: 725; CHECK-NEXT: allocas uses: 726; CHECK: x[1]: full-set{{$}} 727; CHECK: y[1]: full-set{{$}} 728; CHECK: z[1]: full-set{{$}} 729; GLOBAL-NEXT: safe accesses: 730; CHECK-EMPTY: 731entry: 732 %x = alloca i8, align 4 733 %y = alloca i8, align 4 734 %z = alloca i8, align 4 735 736 store i8 5, i8* %x 737 %n = load i8, i8* %y 738 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 739 740 call void @llvm.lifetime.start.p0i8(i64 1, i8* %x) 741 call void @llvm.lifetime.start.p0i8(i64 1, i8* %y) 742 call void @llvm.lifetime.start.p0i8(i64 1, i8* %z) 743 744 ret void 745} 746 747define void @LifeOK() { 748; CHECK-LABEL: @LifeOK dso_preemptable{{$}} 749; CHECK-NEXT: args uses: 750; CHECK-NEXT: allocas uses: 751; CHECK: x[1]: [0,1){{$}} 752; CHECK: y[1]: [0,1){{$}} 753; CHECK: z[1]: [0,1){{$}} 754; GLOBAL-NEXT: safe accesses: 755; GLOBAL-NEXT: store i8 5, i8* %x 756; GLOBAL-NEXT: %n = load i8, i8* %y 757; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 758; CHECK-EMPTY: 759entry: 760 %x = alloca i8, align 4 761 %y = alloca i8, align 4 762 %z = alloca i8, align 4 763 764 call void @llvm.lifetime.start.p0i8(i64 1, i8* %x) 765 call void @llvm.lifetime.start.p0i8(i64 1, i8* %y) 766 call void @llvm.lifetime.start.p0i8(i64 1, i8* %z) 767 768 store i8 5, i8* %x 769 %n = load i8, i8* %y 770 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 771 772 ret void 773} 774 775define void @LifeEnded() { 776; CHECK-LABEL: @LifeEnded dso_preemptable{{$}} 777; CHECK-NEXT: args uses: 778; CHECK-NEXT: allocas uses: 779; CHECK: x[1]: full-set{{$}} 780; CHECK: y[1]: full-set{{$}} 781; CHECK: z[1]: full-set{{$}} 782; GLOBAL-NEXT: safe accesses: 783; CHECK-EMPTY: 784entry: 785 %x = alloca i8, align 4 786 %y = alloca i8, align 4 787 %z = alloca i8, align 4 788 789 call void @llvm.lifetime.start.p0i8(i64 1, i8* %x) 790 call void @llvm.lifetime.start.p0i8(i64 1, i8* %y) 791 call void @llvm.lifetime.start.p0i8(i64 1, i8* %z) 792 793 call void @llvm.lifetime.end.p0i8(i64 1, i8* %x) 794 call void @llvm.lifetime.end.p0i8(i64 1, i8* %y) 795 call void @llvm.lifetime.end.p0i8(i64 1, i8* %z) 796 797 store i8 5, i8* %x 798 %n = load i8, i8* %y 799 call void @llvm.memset.p0i8.i32(i8* nonnull %z, i8 0, i32 1, i1 false) 800 801 ret void 802} 803 804define void @TwoAllocasOK() { 805; CHECK-LABEL: @TwoAllocasOK 806; CHECK-NEXT: args uses: 807; CHECK-NEXT: allocas uses: 808; CHECK: a[4]: [0,1){{$}} 809; CHECK: y[1]: [0,1){{$}} 810; GLOBAL-NEXT: safe accesses: 811; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 1, i1 false) 812; CHECK-EMPTY: 813entry: 814 %a = alloca i32, align 4 815 %x = bitcast i32* %a to i8* 816 %y = alloca i8, align 4 817 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 1, i1 false) 818 ret void 819} 820 821define void @TwoAllocasOOBDest() { 822; CHECK-LABEL: @TwoAllocasOOBDest 823; CHECK-NEXT: args uses: 824; CHECK-NEXT: allocas uses: 825; CHECK: a[4]: [0,4){{$}} 826; CHECK: y[1]: [0,4){{$}} 827; GLOBAL-NEXT: safe accesses: 828; CHECK-EMPTY: 829entry: 830 %a = alloca i32, align 4 831 %x = bitcast i32* %a to i8* 832 %y = alloca i8, align 4 833 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 4, i1 false) 834 ret void 835} 836 837define void @TwoAllocasOOBSource() { 838; CHECK-LABEL: @TwoAllocasOOBSource 839; CHECK-NEXT: args uses: 840; CHECK-NEXT: allocas uses: 841; CHECK: a[4]: [0,4){{$}} 842; CHECK: y[1]: [0,4){{$}} 843; GLOBAL-NEXT: safe accesses: 844; CHECK-EMPTY: 845entry: 846 %a = alloca i32, align 4 847 %x = bitcast i32* %a to i8* 848 %y = alloca i8, align 4 849 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %y, i32 4, i1 false) 850 ret void 851} 852 853define void @TwoAllocasOOBBoth() { 854; CHECK-LABEL: @TwoAllocasOOBBoth 855; CHECK-NEXT: args uses: 856; CHECK-NEXT: allocas uses: 857; CHECK: a[4]: [0,5){{$}} 858; CHECK: y[1]: [0,5){{$}} 859; GLOBAL-NEXT: safe accesses: 860; CHECK-EMPTY: 861entry: 862 %a = alloca i32, align 4 863 %x = bitcast i32* %a to i8* 864 %y = alloca i8, align 4 865 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %y, i8* %x, i32 5, i1 false) 866 ret void 867} 868 869define void @MixedAccesses() { 870; CHECK-LABEL: @MixedAccesses 871; CHECK-NEXT: args uses: 872; CHECK-NEXT: allocas uses: 873; CHECK: a[4]: [0,5){{$}} 874; GLOBAL-NEXT: safe accesses: 875; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 876; CHECK-EMPTY: 877entry: 878 %a = alloca i32, align 4 879 %x = bitcast i32* %a to i8* 880 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 5, i1 false) 881 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 882 ret void 883} 884 885define void @MixedAccesses2() { 886; CHECK-LABEL: @MixedAccesses2 887; CHECK-NEXT: args uses: 888; CHECK-NEXT: allocas uses: 889; CHECK: a[4]: [0,8){{$}} 890; GLOBAL-NEXT: safe accesses: 891; GLOBAL-NEXT: load i32, i32* %a, align 4 892; CHECK-EMPTY: 893entry: 894 %a = alloca i32, align 4 895 %a1 = bitcast i32* %a to i64* 896 %n1 = load i64, i64* %a1, align 4 897 %n2 = load i32, i32* %a, align 4 898 ret void 899} 900 901define void @MixedAccesses3(void (i8*)* %func) { 902; CHECK-LABEL: @MixedAccesses3 903; CHECK-NEXT: args uses: 904; CHECK-NEXT: func[]: full-set 905; CHECK-NEXT: allocas uses: 906; CHECK: a[4]: full-set{{$}} 907; GLOBAL-NEXT: safe accesses: 908; GLOBAL-NEXT: load i32, i32* %a, align 4 909; CHECK-EMPTY: 910entry: 911 %a = alloca i32, align 4 912 %x = bitcast i32* %a to i8* 913 %n2 = load i32, i32* %a, align 4 914 call void %func(i8* %x) 915 ret void 916} 917 918define void @MixedAccesses4() { 919; CHECK-LABEL: @MixedAccesses4 920; CHECK-NEXT: args uses: 921; CHECK-NEXT: allocas uses: 922; CHECK: a[4]: full-set{{$}} 923; CHECK: a1[8]: [0,8){{$}} 924; GLOBAL-NEXT: safe accesses: 925; GLOBAL-NEXT: load i32, i32* %a, align 4 926; CHECK-EMPTY: 927entry: 928 %a = alloca i32, align 4 929 %a1 = alloca i32*, align 4 930 %n2 = load i32, i32* %a, align 4 931 store i32* %a, i32** %a1 932 ret void 933} 934 935define i32* @MixedAccesses5(i1 %x, i32* %y) { 936; CHECK-LABEL: @MixedAccesses5 937; CHECK-NEXT: args uses: 938; CHECK: y[]: full-set 939; CHECK-NEXT: allocas uses: 940; CHECK: a[4]: full-set{{$}} 941; GLOBAL-NEXT: safe accesses: 942; GLOBAL-NEXT: load i32, i32* %a, align 4 943; CHECK-EMPTY: 944entry: 945 %a = alloca i32, align 4 946 br i1 %x, label %tlabel, label %flabel 947flabel: 948 %n = load i32, i32* %a, align 4 949 ret i32* %y 950tlabel: 951 ret i32* %a 952} 953 954define void @MixedAccesses6(i8* %arg) { 955; CHECK-LABEL: @MixedAccesses6 956; CHECK-NEXT: args uses: 957; CHECK-NEXT: arg[]: [0,4) 958; CHECK-NEXT: allocas uses: 959; CHECK: a[4]: [0,4) 960; GLOBAL-NEXT: safe accesses: 961; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %arg, i32 4, i1 false) 962; CHECK-EMPTY: 963entry: 964 %a = alloca i32, align 4 965 %x = bitcast i32* %a to i8* 966 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x, i8* %arg, i32 4, i1 false) 967 ret void 968} 969 970define void @MixedAccesses7(i1 %cond, i8* %arg) { 971; SECV doesn't support select, so we consider this non-stack-safe, even through 972; it is. 973; 974; CHECK-LABEL: @MixedAccesses7 975; CHECK-NEXT: args uses: 976; CHECK-NEXT: arg[]: full-set 977; CHECK-NEXT: allocas uses: 978; CHECK: a[4]: full-set 979; GLOBAL-NEXT: safe accesses: 980; CHECK-EMPTY: 981entry: 982 %a = alloca i32, align 4 983 %x = bitcast i32* %a to i8* 984 %x1 = select i1 %cond, i8* %arg, i8* %x 985 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %arg, i32 4, i1 false) 986 ret void 987} 988 989define void @NoStackAccess(i8* %arg1, i8* %arg2) { 990; CHECK-LABEL: @NoStackAccess 991; CHECK-NEXT: args uses: 992; CHECK-NEXT: arg1[]: [0,4) 993; CHECK-NEXT: arg2[]: [0,4) 994; CHECK-NEXT: allocas uses: 995; CHECK: a[4]: empty-set{{$}} 996; GLOBAL-NEXT: safe accesses: 997; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %arg1, i8* %arg2, i32 4, i1 false) 998; CHECK-EMPTY: 999entry: 1000 %a = alloca i32, align 4 1001 %x = bitcast i32* %a to i8* 1002 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %arg1, i8* %arg2, i32 4, i1 false) 1003 ret void 1004} 1005 1006define void @DoubleLifetime() { 1007; CHECK-LABEL: @DoubleLifetime 1008; CHECK-NEXT: args uses: 1009; CHECK-NEXT: allocas uses: 1010; CHECK: a[4]: full-set{{$}} 1011; GLOBAL-NEXT: safe accesses: 1012; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1013; CHECK-EMPTY: 1014entry: 1015 %a = alloca i32, align 4 1016 %x = bitcast i32* %a to i8* 1017 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1018 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1019 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 true) 1020 1021 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1022 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1023 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1024 ret void 1025} 1026 1027define void @DoubleLifetime2() { 1028; CHECK-LABEL: @DoubleLifetime2 1029; CHECK-NEXT: args uses: 1030; CHECK-NEXT: allocas uses: 1031; CHECK: a[4]: full-set{{$}} 1032; GLOBAL-NEXT: safe accesses: 1033; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1034; CHECK-EMPTY: 1035entry: 1036 %a = alloca i32, align 4 1037 %x = bitcast i32* %a to i8* 1038 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1039 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1040 %n = load i32, i32* %a 1041 1042 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1043 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1044 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1045 ret void 1046} 1047 1048define void @DoubleLifetime3() { 1049; CHECK-LABEL: @DoubleLifetime3 1050; CHECK-NEXT: args uses: 1051; CHECK-NEXT: allocas uses: 1052; CHECK: a[4]: full-set{{$}} 1053; GLOBAL-NEXT: safe accesses: 1054; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1055; CHECK-EMPTY: 1056entry: 1057 %a = alloca i32, align 4 1058 %x = bitcast i32* %a to i8* 1059 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1060 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1061 store i32 5, i32* %a 1062 1063 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1064 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1065 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1066 ret void 1067} 1068 1069define void @DoubleLifetime4() { 1070; CHECK-LABEL: @DoubleLifetime4 1071; CHECK-NEXT: args uses: 1072; CHECK-NEXT: allocas uses: 1073; CHECK: a[4]: full-set{{$}} 1074; GLOBAL-NEXT: safe accesses: 1075; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1076; CHECK-EMPTY: 1077entry: 1078 %a = alloca i32, align 4 1079 %x = bitcast i32* %a to i8* 1080 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) 1081 call void @llvm.memset.p0i8.i32(i8* %x, i8 1, i32 4, i1 false) 1082 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) 1083 call void @unknown_call(i8* %x) 1084 ret void 1085} 1086 1087declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) 1088declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) 1089