1; RUN: opt -safe-stack -safe-stack-coloring=1 -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s 2; RUN: opt -safe-stack -safe-stack-coloring=1 -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s 3 4; x and y share the stack slot. 5define void @f() safestack { 6; CHECK-LABEL: define void @f 7entry: 8; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 9; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 10 11 %x = alloca i32, align 4 12 %y = alloca i32, align 4 13 %z = alloca i32, align 4 14 %x0 = bitcast i32* %x to i8* 15 %y0 = bitcast i32* %y to i8* 16 %z0 = bitcast i32* %z to i8* 17 18 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %z0) 19 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 20 21; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 22 call void @capture32(i32* %x) 23 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 24 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 25 26; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 27 call void @capture32(i32* %y) 28 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0) 29 30; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 31 call void @capture32(i32* %z) 32 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %z0) 33 34 ret void 35} 36 37define void @no_markers() safestack { 38; CHECK-LABEL: define void @no_markers( 39entry: 40; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 41; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 42 43 %x = alloca i32, align 4 44 %y = alloca i32, align 4 45 %x0 = bitcast i32* %x to i8* 46 47 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 48 49; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 50 call void @capture32(i32* %x) 51 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 52 53; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 54 call void @capture32(i32* %y) 55 56 ret void 57} 58 59; x and y can't share memory, but they can split z's storage. 60define void @g() safestack { 61; CHECK-LABEL: define void @g 62entry: 63; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 64; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 65 66 %x = alloca i32, align 4 67 %y = alloca i32, align 4 68 %z = alloca i64, align 4 69 %x0 = bitcast i32* %x to i8* 70 %y0 = bitcast i32* %y to i8* 71 %z0 = bitcast i64* %z to i8* 72 73 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 74 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 75 76; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 77 call void @capture32(i32* %x) 78 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 79 80; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 81 call void @capture32(i32* %y) 82 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0) 83 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %z0) 84 85; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 86 call void @capture64(i64* %z) 87 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %z0) 88 89 ret void 90} 91 92; Both y and z fit in x's alignment gap. 93define void @h() safestack { 94; CHECK-LABEL: define void @h 95entry: 96; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 97; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 98 99 %x = alloca i32, align 16 100 %z = alloca i64, align 4 101 %y = alloca i32, align 4 102 %x0 = bitcast i32* %x to i8* 103 %y0 = bitcast i32* %y to i8* 104 %z0 = bitcast i64* %z to i8* 105 106 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 107 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 108 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %z0) 109 110; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 111 call void @capture32(i32* %x) 112 113; CHECK: getelementptr i8, i8* %[[USP]], i32 -12 114 call void @capture32(i32* %y) 115 116; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 117 call void @capture64(i64* %z) 118 119 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 120 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0) 121 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %z0) 122 123 ret void 124} 125 126; void f(bool a, bool b) { 127; long x1, x2; capture64(&x1); capture64(&x2); 128; if (a) { 129; long y; capture64(&y); 130; if (b) { 131; long y1; capture64(&y1); 132; } else { 133; long y2; capture64(&y2); 134; } 135; } else { 136; long z; capture64(&z); 137; if (b) { 138; long z1; capture64(&z1); 139; } else { 140; long z2; capture64(&z2); 141; } 142; } 143; } 144; Everything fits in 4 x 64-bit slots. 145define void @i(i1 zeroext %a, i1 zeroext %b) safestack { 146; CHECK-LABEL: define void @i 147entry: 148; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 149; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -32 150 %x1 = alloca i64, align 8 151 %x2 = alloca i64, align 8 152 %y = alloca i64, align 8 153 %y1 = alloca i64, align 8 154 %y2 = alloca i64, align 8 155 %z = alloca i64, align 8 156 %z1 = alloca i64, align 8 157 %z2 = alloca i64, align 8 158 %0 = bitcast i64* %x1 to i8* 159 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0) 160 %1 = bitcast i64* %x2 to i8* 161 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %1) 162; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 163; CHECK: call void @capture64( 164 call void @capture64(i64* nonnull %x1) 165; CHECK: getelementptr i8, i8* %[[USP]], i32 -16 166; CHECK: call void @capture64( 167 call void @capture64(i64* nonnull %x2) 168 br i1 %a, label %if.then, label %if.else4 169 170if.then: ; preds = %entry 171 %2 = bitcast i64* %y to i8* 172 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %2) 173; CHECK: getelementptr i8, i8* %[[USP]], i32 -24 174; CHECK: call void @capture64( 175 call void @capture64(i64* nonnull %y) 176 br i1 %b, label %if.then3, label %if.else 177 178if.then3: ; preds = %if.then 179 %3 = bitcast i64* %y1 to i8* 180 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %3) 181; CHECK: getelementptr i8, i8* %[[USP]], i32 -32 182; CHECK: call void @capture64( 183 call void @capture64(i64* nonnull %y1) 184 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %3) 185 br label %if.end 186 187if.else: ; preds = %if.then 188 %4 = bitcast i64* %y2 to i8* 189 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %4) 190; CHECK: getelementptr i8, i8* %[[USP]], i32 -32 191; CHECK: call void @capture64( 192 call void @capture64(i64* nonnull %y2) 193 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %4) 194 br label %if.end 195 196if.end: ; preds = %if.else, %if.then3 197 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %2) 198 br label %if.end9 199 200if.else4: ; preds = %entry 201 %5 = bitcast i64* %z to i8* 202 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %5) 203; CHECK: getelementptr i8, i8* %[[USP]], i32 -24 204; CHECK: call void @capture64( 205 call void @capture64(i64* nonnull %z) 206 br i1 %b, label %if.then6, label %if.else7 207 208if.then6: ; preds = %if.else4 209 %6 = bitcast i64* %z1 to i8* 210 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %6) 211; CHECK: getelementptr i8, i8* %[[USP]], i32 -32 212; CHECK: call void @capture64( 213 call void @capture64(i64* nonnull %z1) 214 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %6) 215 br label %if.end8 216 217if.else7: ; preds = %if.else4 218 %7 = bitcast i64* %z2 to i8* 219 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %7) 220; CHECK: getelementptr i8, i8* %[[USP]], i32 -32 221; CHECK: call void @capture64( 222 call void @capture64(i64* nonnull %z2) 223 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %7) 224 br label %if.end8 225 226if.end8: ; preds = %if.else7, %if.then6 227 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %5) 228 br label %if.end9 229 230if.end9: ; preds = %if.end8, %if.end 231 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %1) 232 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0) 233 ret void 234} 235 236; lifetime for x ends in 2 different BBs 237define void @no_merge1(i1 %d) safestack { 238; CHECK-LABEL: define void @no_merge1( 239entry: 240; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 241; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 242 %x = alloca i32, align 4 243 %y = alloca i32, align 4 244 %x0 = bitcast i32* %x to i8* 245 %y0 = bitcast i32* %y to i8* 246 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 247; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 248; CHECK: call void @capture32( 249 call void @capture32(i32* %x) 250 br i1 %d, label %bb2, label %bb3 251bb2: 252 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 253; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 254; CHECK: call void @capture32( 255 call void @capture32(i32* %y) 256 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0) 257 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 258 ret void 259bb3: 260 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 261 ret void 262} 263 264define void @merge1(i1 %d) safestack { 265; CHECK-LABEL: define void @merge1( 266entry: 267; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 268; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 269 %x = alloca i32, align 4 270 %y = alloca i32, align 4 271 %x0 = bitcast i32* %x to i8* 272 %y0 = bitcast i32* %y to i8* 273 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 274; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 275; CHECK: call void @capture32( 276 call void @capture32(i32* %x) 277 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 278 br i1 %d, label %bb2, label %bb3 279bb2: 280 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 281; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 282; CHECK: call void @capture32( 283 call void @capture32(i32* %y) 284 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %y0) 285 ret void 286bb3: 287 ret void 288} 289 290; Missing lifetime.end 291define void @merge2_noend(i1 %d) safestack { 292; CHECK-LABEL: define void @merge2_noend( 293entry: 294; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 295; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 296 %x = alloca i32, align 4 297 %y = alloca i32, align 4 298 %x0 = bitcast i32* %x to i8* 299 %y0 = bitcast i32* %y to i8* 300 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 301; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 302; CHECK: call void @capture32( 303 call void @capture32(i32* %x) 304 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 305 br i1 %d, label %bb2, label %bb3 306bb2: 307 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 308; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 309; CHECK: call void @capture32( 310 call void @capture32(i32* %y) 311 ret void 312bb3: 313 ret void 314} 315 316; Missing lifetime.end 317define void @merge3_noend(i1 %d) safestack { 318; CHECK-LABEL: define void @merge3_noend( 319entry: 320; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 321; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 322 %x = alloca i32, align 4 323 %y = alloca i32, align 4 324 %x0 = bitcast i32* %x to i8* 325 %y0 = bitcast i32* %y to i8* 326 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %x0) 327; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 328; CHECK: call void @capture32( 329 call void @capture32(i32* %x) 330 br i1 %d, label %bb2, label %bb3 331bb2: 332 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 333 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 334; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 335; CHECK: call void @capture32( 336 call void @capture32(i32* %y) 337 ret void 338bb3: 339 ret void 340} 341 342; Missing lifetime.start 343define void @nomerge4_nostart(i1 %d) safestack { 344; CHECK-LABEL: define void @nomerge4_nostart( 345entry: 346; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 347; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 348 %x = alloca i32, align 4 349 %y = alloca i32, align 4 350 %x0 = bitcast i32* %x to i8* 351 %y0 = bitcast i32* %y to i8* 352; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 353; CHECK: call void @capture32( 354 call void @capture32(i32* %x) 355 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %x0) 356 br i1 %d, label %bb2, label %bb3 357bb2: 358 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %y0) 359; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 360; CHECK: call void @capture32( 361 call void @capture32(i32* %y) 362 ret void 363bb3: 364 ret void 365} 366 367define void @array_merge() safestack { 368; CHECK-LABEL: define void @array_merge( 369entry: 370; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 371; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -800 372 %A.i1 = alloca [100 x i32], align 4 373 %B.i2 = alloca [100 x i32], align 4 374 %A.i = alloca [100 x i32], align 4 375 %B.i = alloca [100 x i32], align 4 376 %0 = bitcast [100 x i32]* %A.i to i8* 377 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0) 378 %1 = bitcast [100 x i32]* %B.i to i8* 379 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %1) 380; CHECK: getelementptr i8, i8* %[[USP]], i32 -400 381; CHECK: call void @capture100x32( 382 call void @capture100x32([100 x i32]* %A.i) 383; CHECK: getelementptr i8, i8* %[[USP]], i32 -800 384; CHECK: call void @capture100x32( 385 call void @capture100x32([100 x i32]* %B.i) 386 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0) 387 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %1) 388 %2 = bitcast [100 x i32]* %A.i1 to i8* 389 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %2) 390 %3 = bitcast [100 x i32]* %B.i2 to i8* 391 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %3) 392; CHECK: getelementptr i8, i8* %[[USP]], i32 -400 393; CHECK: call void @capture100x32( 394 call void @capture100x32([100 x i32]* %A.i1) 395; CHECK: getelementptr i8, i8* %[[USP]], i32 -800 396; CHECK: call void @capture100x32( 397 call void @capture100x32([100 x i32]* %B.i2) 398 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %2) 399 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %3) 400 ret void 401} 402 403define void @myCall_pr15707() safestack { 404; CHECK-LABEL: define void @myCall_pr15707( 405entry: 406; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 407; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -200000 408 %buf1 = alloca i8, i32 100000, align 16 409 %buf2 = alloca i8, i32 100000, align 16 410 411 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %buf1) 412 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %buf1) 413 414 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %buf1) 415 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %buf2) 416 call void @capture8(i8* %buf1) 417 call void @capture8(i8* %buf2) 418 ret void 419} 420 421; Check that we don't assert and crash even when there are allocas 422; outside the declared lifetime regions. 423define void @bad_range() safestack { 424; CHECK-LABEL: define void @bad_range( 425entry: 426; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 427; A.i and B.i unsafe, not merged 428; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -800 429; A.i1 and B.i2 safe 430; CHECK: = alloca [100 x i32], align 4 431; CHECK: = alloca [100 x i32], align 4 432 433 %A.i1 = alloca [100 x i32], align 4 434 %B.i2 = alloca [100 x i32], align 4 435 %A.i = alloca [100 x i32], align 4 436 %B.i = alloca [100 x i32], align 4 437 %0 = bitcast [100 x i32]* %A.i to i8* 438 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0) nounwind 439 %1 = bitcast [100 x i32]* %B.i to i8* 440 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %1) nounwind 441 call void @capture100x32([100 x i32]* %A.i) 442 call void @capture100x32([100 x i32]* %B.i) 443 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0) nounwind 444 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %1) nounwind 445 br label %block2 446 447block2: 448 ; I am used outside the marked lifetime. 449 call void @capture100x32([100 x i32]* %A.i) 450 call void @capture100x32([100 x i32]* %B.i) 451 ret void 452} 453 454%struct.Klass = type { i32, i32 } 455 456define i32 @shady_range(i32 %argc, i8** nocapture %argv) safestack { 457; CHECK-LABEL: define i32 @shady_range( 458entry: 459; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 460; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -64 461 %a.i = alloca [4 x %struct.Klass], align 16 462 %b.i = alloca [4 x %struct.Klass], align 16 463 %a8 = bitcast [4 x %struct.Klass]* %a.i to i8* 464 %b8 = bitcast [4 x %struct.Klass]* %b.i to i8* 465 ; I am used outside the lifetime zone below: 466 %z2 = getelementptr inbounds [4 x %struct.Klass], [4 x %struct.Klass]* %a.i, i64 0, i64 0, i32 0 467 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %a8) 468 call void @llvm.lifetime.start.p0i8(i64 -1, i8* %b8) 469 call void @capture8(i8* %a8) 470 call void @capture8(i8* %b8) 471 %z3 = load i32, i32* %z2, align 16 472 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %a8) 473 call void @llvm.lifetime.end.p0i8(i64 -1, i8* %b8) 474 ret i32 %z3 475} 476 477define void @end_loop() safestack { 478; CHECK-LABEL: define void @end_loop() 479entry: 480; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 481; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 482 %x = alloca i8, align 4 483 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) nounwind 484 br label %l2 485 486l2: 487 call void @capture8(i8* %x) 488 call void @llvm.lifetime.end.p0i8(i64 4, i8* %x) nounwind 489 br label %l2 490} 491 492; Check that @x and @y get distinct stack slots => @x lifetime does not break 493; when control re-enters l2. 494define void @start_loop() safestack { 495; CHECK-LABEL: define void @start_loop() 496entry: 497; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 498; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -16 499 %x = alloca i8, align 4 500 %y = alloca i8, align 4 501 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) nounwind 502 br label %l2 503 504l2: 505; CHECK: getelementptr i8, i8* %[[USP]], i32 -8 506 call void @llvm.lifetime.start.p0i8(i64 4, i8* %y) nounwind 507 call void @capture8(i8* %y) 508 call void @llvm.lifetime.end.p0i8(i64 4, i8* %y) nounwind 509 510; CHECK: getelementptr i8, i8* %[[USP]], i32 -4 511 call void @llvm.lifetime.start.p0i8(i64 4, i8* %x) nounwind 512 call void @capture8(i8* %x) 513 br label %l2 514} 515 516; This test checks for a bug where the stack coloring algorithm was not tracking 517; the live range of allocas through phi instructions, so it did not consider 518; alloca and alloca2 to be live at the same time. As a result it was using 519; the same stack slot for both allocas. To ensure this bug isn't present, we 520; check that there are 64 bytes allocated for the unsafe stack which is enough 521; space for both allocas. 522; CHECK-LABEL: @stack_coloring_liveness_bug 523define void @stack_coloring_liveness_bug(i32 %arg0) #0 { 524entry: 525; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr 526; CHECK-NEXT: getelementptr i8, i8* %[[USP]], i32 -64 527 %alloca = alloca [32 x i8], align 16 528 %alloca2 = alloca [32 x i8], align 16 529 %cond = icmp eq i32 %arg0, 0 530 br i1 %cond, label %if, label %else 531 532if: 533 %alloca.if = bitcast [32 x i8]* %alloca to i8* 534 br label %end 535 536else: 537; CHECK: getelementptr i8, i8* %[[USP]], i32 -32 538 %alloca.else = bitcast [32 x i8]* %alloca to i8* 539 call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %alloca.else) 540 call void @capture8(i8* %alloca.else) 541 call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %alloca.else) 542 br label %end 543 544end: 545; CHECK: getelementptr i8, i8* %[[USP]], i32 -64 546 %alloca.end = phi i8* [ %alloca.if, %if], [%alloca.else, %else] 547 %alloca2.bitcast = bitcast [32 x i8]* %alloca2 to i8* 548 call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %alloca2.bitcast) 549 call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %alloca.end) 550 call void @capture2_8(i8* %alloca2.bitcast, i8* %alloca.end) 551 call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %alloca2.bitcast) 552 call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %alloca.end) 553 ret void 554} 555 556attributes #0 = { safestack } 557 558declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) 559declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) 560declare void @capture8(i8*) 561declare void @capture32(i32*) 562declare void @capture64(i64*) 563declare void @capture100x32([100 x i32]*) 564declare void @capture2_8(i8*, i8*) 565