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, i32* [[V1]], align 4 13; CHECK-NEXT: call void @escape(i32* nonnull [[V1]]) 14; CHECK-NEXT: [[CALL:%.*]] = call i32 @getval() 15; CHECK-NEXT: store i32 [[CALL]], i32* [[V2]], align 4 16; CHECK-NEXT: call void @escape(i32* nonnull [[V2]]) 17; CHECK-NEXT: [[LOAD_V2:%.*]] = load i32, i32* [[V2]], align 4 18; CHECK-NEXT: [[LOAD_V1:%.*]] = load i32, i32* [[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, i32* %v1, align 4 26 call void @escape(i32* nonnull %v1) 27 store i32 55555, i32* %v2, align 4 28 %call = call i32 @getval() 29 store i32 %call, i32* %v2, align 4 30 call void @escape(i32* nonnull %v2) 31 %load.v2 = load i32, i32* %v2, align 4 32 %load.v1 = load i32, i32* %v1, align 4 33 %add = add nsw i32 %load.v2, %load.v1 34 ret i32 %add 35} 36 37declare void @escape(i32*) 38 39declare i32 @getval() 40 41declare void @escape_and_clobber(i32*) 42declare void @escape_writeonly(i32*) 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, i32* [[A]], align 4 50; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]]) 51; CHECK-NEXT: ret i32 [[R]] 52; 53 %a = alloca i32, align 4 54 store i32 55, i32* %a 55 %r = call i32 @getval() 56 store i32 99, i32* %a, align 4 57 call void @escape_and_clobber(i32* %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, i32* [[A]], align 4 66; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]]) 67; CHECK-NEXT: ret i32 [[R]] 68; CHECK: unreach: 69; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]]) 70; CHECK-NEXT: ret i32 0 71; 72 %a = alloca i32, align 4 73 store i32 55, i32* %a 74 %r = call i32 @getval() 75 store i32 99, i32* %a, align 4 76 call void @escape_and_clobber(i32* %a) 77 ret i32 %r 78 79unreach: 80 call void @escape_and_clobber(i32* %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, i32* [[A]], align 4 88; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 89; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]]) 90; CHECK-NEXT: store i32 99, i32* [[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, i32* %a 96 %r = call i32 @getval() 97 call void @escape_and_clobber(i32* %a) 98 store i32 99, i32* %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(i32* [[A]]) 108; CHECK-NEXT: store i32 99, i32* [[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, i32* %a 114 %r = call i32 @getval() 115 call void @escape_writeonly(i32* %a) 116 store i32 99, i32* %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(i32* [[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, i32* [[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, i32* %a 139 br i1 %c.1, label %then, label %else 140 141then: 142 call void @escape_writeonly(i32* %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, i32* %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, i32* [[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(i32* [[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, i32* [[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, i32* %a 175 br i1 %c.1, label %then, label %else 176 177then: 178 br label %exit 179 180else: 181 call void @escape_and_clobber(i32* %a) 182 %r = call i32 @getval() 183 br label %exit 184 185exit: 186 %p = phi i32 [ 0, %then ], [ %r, %else ] 187 store i32 99, i32* %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, i32* [[A]], align 4 197; CHECK-NEXT: call void @escape_writeonly(i32* [[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(i32* [[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, i32* [[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, i32* %a 212 call void @escape_writeonly(i32* %a) 213 %r = call i32 @getval() 214 br i1 %c.1, label %then, label %exit 215 216then: 217 call void @escape_writeonly(i32* %a) 218 br label %exit 219 220exit: 221 %p = phi i32 [ 0, %then ], [ %r, %entry ] 222 store i32 99, i32* %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, i32* [[A]], align 4 232; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 233; CHECK: then: 234; CHECK-NEXT: call void @escape_writeonly(i32* [[A]]) 235; CHECK-NEXT: br label [[EXIT]] 236; CHECK: exit: 237; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 238; CHECK-NEXT: store i32 99, i32* [[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, i32* %a 245 br i1 %c.1, label %then, label %exit 246 247then: 248 call void @escape_writeonly(i32* %a) 249 br label %exit 250 251exit: 252 %r = call i32 @getval() 253 store i32 99, i32* %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, i32* [[A]], align 4 263; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 264; CHECK: then: 265; CHECK-NEXT: call void @escape_writeonly(i32* [[A]]) 266; CHECK-NEXT: br label [[EXIT]] 267; CHECK: exit: 268; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 269; CHECK-NEXT: store i32 99, i32* [[A]], align 4 270; CHECK-NEXT: call void @escape_writeonly(i32* [[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, i32* %a 277 br i1 %c.1, label %then, label %exit 278 279then: 280 call void @escape_writeonly(i32* %a) 281 br label %exit 282 283exit: 284 %r = call i32 @getval() 285 store i32 99, i32* %a, align 4 286 call void @escape_writeonly(i32* %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, i32* [[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(i32* [[A]]) 303; CHECK-NEXT: ret i32 [[R]] 304; 305 %a = alloca i32, align 4 306 store i32 55, i32* %a 307 %r = call i32 @getval() 308 store i32 99, i32* %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(i32* %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, i32* [[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(i32* [[A]]) 330; CHECK-NEXT: br label [[EXIT:%.*]] 331; CHECK: else: 332; CHECK-NEXT: call void @escape_and_clobber(i32* [[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, i32* %a 339 %r = call i32 @getval() 340 store i32 99, i32* %a, align 4 341 br i1 %c.1, label %then, label %else 342 343then: 344 call void @escape_and_clobber(i32* %a) 345 br label %exit 346 347else: 348 call void @escape_and_clobber(i32* %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, i32* [[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(i32* [[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, i32* %a 371 %r = call i32 @getval() 372 store i32 99, i32* %a, align 4 373 br i1 %c.1, label %then, label %else 374 375then: 376 call void @escape_and_clobber(i32* %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(i32* [[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, i32* [[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, i32* %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(i32* %a) 412 br label %exit 413 414exit: 415 %p = phi i32 [ 0, %then ], [ %r, %else ] 416 store i32 99, i32* %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(i32* [[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, i32* [[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, i32* %a 439 br i1 %c.1, label %then, label %exit 440 441then: 442 %r = call i32 @getval() 443 call void @escape_writeonly(i32* %a) 444 br label %exit 445 446exit: 447 %p = phi i32 [ %r, %then ], [ 0, %entry ] 448 store i32 99, i32* %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, i32* [[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(i32* [[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, i32* [[A]], align 4 466; CHECK-NEXT: call void @escape_writeonly(i32* [[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, i32* %a 473 br i1 %c.1, label %then, label %exit 474 475then: 476 %r = call i32 @getval() 477 call void @escape_writeonly(i32* %a) 478 br label %exit 479 480exit: 481 %p = phi i32 [ %r, %then ], [ 0, %entry ] 482 store i32 99, i32* %a, align 4 483 call void @escape_writeonly(i32* %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(i32* [[A]]) 494; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 495; CHECK: then: 496; CHECK-NEXT: call void @escape_writeonly(i32* [[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, i32* [[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, i32* %a 507 %r = call i32 @getval() 508 call void @escape_writeonly(i32* %a) 509 br i1 %c.1, label %then, label %exit 510 511then: 512 call void @escape_writeonly(i32* %a) 513 br label %exit 514 515exit: 516 %p = phi i32 [ 0, %then ], [ %r, %entry ] 517 store i32 99, i32* %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, i32* [[A]], align 4 526; CHECK-NEXT: [[R:%.*]] = call i32 @getval() 527; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[A]], align 4 528; CHECK-NEXT: store i32 99, i32* [[A]], align 4 529; CHECK-NEXT: call void @escape_and_clobber(i32* [[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, i32* %a 535 %r = call i32 @getval() 536 %lv = load i32, i32* %a 537 store i32 99, i32* %a, align 4 538 call void @escape_and_clobber(i32* %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, i32* [[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(i32* [[A]]) 553; CHECK-NEXT: ret i32 [[R]] 554; 555 %a = alloca i32, align 4 556 store i32 55, i32* %a 557 br label %loop 558 559loop: 560 %r = call i32 @getval() 561 store i32 99, i32* %a, align 4 562 br i1 %c.1, label %loop, label %exit 563 564exit: 565 call void @escape_and_clobber(i32* %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, i32* [[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(i32* [[A]]) 577; CHECK-NEXT: store i32 99, i32* [[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(i32* [[A]]) 581; CHECK-NEXT: ret i32 [[R]] 582; 583 %a = alloca i32, align 4 584 store i32 55, i32* %a 585 br label %loop 586 587loop: 588 %r = call i32 @getval() 589 call void @escape_writeonly(i32* %a) 590 store i32 99, i32* %a, align 4 591 br i1 %c.1, label %loop, label %exit 592 593exit: 594 call void @escape_and_clobber(i32* %a) 595 ret i32 %r 596} 597 598declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) 599define void @test_escaping_store_removed(i8* %src, i64** %escape) { 600; CHECK-LABEL: @test_escaping_store_removed( 601; CHECK-NEXT: bb: 602; CHECK-NEXT: [[A:%.*]] = alloca i64, align 8 603; CHECK-NEXT: [[EXT_A:%.*]] = bitcast i64* [[A]] to i8* 604; CHECK-NEXT: call void @clobber() 605; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXT_A]], i8* [[SRC:%.*]], i64 8, i1 false) 606; CHECK-NEXT: store i64* [[A]], i64** [[ESCAPE:%.*]], align 8 607; CHECK-NEXT: call void @clobber() 608; CHECK-NEXT: store i64 99, i64* [[A]], align 8 609; CHECK-NEXT: call void @clobber() 610; CHECK-NEXT: ret void 611; 612bb: 613 %a = alloca i64, align 8 614 %ext.a = bitcast i64* %a to i8* 615 store i64 0, i64* %a 616 call void @clobber() 617 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %ext.a, i8* %src, i64 8, i1 false) 618 store i64* %a, i64** %escape, align 8 619 store i64* %a, i64** %escape, align 8 620 call void @clobber() 621 store i64 99, i64* %a 622 call void @clobber() 623 ret void 624} 625 626 627define void @test_invoke_captures() personality i8* undef { 628; CHECK-LABEL: @test_invoke_captures( 629; CHECK-NEXT: bb: 630; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 631; CHECK-NEXT: invoke void @clobber() 632; CHECK-NEXT: to label [[BB2:%.*]] unwind label [[BB5:%.*]] 633; CHECK: bb2: 634; CHECK-NEXT: store i32 0, i32* [[A]], align 8 635; CHECK-NEXT: invoke void @escape(i32* [[A]]) 636; CHECK-NEXT: to label [[BB9:%.*]] unwind label [[BB10:%.*]] 637; CHECK: bb4: 638; CHECK-NEXT: ret void 639; CHECK: bb5: 640; CHECK-NEXT: [[LP_1:%.*]] = landingpad { i8*, i32 } 641; CHECK-NEXT: cleanup 642; CHECK-NEXT: ret void 643; CHECK: bb9: 644; CHECK-NEXT: ret void 645; CHECK: bb10: 646; CHECK-NEXT: [[LP_2:%.*]] = landingpad { i8*, i32 } 647; CHECK-NEXT: cleanup 648; CHECK-NEXT: unreachable 649; 650bb: 651 %a = alloca i32 652 store i32 99, i32* %a 653 invoke void @clobber() 654 to label %bb2 unwind label %bb5 655 656bb2: 657 store i32 0, i32* %a, align 8 658 invoke void @escape(i32* %a) 659 to label %bb9 unwind label %bb10 660 661bb4: 662 ret void 663 664bb5: 665 %lp.1 = landingpad { i8*, i32 } 666 cleanup 667 ret void 668 669bb9: 670 ret void 671 672bb10: 673 %lp.2 = landingpad { i8*, i32 } 674 cleanup 675 unreachable 676} 677 678declare noalias i32* @alloc() nounwind 679declare i32 @getval_nounwind() nounwind 680 681define i32 @test_not_captured_before_load_same_bb_noalias_call() { 682; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call( 683; CHECK-NEXT: [[A:%.*]] = call i32* @alloc() 684; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind() 685; CHECK-NEXT: store i32 99, i32* [[A]], align 4 686; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]]) 687; CHECK-NEXT: ret i32 [[R]] 688; 689 %a = call i32* @alloc() 690 store i32 55, i32* %a 691 %r = call i32 @getval_nounwind() 692 store i32 99, i32* %a, align 4 693 call void @escape_and_clobber(i32* %a) 694 ret i32 %r 695} 696 697define i32 @test_not_captured_before_load_same_bb_noalias_arg(i32* noalias %a) { 698; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg( 699; CHECK-NEXT: [[R:%.*]] = call i32 @getval_nounwind() 700; CHECK-NEXT: store i32 99, i32* [[A:%.*]], align 4 701; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]]) 702; CHECK-NEXT: ret i32 [[R]] 703; 704 store i32 55, i32* %a 705 %r = call i32 @getval_nounwind() 706 store i32 99, i32* %a, align 4 707 call void @escape_and_clobber(i32* %a) 708 ret i32 %r 709} 710