1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='dse' -S %s | FileCheck %s 3 4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5 6; Test case from PR50220. 7define i32 @other_value_escapes_before_call() { 8; CHECK-LABEL: @other_value_escapes_before_call( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[V1:%.*]] = alloca i32, align 4 11; CHECK-NEXT: [[V2:%.*]] = alloca i32, align 4 12; CHECK-NEXT: store i32 0, ptr [[V1]], align 4 13; CHECK-NEXT: call void @escape(ptr nonnull [[V1]]) 14; CHECK-NEXT: [[CALL:%.*]] = call i32 @getval() 15; CHECK-NEXT: store i32 [[CALL]], ptr [[V2]], align 4 16; CHECK-NEXT: call void @escape(ptr nonnull [[V2]]) 17; CHECK-NEXT: [[LOAD_V2:%.*]] = load i32, ptr [[V2]], align 4 18; CHECK-NEXT: [[LOAD_V1:%.*]] = load i32, ptr [[V1]], align 4 19; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[LOAD_V2]], [[LOAD_V1]] 20; CHECK-NEXT: ret i32 [[ADD]] 21; 22entry: 23 %v1 = alloca i32, align 4 24 %v2 = alloca i32, align 4 25 store i32 0, ptr %v1, align 4 26 call void @escape(ptr nonnull %v1) 27 store i32 55555, ptr %v2, align 4 28 %call = call i32 @getval() 29 store i32 %call, ptr %v2, align 4 30 call void @escape(ptr nonnull %v2) 31 %load.v2 = load i32, ptr %v2, align 4 32 %load.v1 = load i32, ptr %v1, align 4 33 %add = add nsw i32 %load.v2, %load.v1 34 ret i32 %add 35} 36 37declare void @escape(ptr) 38 39declare i32 @getval() 40 41declare void @escape_and_clobber(ptr) 42declare void @escape_writeonly(ptr) writeonly 43declare void @clobber() 44 45define i32 @test_not_captured_before_call_same_bb() { 46; CHECK-LABEL: @test_not_captured_before_call_same_bb( 47; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 48; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 49; CHECK-NEXT: store i32 99, ptr [[A]], align 4 50; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 51; CHECK-NEXT: ret i32 [[R]] 52; 53 %a = alloca i32, align 4 54 store i32 55, ptr %a 55 %r = call i32 @getval() 56 store i32 99, ptr %a, align 4 57 call void @escape_and_clobber(ptr %a) 58 ret i32 %r 59} 60 61define i32 @test_not_captured_before_call_same_bb_escape_unreachable_block() { 62; CHECK-LABEL: @test_not_captured_before_call_same_bb_escape_unreachable_block( 63; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 64; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 65; CHECK-NEXT: store i32 99, ptr [[A]], align 4 66; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 67; CHECK-NEXT: ret i32 [[R]] 68; CHECK: unreach: 69; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 70; CHECK-NEXT: ret i32 0 71; 72 %a = alloca i32, align 4 73 store i32 55, ptr %a 74 %r = call i32 @getval() 75 store i32 99, ptr %a, align 4 76 call void @escape_and_clobber(ptr %a) 77 ret i32 %r 78 79unreach: 80 call void @escape_and_clobber(ptr %a) 81 ret i32 0 82} 83 84define i32 @test_captured_and_clobbered_after_load_same_bb_2() { 85; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2( 86; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 87; CHECK-NEXT: store i32 55, ptr [[A]], align 4 88; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 89; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 90; CHECK-NEXT: store i32 99, ptr [[A]], align 4 91; CHECK-NEXT: call void @clobber() 92; CHECK-NEXT: ret i32 [[R]] 93; 94 %a = alloca i32, align 4 95 store i32 55, ptr %a 96 %r = call i32 @getval() 97 call void @escape_and_clobber(ptr %a) 98 store i32 99, ptr %a, align 4 99 call void @clobber() 100 ret i32 %r 101} 102 103define i32 @test_captured_after_call_same_bb_2_clobbered_later() { 104; CHECK-LABEL: @test_captured_after_call_same_bb_2_clobbered_later( 105; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 106; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 107; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 108; CHECK-NEXT: store i32 99, ptr [[A]], align 4 109; CHECK-NEXT: call void @clobber() 110; CHECK-NEXT: ret i32 [[R]] 111; 112 %a = alloca i32, align 4 113 store i32 55, ptr %a 114 %r = call i32 @getval() 115 call void @escape_writeonly(ptr %a) 116 store i32 99, ptr %a, align 4 117 call void @clobber() 118 ret i32 %r 119} 120 121define i32 @test_captured_sibling_path_to_call_other_blocks_1(i1 %c.1) { 122; CHECK-LABEL: @test_captured_sibling_path_to_call_other_blocks_1( 123; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 124; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 125; CHECK: then: 126; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 127; CHECK-NEXT: br label [[EXIT:%.*]] 128; CHECK: else: 129; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 130; CHECK-NEXT: br label [[EXIT]] 131; CHECK: exit: 132; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ] 133; CHECK-NEXT: store i32 99, ptr [[A]], align 4 134; CHECK-NEXT: call void @clobber() 135; CHECK-NEXT: ret i32 [[P]] 136; 137 %a = alloca i32, align 4 138 store i32 55, ptr %a 139 br i1 %c.1, label %then, label %else 140 141then: 142 call void @escape_writeonly(ptr %a) 143 br label %exit 144 145else: 146 %r = call i32 @getval() 147 br label %exit 148 149exit: 150 %p = phi i32 [ 0, %then ], [ %r, %else ] 151 store i32 99, ptr %a, align 4 152 call void @clobber() 153 ret i32 %p 154} 155 156define i32 @test_captured_before_call_other_blocks_2(i1 %c.1) { 157; CHECK-LABEL: @test_captured_before_call_other_blocks_2( 158; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 159; CHECK-NEXT: store i32 55, ptr [[A]], align 4 160; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 161; CHECK: then: 162; CHECK-NEXT: br label [[EXIT:%.*]] 163; CHECK: else: 164; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 165; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 166; CHECK-NEXT: br label [[EXIT]] 167; CHECK: exit: 168; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ] 169; CHECK-NEXT: store i32 99, ptr [[A]], align 4 170; CHECK-NEXT: call void @clobber() 171; CHECK-NEXT: ret i32 [[P]] 172; 173 %a = alloca i32, align 4 174 store i32 55, ptr %a 175 br i1 %c.1, label %then, label %else 176 177then: 178 br label %exit 179 180else: 181 call void @escape_and_clobber(ptr %a) 182 %r = call i32 @getval() 183 br label %exit 184 185exit: 186 %p = phi i32 [ 0, %then ], [ %r, %else ] 187 store i32 99, ptr %a, align 4 188 call void @clobber() 189 ret i32 %p 190} 191 192define i32 @test_captured_before_call_other_blocks_4(i1 %c.1) { 193; CHECK-LABEL: @test_captured_before_call_other_blocks_4( 194; CHECK-NEXT: entry: 195; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 196; CHECK-NEXT: store i32 55, ptr [[A]], align 4 197; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 198; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 199; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 200; CHECK: then: 201; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 202; CHECK-NEXT: br label [[EXIT]] 203; CHECK: exit: 204; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ] 205; CHECK-NEXT: store i32 99, ptr [[A]], align 4 206; CHECK-NEXT: call void @clobber() 207; CHECK-NEXT: ret i32 [[P]] 208; 209entry: 210 %a = alloca i32, align 4 211 store i32 55, ptr %a 212 call void @escape_writeonly(ptr %a) 213 %r = call i32 @getval() 214 br i1 %c.1, label %then, label %exit 215 216then: 217 call void @escape_writeonly(ptr %a) 218 br label %exit 219 220exit: 221 %p = phi i32 [ 0, %then ], [ %r, %entry ] 222 store i32 99, ptr %a, align 4 223 call void @clobber() 224 ret i32 %p 225} 226 227define i32 @test_captured_before_call_other_blocks_5(i1 %c.1) { 228; CHECK-LABEL: @test_captured_before_call_other_blocks_5( 229; CHECK-NEXT: entry: 230; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 231; CHECK-NEXT: store i32 55, ptr [[A]], align 4 232; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 233; CHECK: then: 234; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 235; CHECK-NEXT: br label [[EXIT]] 236; CHECK: exit: 237; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 238; CHECK-NEXT: store i32 99, ptr [[A]], align 4 239; CHECK-NEXT: call void @clobber() 240; CHECK-NEXT: ret i32 [[R]] 241; 242entry: 243 %a = alloca i32, align 4 244 store i32 55, ptr %a 245 br i1 %c.1, label %then, label %exit 246 247then: 248 call void @escape_writeonly(ptr %a) 249 br label %exit 250 251exit: 252 %r = call i32 @getval() 253 store i32 99, ptr %a, align 4 254 call void @clobber() 255 ret i32 %r 256} 257 258define i32 @test_captured_before_call_other_blocks_6(i1 %c.1) { 259; CHECK-LABEL: @test_captured_before_call_other_blocks_6( 260; CHECK-NEXT: entry: 261; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 262; CHECK-NEXT: store i32 55, ptr [[A]], align 4 263; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 264; CHECK: then: 265; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 266; CHECK-NEXT: br label [[EXIT]] 267; CHECK: exit: 268; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 269; CHECK-NEXT: store i32 99, ptr [[A]], align 4 270; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 271; CHECK-NEXT: call void @clobber() 272; CHECK-NEXT: ret i32 [[R]] 273; 274entry: 275 %a = alloca i32, align 4 276 store i32 55, ptr %a 277 br i1 %c.1, label %then, label %exit 278 279then: 280 call void @escape_writeonly(ptr %a) 281 br label %exit 282 283exit: 284 %r = call i32 @getval() 285 store i32 99, ptr %a, align 4 286 call void @escape_writeonly(ptr %a) 287 call void @clobber() 288 ret i32 %r 289} 290 291define i32 @test_not_captured_before_call_other_blocks_1(i1 %c.1) { 292; CHECK-LABEL: @test_not_captured_before_call_other_blocks_1( 293; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 294; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 295; CHECK-NEXT: store i32 99, ptr [[A]], align 4 296; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 297; CHECK: then: 298; CHECK-NEXT: br label [[EXIT:%.*]] 299; CHECK: else: 300; CHECK-NEXT: br label [[EXIT]] 301; CHECK: exit: 302; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 303; CHECK-NEXT: ret i32 [[R]] 304; 305 %a = alloca i32, align 4 306 store i32 55, ptr %a 307 %r = call i32 @getval() 308 store i32 99, ptr %a, align 4 309 br i1 %c.1, label %then, label %else 310 311then: 312 br label %exit 313 314else: 315 br label %exit 316 317exit: 318 call void @escape_and_clobber(ptr %a) 319 ret i32 %r 320} 321 322define i32 @test_not_captured_before_call_other_blocks_2(i1 %c.1) { 323; CHECK-LABEL: @test_not_captured_before_call_other_blocks_2( 324; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 325; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 326; CHECK-NEXT: store i32 99, ptr [[A]], align 4 327; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 328; CHECK: then: 329; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 330; CHECK-NEXT: br label [[EXIT:%.*]] 331; CHECK: else: 332; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 333; CHECK-NEXT: br label [[EXIT]] 334; CHECK: exit: 335; CHECK-NEXT: ret i32 [[R]] 336; 337 %a = alloca i32, align 4 338 store i32 55, ptr %a 339 %r = call i32 @getval() 340 store i32 99, ptr %a, align 4 341 br i1 %c.1, label %then, label %else 342 343then: 344 call void @escape_and_clobber(ptr %a) 345 br label %exit 346 347else: 348 call void @escape_and_clobber(ptr %a) 349 br label %exit 350 351exit: 352 ret i32 %r 353} 354 355define i32 @test_not_captured_before_call_other_blocks_3(i1 %c.1) { 356; CHECK-LABEL: @test_not_captured_before_call_other_blocks_3( 357; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 358; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 359; CHECK-NEXT: store i32 99, ptr [[A]], align 4 360; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 361; CHECK: then: 362; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 363; CHECK-NEXT: br label [[EXIT:%.*]] 364; CHECK: else: 365; CHECK-NEXT: br label [[EXIT]] 366; CHECK: exit: 367; CHECK-NEXT: ret i32 [[R]] 368; 369 %a = alloca i32, align 4 370 store i32 55, ptr %a 371 %r = call i32 @getval() 372 store i32 99, ptr %a, align 4 373 br i1 %c.1, label %then, label %else 374 375then: 376 call void @escape_and_clobber(ptr %a) 377 br label %exit 378 379else: 380 br label %exit 381 382exit: 383 ret i32 %r 384} 385 386define i32 @test_not_captured_before_call_other_blocks_4(i1 %c.1) { 387; CHECK-LABEL: @test_not_captured_before_call_other_blocks_4( 388; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 389; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 390; CHECK: then: 391; CHECK-NEXT: br label [[EXIT:%.*]] 392; CHECK: else: 393; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 394; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 395; CHECK-NEXT: br label [[EXIT]] 396; CHECK: exit: 397; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ] 398; CHECK-NEXT: store i32 99, ptr [[A]], align 4 399; CHECK-NEXT: call void @clobber() 400; CHECK-NEXT: ret i32 [[P]] 401; 402 %a = alloca i32, align 4 403 store i32 55, ptr %a 404 br i1 %c.1, label %then, label %else 405 406then: 407 br label %exit 408 409else: 410 %r = call i32 @getval() 411 call void @escape_writeonly(ptr %a) 412 br label %exit 413 414exit: 415 %p = phi i32 [ 0, %then ], [ %r, %else ] 416 store i32 99, ptr %a, align 4 417 call void @clobber() 418 ret i32 %p 419} 420 421define i32 @test_not_captured_before_call_other_blocks_5(i1 %c.1) { 422; CHECK-LABEL: @test_not_captured_before_call_other_blocks_5( 423; CHECK-NEXT: entry: 424; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 425; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 426; CHECK: then: 427; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 428; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 429; CHECK-NEXT: br label [[EXIT]] 430; CHECK: exit: 431; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ] 432; CHECK-NEXT: store i32 99, ptr [[A]], align 4 433; CHECK-NEXT: call void @clobber() 434; CHECK-NEXT: ret i32 [[P]] 435; 436entry: 437 %a = alloca i32, align 4 438 store i32 55, ptr %a 439 br i1 %c.1, label %then, label %exit 440 441then: 442 %r = call i32 @getval() 443 call void @escape_writeonly(ptr %a) 444 br label %exit 445 446exit: 447 %p = phi i32 [ %r, %then ], [ 0, %entry ] 448 store i32 99, ptr %a, align 4 449 call void @clobber() 450 ret i32 %p 451} 452 453define i32 @test_not_captured_before_call_other_blocks_6(i1 %c.1) { 454; CHECK-LABEL: @test_not_captured_before_call_other_blocks_6( 455; CHECK-NEXT: entry: 456; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 457; CHECK-NEXT: store i32 55, ptr [[A]], align 4 458; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 459; CHECK: then: 460; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 461; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 462; CHECK-NEXT: br label [[EXIT]] 463; CHECK: exit: 464; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ] 465; CHECK-NEXT: store i32 99, ptr [[A]], align 4 466; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 467; CHECK-NEXT: call void @clobber() 468; CHECK-NEXT: ret i32 [[P]] 469; 470entry: 471 %a = alloca i32, align 4 472 store i32 55, ptr %a 473 br i1 %c.1, label %then, label %exit 474 475then: 476 %r = call i32 @getval() 477 call void @escape_writeonly(ptr %a) 478 br label %exit 479 480exit: 481 %p = phi i32 [ %r, %then ], [ 0, %entry ] 482 store i32 99, ptr %a, align 4 483 call void @escape_writeonly(ptr %a) 484 call void @clobber() 485 ret i32 %p 486} 487 488define i32 @test_not_captured_before_call_other_blocks_7(i1 %c.1) { 489; CHECK-LABEL: @test_not_captured_before_call_other_blocks_7( 490; CHECK-NEXT: entry: 491; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 492; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 493; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 494; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 495; CHECK: then: 496; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 497; CHECK-NEXT: br label [[EXIT]] 498; CHECK: exit: 499; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ] 500; CHECK-NEXT: store i32 99, ptr [[A]], align 4 501; CHECK-NEXT: call void @clobber() 502; CHECK-NEXT: ret i32 [[P]] 503; 504entry: 505 %a = alloca i32, align 4 506 store i32 55, ptr %a 507 %r = call i32 @getval() 508 call void @escape_writeonly(ptr %a) 509 br i1 %c.1, label %then, label %exit 510 511then: 512 call void @escape_writeonly(ptr %a) 513 br label %exit 514 515exit: 516 %p = phi i32 [ 0, %then ], [ %r, %entry ] 517 store i32 99, ptr %a, align 4 518 call void @clobber() 519 ret i32 %p 520} 521 522define i32 @test_not_captured_before_call_same_bb_but_read() { 523; CHECK-LABEL: @test_not_captured_before_call_same_bb_but_read( 524; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 525; CHECK-NEXT: store i32 55, ptr [[A]], align 4 526; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 527; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[A]], align 4 528; CHECK-NEXT: store i32 99, ptr [[A]], align 4 529; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 530; CHECK-NEXT: [[RES:%.*]] = add i32 [[R]], [[LV]] 531; CHECK-NEXT: ret i32 [[RES]] 532; 533 %a = alloca i32, align 4 534 store i32 55, ptr %a 535 %r = call i32 @getval() 536 %lv = load i32, ptr %a 537 store i32 99, ptr %a, align 4 538 call void @escape_and_clobber(ptr %a) 539 %res = add i32 %r, %lv 540 ret i32 %res 541} 542 543define i32 @test_captured_after_loop(i1 %c.1) { 544; CHECK-LABEL: @test_captured_after_loop( 545; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 546; CHECK-NEXT: br label [[LOOP:%.*]] 547; CHECK: loop: 548; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 549; CHECK-NEXT: store i32 99, ptr [[A]], align 4 550; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]] 551; CHECK: exit: 552; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 553; CHECK-NEXT: ret i32 [[R]] 554; 555 %a = alloca i32, align 4 556 store i32 55, ptr %a 557 br label %loop 558 559loop: 560 %r = call i32 @getval() 561 store i32 99, ptr %a, align 4 562 br i1 %c.1, label %loop, label %exit 563 564exit: 565 call void @escape_and_clobber(ptr %a) 566 ret i32 %r 567} 568 569define i32 @test_captured_in_loop(i1 %c.1) { 570; CHECK-LABEL: @test_captured_in_loop( 571; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 572; CHECK-NEXT: store i32 55, ptr [[A]], align 4 573; CHECK-NEXT: br label [[LOOP:%.*]] 574; CHECK: loop: 575; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 576; CHECK-NEXT: call void @escape_writeonly(ptr [[A]]) 577; CHECK-NEXT: store i32 99, ptr [[A]], align 4 578; CHECK-NEXT: br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]] 579; CHECK: exit: 580; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 581; CHECK-NEXT: ret i32 [[R]] 582; 583 %a = alloca i32, align 4 584 store i32 55, ptr %a 585 br label %loop 586 587loop: 588 %r = call i32 @getval() 589 call void @escape_writeonly(ptr %a) 590 store i32 99, ptr %a, align 4 591 br i1 %c.1, label %loop, label %exit 592 593exit: 594 call void @escape_and_clobber(ptr %a) 595 ret i32 %r 596} 597 598declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1) 599define void @test_escaping_store_removed(ptr %src, ptr %escape) { 600; CHECK-LABEL: @test_escaping_store_removed( 601; CHECK-NEXT: bb: 602; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8 603; CHECK-NEXT: call void @clobber() 604; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr [[SRC:%.*]], i64 8, i1 false) 605; CHECK-NEXT: store ptr [[A]], ptr [[ESCAPE:%.*]], align 8 606; CHECK-NEXT: call void @clobber() 607; CHECK-NEXT: store i64 99, ptr [[A]], align 8 608; CHECK-NEXT: call void @clobber() 609; CHECK-NEXT: ret void 610; 611bb: 612 %a = alloca i64, align 8 613 store i64 0, ptr %a 614 call void @clobber() 615 call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %src, i64 8, i1 false) 616 store ptr %a, ptr %escape, align 8 617 store ptr %a, ptr %escape, align 8 618 call void @clobber() 619 store i64 99, ptr %a 620 call void @clobber() 621 ret void 622} 623 624 625define void @test_invoke_captures() personality ptr undef { 626; CHECK-LABEL: @test_invoke_captures( 627; CHECK-NEXT: bb: 628; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 629; CHECK-NEXT: invoke void @clobber() 630; CHECK-NEXT: to label [[BB2:%.*]] unwind label [[BB5:%.*]] 631; CHECK: bb2: 632; CHECK-NEXT: store i32 0, ptr [[A]], align 8 633; CHECK-NEXT: invoke void @escape(ptr [[A]]) 634; CHECK-NEXT: to label [[BB9:%.*]] unwind label [[BB10:%.*]] 635; CHECK: bb4: 636; CHECK-NEXT: ret void 637; CHECK: bb5: 638; CHECK-NEXT: [[LP_1:%.*]] = landingpad { ptr, i32 } 639; CHECK-NEXT: cleanup 640; CHECK-NEXT: ret void 641; CHECK: bb9: 642; CHECK-NEXT: ret void 643; CHECK: bb10: 644; CHECK-NEXT: [[LP_2:%.*]] = landingpad { ptr, i32 } 645; CHECK-NEXT: cleanup 646; CHECK-NEXT: unreachable 647; 648bb: 649 %a = alloca i32 650 store i32 99, ptr %a 651 invoke void @clobber() 652 to label %bb2 unwind label %bb5 653 654bb2: 655 store i32 0, ptr %a, align 8 656 invoke void @escape(ptr %a) 657 to label %bb9 unwind label %bb10 658 659bb4: 660 ret void 661 662bb5: 663 %lp.1 = landingpad { ptr, i32 } 664 cleanup 665 ret void 666 667bb9: 668 ret void 669 670bb10: 671 %lp.2 = landingpad { ptr, i32 } 672 cleanup 673 unreachable 674} 675 676declare noalias ptr @alloc() nounwind 677declare i32 @getval_nounwind() nounwind 678 679define i32 @test_not_captured_before_load_same_bb_noalias_call() { 680; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call( 681; CHECK-NEXT: [[A:%.*]] = call ptr @alloc() 682; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind() 683; CHECK-NEXT: store i32 99, ptr [[A]], align 4 684; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 685; CHECK-NEXT: ret i32 [[R]] 686; 687 %a = call ptr @alloc() 688 store i32 55, ptr %a 689 %r = call i32 @getval_nounwind() 690 store i32 99, ptr %a, align 4 691 call void @escape_and_clobber(ptr %a) 692 ret i32 %r 693} 694 695define i32 @test_not_captured_before_load_same_bb_noalias_arg(ptr noalias %a) { 696; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg( 697; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind() 698; CHECK-NEXT: store i32 99, ptr [[A:%.*]], align 4 699; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]]) 700; CHECK-NEXT: ret i32 [[R]] 701; 702 store i32 55, ptr %a 703 %r = call i32 @getval_nounwind() 704 store i32 99, ptr %a, align 4 705 call void @escape_and_clobber(ptr %a) 706 ret i32 %r 707} 708