1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=loop-unroll -S %s | FileCheck %s 3 4declare void @foo() 5 6define void @peel_unreachable_exit_and_latch_exit(ptr %ptr, i32 %N, i32 %x) { 7; CHECK-LABEL: @peel_unreachable_exit_and_latch_exit( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_BEGIN:%.*]] 10; CHECK: loop.header.peel.begin: 11; CHECK-NEXT: br label [[LOOP_HEADER_PEEL:%.*]] 12; CHECK: loop.header.peel: 13; CHECK-NEXT: [[C_PEEL:%.*]] = icmp ult i32 1, 2 14; CHECK-NEXT: br i1 [[C_PEEL]], label [[THEN_PEEL:%.*]], label [[ELSE_PEEL:%.*]] 15; CHECK: else.peel: 16; CHECK-NEXT: [[C_2_PEEL:%.*]] = icmp eq i32 1, [[X:%.*]] 17; CHECK-NEXT: br i1 [[C_2_PEEL]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH_PEEL:%.*]] 18; CHECK: then.peel: 19; CHECK-NEXT: br label [[LOOP_LATCH_PEEL]] 20; CHECK: loop.latch.peel: 21; CHECK-NEXT: [[M_PEEL:%.*]] = phi i32 [ 0, [[THEN_PEEL]] ], [ [[X]], [[ELSE_PEEL]] ] 22; CHECK-NEXT: [[GEP_PEEL:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 1 23; CHECK-NEXT: store i32 [[M_PEEL]], ptr [[GEP_PEEL]], align 4 24; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add nuw nsw i32 1, 1 25; CHECK-NEXT: [[C_3_PEEL:%.*]] = icmp ult i32 1, 1000 26; CHECK-NEXT: br i1 [[C_3_PEEL]], label [[LOOP_HEADER_PEEL_NEXT:%.*]], label [[EXIT:%.*]] 27; CHECK: loop.header.peel.next: 28; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_NEXT1:%.*]] 29; CHECK: loop.header.peel.next1: 30; CHECK-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] 31; CHECK: entry.peel.newph: 32; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 33; CHECK: loop.header: 34; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 35; CHECK-NEXT: br i1 false, label [[THEN:%.*]], label [[ELSE:%.*]] 36; CHECK: then: 37; CHECK-NEXT: br label [[LOOP_LATCH]] 38; CHECK: else: 39; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X]] 40; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT_LOOPEXIT:%.*]], label [[LOOP_LATCH]] 41; CHECK: loop.latch: 42; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ] 43; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[IV]] 44; CHECK-NEXT: store i32 [[M]], ptr [[GEP]], align 4 45; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 46; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 47; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]] 48; CHECK: exit.loopexit: 49; CHECK-NEXT: br label [[EXIT]] 50; CHECK: exit: 51; CHECK-NEXT: ret void 52; CHECK: unreachable.exit.loopexit: 53; CHECK-NEXT: br label [[UNREACHABLE_EXIT]] 54; CHECK: unreachable.exit: 55; CHECK-NEXT: call void @foo() 56; CHECK-NEXT: unreachable 57; 58entry: 59 br label %loop.header 60 61loop.header: 62 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 63 %c = icmp ult i32 %iv, 2 64 br i1 %c, label %then, label %else 65 66then: 67 br label %loop.latch 68 69else: 70 %c.2 = icmp eq i32 %iv, %x 71 br i1 %c.2, label %unreachable.exit, label %loop.latch 72 73loop.latch: 74 %m = phi i32 [ 0, %then ], [ %x, %else ] 75 %gep = getelementptr i32, ptr %ptr, i32 %iv 76 store i32 %m, ptr %gep 77 %iv.next = add nuw nsw i32 %iv, 1 78 %c.3 = icmp ult i32 %iv, 1000 79 br i1 %c.3, label %loop.header, label %exit 80 81exit: 82 ret void 83 84unreachable.exit: 85 call void @foo() 86 unreachable 87} 88 89define void @peel_unreachable_exit_and_header_exit(ptr %ptr, i32 %N, i32 %x) { 90; CHECK-LABEL: @peel_unreachable_exit_and_header_exit( 91; CHECK-NEXT: entry: 92; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 93; CHECK: loop.header: 94; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[ELSE:%.*]] 95; CHECK: else: 96; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 1, [[X:%.*]] 97; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH:%.*]] 98; CHECK: loop.latch: 99; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 1 100; CHECK-NEXT: store i32 [[X]], ptr [[GEP]], align 4 101; CHECK-NEXT: unreachable 102; CHECK: exit: 103; CHECK-NEXT: ret void 104; CHECK: unreachable.exit: 105; CHECK-NEXT: call void @foo() 106; CHECK-NEXT: unreachable 107; 108entry: 109 br label %loop.header 110 111loop.header: 112 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 113 %c = icmp ult i32 %iv, 1000 114 br i1 %c, label %exit, label %else 115 116else: 117 %c.2 = icmp eq i32 %iv, %x 118 br i1 %c.2, label %unreachable.exit, label %loop.latch 119 120loop.latch: 121 %gep = getelementptr i32, ptr %ptr, i32 %iv 122 store i32 %x, ptr %gep 123 %iv.next = add nuw nsw i32 %iv, 1 124 br label %loop.header 125 126exit: 127 ret void 128 129unreachable.exit: 130 call void @foo() 131 unreachable 132} 133 134define void @peel_unreachable_and_multiple_reachable_exits(ptr %ptr, i32 %N, i32 %x) { 135; CHECK-LABEL: @peel_unreachable_and_multiple_reachable_exits( 136; CHECK-NEXT: entry: 137; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_BEGIN:%.*]] 138; CHECK: loop.header.peel.begin: 139; CHECK-NEXT: br label [[LOOP_HEADER_PEEL:%.*]] 140; CHECK: loop.header.peel: 141; CHECK-NEXT: [[C_PEEL:%.*]] = icmp ult i32 1, 2 142; CHECK-NEXT: br i1 [[C_PEEL]], label [[THEN_PEEL:%.*]], label [[ELSE_PEEL:%.*]] 143; CHECK: else.peel: 144; CHECK-NEXT: [[C_3_PEEL:%.*]] = icmp eq i32 1, [[X:%.*]] 145; CHECK-NEXT: br i1 [[C_3_PEEL]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH_PEEL:%.*]] 146; CHECK: then.peel: 147; CHECK-NEXT: [[C_2_PEEL:%.*]] = icmp sgt i32 1, [[X]] 148; CHECK-NEXT: br i1 [[C_2_PEEL]], label [[EXIT:%.*]], label [[LOOP_LATCH_PEEL]] 149; CHECK: loop.latch.peel: 150; CHECK-NEXT: [[M_PEEL:%.*]] = phi i32 [ 0, [[THEN_PEEL]] ], [ [[X]], [[ELSE_PEEL]] ] 151; CHECK-NEXT: [[GEP_PEEL:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 1 152; CHECK-NEXT: store i32 [[M_PEEL]], ptr [[GEP_PEEL]], align 4 153; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add nuw nsw i32 1, 1 154; CHECK-NEXT: [[C_4_PEEL:%.*]] = icmp ult i32 1, 1000 155; CHECK-NEXT: br i1 [[C_4_PEEL]], label [[LOOP_HEADER_PEEL_NEXT:%.*]], label [[EXIT]] 156; CHECK: loop.header.peel.next: 157; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_NEXT1:%.*]] 158; CHECK: loop.header.peel.next1: 159; CHECK-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] 160; CHECK: entry.peel.newph: 161; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 162; CHECK: loop.header: 163; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 164; CHECK-NEXT: br i1 false, label [[THEN:%.*]], label [[ELSE:%.*]] 165; CHECK: then: 166; CHECK-NEXT: br i1 true, label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_LATCH]] 167; CHECK: else: 168; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[IV]], [[X]] 169; CHECK-NEXT: br i1 [[C_3]], label [[UNREACHABLE_EXIT_LOOPEXIT:%.*]], label [[LOOP_LATCH]] 170; CHECK: loop.latch: 171; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ] 172; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[IV]] 173; CHECK-NEXT: store i32 [[M]], ptr [[GEP]], align 4 174; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 175; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[IV]], 1000 176; CHECK-NEXT: br i1 [[C_4]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP2:![0-9]+]] 177; CHECK: exit.loopexit: 178; CHECK-NEXT: br label [[EXIT]] 179; CHECK: exit: 180; CHECK-NEXT: ret void 181; CHECK: unreachable.exit.loopexit: 182; CHECK-NEXT: br label [[UNREACHABLE_EXIT]] 183; CHECK: unreachable.exit: 184; CHECK-NEXT: call void @foo() 185; CHECK-NEXT: unreachable 186; 187entry: 188 br label %loop.header 189 190loop.header: 191 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 192 %c = icmp ult i32 %iv, 2 193 br i1 %c, label %then, label %else 194 195then: 196 %c.2 = icmp sgt i32 %iv, %x 197 br i1 %c.2, label %exit, label %loop.latch 198 199else: 200 %c.3 = icmp eq i32 %iv, %x 201 br i1 %c.3, label %unreachable.exit, label %loop.latch 202 203loop.latch: 204 %m = phi i32 [ 0, %then ], [ %x, %else ] 205 %gep = getelementptr i32, ptr %ptr, i32 %iv 206 store i32 %m, ptr %gep 207 %iv.next = add nuw nsw i32 %iv, 1 208 %c.4 = icmp ult i32 %iv, 1000 209 br i1 %c.4, label %loop.header, label %exit 210 211exit: 212 ret void 213 214unreachable.exit: 215 call void @foo() 216 unreachable 217} 218 219define void @peel_exits_to_blocks_branch_to_unreachable_block(ptr %ptr, i32 %N, i32 %x, i1 %c.1) { 220; CHECK-LABEL: @peel_exits_to_blocks_branch_to_unreachable_block( 221; CHECK-NEXT: entry: 222; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_BEGIN:%.*]] 223; CHECK: loop.header.peel.begin: 224; CHECK-NEXT: br label [[LOOP_HEADER_PEEL:%.*]] 225; CHECK: loop.header.peel: 226; CHECK-NEXT: [[C_PEEL:%.*]] = icmp ult i32 1, 2 227; CHECK-NEXT: br i1 [[C_PEEL]], label [[THEN_PEEL:%.*]], label [[ELSE_PEEL:%.*]] 228; CHECK: else.peel: 229; CHECK-NEXT: [[C_2_PEEL:%.*]] = icmp eq i32 1, [[X:%.*]] 230; CHECK-NEXT: br i1 [[C_2_PEEL]], label [[EXIT_2:%.*]], label [[LOOP_LATCH_PEEL:%.*]] 231; CHECK: then.peel: 232; CHECK-NEXT: br i1 [[C_1:%.*]], label [[EXIT_1:%.*]], label [[LOOP_LATCH_PEEL]] 233; CHECK: loop.latch.peel: 234; CHECK-NEXT: [[M_PEEL:%.*]] = phi i32 [ 0, [[THEN_PEEL]] ], [ [[X]], [[ELSE_PEEL]] ] 235; CHECK-NEXT: [[GEP_PEEL:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 1 236; CHECK-NEXT: store i32 [[M_PEEL]], ptr [[GEP_PEEL]], align 4 237; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add nuw nsw i32 1, 1 238; CHECK-NEXT: [[C_3_PEEL:%.*]] = icmp ult i32 1, 1000 239; CHECK-NEXT: br i1 [[C_3_PEEL]], label [[LOOP_HEADER_PEEL_NEXT:%.*]], label [[EXIT:%.*]] 240; CHECK: loop.header.peel.next: 241; CHECK-NEXT: br label [[LOOP_HEADER_PEEL_NEXT1:%.*]] 242; CHECK: loop.header.peel.next1: 243; CHECK-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] 244; CHECK: entry.peel.newph: 245; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 246; CHECK: loop.header: 247; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT_PEEL]], [[ENTRY_PEEL_NEWPH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 248; CHECK-NEXT: br i1 false, label [[THEN:%.*]], label [[ELSE:%.*]] 249; CHECK: then: 250; CHECK-NEXT: br i1 [[C_1]], label [[EXIT_1_LOOPEXIT:%.*]], label [[LOOP_LATCH]] 251; CHECK: else: 252; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X]] 253; CHECK-NEXT: br i1 [[C_2]], label [[EXIT_2_LOOPEXIT:%.*]], label [[LOOP_LATCH]] 254; CHECK: loop.latch: 255; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ] 256; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[IV]] 257; CHECK-NEXT: store i32 [[M]], ptr [[GEP]], align 4 258; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 259; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000 260; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]] 261; CHECK: exit.loopexit: 262; CHECK-NEXT: br label [[EXIT]] 263; CHECK: exit: 264; CHECK-NEXT: ret void 265; CHECK: exit.1.loopexit: 266; CHECK-NEXT: br label [[EXIT_1]] 267; CHECK: exit.1: 268; CHECK-NEXT: call void @foo() 269; CHECK-NEXT: br label [[UNREACHABLE_TERM:%.*]] 270; CHECK: exit.2.loopexit: 271; CHECK-NEXT: br label [[EXIT_2]] 272; CHECK: exit.2: 273; CHECK-NEXT: call void @bar() 274; CHECK-NEXT: br label [[UNREACHABLE_TERM]] 275; CHECK: unreachable.term: 276; CHECK-NEXT: call void @baz() 277; CHECK-NEXT: unreachable 278; 279entry: 280 br label %loop.header 281 282loop.header: 283 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 284 %c = icmp ult i32 %iv, 2 285 br i1 %c, label %then, label %else 286 287then: 288 br i1 %c.1, label %exit.1, label %loop.latch 289 290else: 291 %c.2 = icmp eq i32 %iv, %x 292 br i1 %c.2, label %exit.2, label %loop.latch 293 294loop.latch: 295 %m = phi i32 [ 0, %then ], [ %x, %else ] 296 %gep = getelementptr i32, ptr %ptr, i32 %iv 297 store i32 %m, ptr %gep 298 %iv.next = add nuw nsw i32 %iv, 1 299 %c.3 = icmp ult i32 %iv, 1000 300 br i1 %c.3, label %loop.header, label %exit 301 302exit: 303 ret void 304 305exit.1: 306 call void @foo() 307 br label %unreachable.term 308 309exit.2: 310 call void @bar() 311 br label %unreachable.term 312 313unreachable.term: 314 call void @baz() 315 unreachable 316} 317 318define void @peel_exits_to_blocks_branch_to_unreachable_block_with_invariant_load(ptr %ptr, i32 %N, i32 %x, i1 %c.1, i32 %y, ptr %size_ptr) { 319; CHECK-LABEL: @peel_exits_to_blocks_branch_to_unreachable_block_with_invariant_load( 320; CHECK-NEXT: entry: 321; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 322; CHECK: loop.header: 323; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 324; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[Y:%.*]] 325; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 326; CHECK: then: 327; CHECK-NEXT: br i1 [[C_1:%.*]], label [[EXIT_1:%.*]], label [[LOOP_LATCH]] 328; CHECK: else: 329; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X:%.*]] 330; CHECK-NEXT: br i1 [[C_2]], label [[EXIT_2:%.*]], label [[LOOP_LATCH]] 331; CHECK: loop.latch: 332; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ] 333; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 334; CHECK-NEXT: store i32 [[M]], ptr [[GEP]], align 4 335; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 336; CHECK-NEXT: [[SIZE:%.*]] = load i32, ptr [[SIZE_PTR:%.*]], align 4 337; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV_NEXT]], [[SIZE]] 338; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]] 339; CHECK: exit: 340; CHECK-NEXT: ret void 341; CHECK: exit.1: 342; CHECK-NEXT: call void @foo() 343; CHECK-NEXT: br label [[UNREACHABLE_TERM:%.*]] 344; CHECK: exit.2: 345; CHECK-NEXT: call void @bar() 346; CHECK-NEXT: br label [[UNREACHABLE_TERM]] 347; CHECK: unreachable.term: 348; CHECK-NEXT: call void @baz() 349; CHECK-NEXT: unreachable 350; 351entry: 352 br label %loop.header 353 354loop.header: 355 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 356 %c = icmp ult i32 %iv, %y 357 br i1 %c, label %then, label %else 358 359then: 360 br i1 %c.1, label %exit.1, label %loop.latch 361 362else: 363 %c.2 = icmp eq i32 %iv, %x 364 br i1 %c.2, label %exit.2, label %loop.latch 365 366loop.latch: 367 %m = phi i32 [ 0, %then ], [ %x, %else ] 368 %gep = getelementptr i32, ptr %ptr, i32 %iv 369 store i32 %m, ptr %gep 370 %iv.next = add nuw nsw i32 %iv, 1 371 %size = load i32, ptr %size_ptr, align 4 372 %c.3 = icmp ult i32 %iv.next, %size 373 br i1 %c.3, label %loop.header, label %exit 374 375exit: 376 ret void 377 378exit.1: 379 call void @foo() 380 br label %unreachable.term 381 382exit.2: 383 call void @bar() 384 br label %unreachable.term 385 386unreachable.term: 387 call void @baz() 388 unreachable 389} 390 391define void @peel_exits_to_blocks_branch_to_unreachable_block_with_profile(ptr %ptr, i32 %N, i32 %x, i1 %c.1) !prof !0 { 392; CHECK-LABEL: @peel_exits_to_blocks_branch_to_unreachable_block_with_profile( 393; CHECK-NEXT: entry: 394; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 395; CHECK: loop.header: 396; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 397; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N:%.*]] 398; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]], !prof [[PROF5:![0-9]+]] 399; CHECK: then: 400; CHECK-NEXT: br i1 [[C_1:%.*]], label [[EXIT_1:%.*]], label [[LOOP_LATCH]] 401; CHECK: else: 402; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X:%.*]] 403; CHECK-NEXT: br i1 [[C_2]], label [[EXIT_2:%.*]], label [[LOOP_LATCH]] 404; CHECK: loop.latch: 405; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ] 406; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[PTR:%.*]], i32 [[IV]] 407; CHECK-NEXT: store i32 [[M]], ptr [[GEP]], align 4 408; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 409; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV_NEXT]], [[N]] 410; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]], !prof [[PROF5]] 411; CHECK: exit: 412; CHECK-NEXT: ret void 413; CHECK: exit.1: 414; CHECK-NEXT: call void @foo() 415; CHECK-NEXT: br label [[UNREACHABLE_TERM:%.*]] 416; CHECK: exit.2: 417; CHECK-NEXT: call void @bar() 418; CHECK-NEXT: br label [[UNREACHABLE_TERM]] 419; CHECK: unreachable.term: 420; CHECK-NEXT: call void @baz() 421; CHECK-NEXT: unreachable 422; 423entry: 424 br label %loop.header 425 426loop.header: 427 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 428 %c = icmp ult i32 %iv, %N 429 br i1 %c, label %then, label %else, !prof !1 430 431then: 432 br i1 %c.1, label %exit.1, label %loop.latch 433 434else: 435 %c.2 = icmp eq i32 %iv, %x 436 br i1 %c.2, label %exit.2, label %loop.latch 437 438loop.latch: 439 %m = phi i32 [ 0, %then ], [ %x, %else ] 440 %gep = getelementptr i32, ptr %ptr, i32 %iv 441 store i32 %m, ptr %gep 442 %iv.next = add nuw nsw i32 %iv, 1 443 %c.3 = icmp ult i32 %iv.next, %N 444 br i1 %c.3, label %loop.header, label %exit, !prof !2 445 446exit: 447 ret void 448 449exit.1: 450 call void @foo() 451 br label %unreachable.term 452 453exit.2: 454 call void @bar() 455 br label %unreachable.term 456 457unreachable.term: 458 call void @baz() 459 unreachable 460} 461 462declare void @bar() 463declare void @baz() 464 465!0 = !{!"function_entry_count", i64 32768} 466!1 = !{!"branch_weights", i32 0, i32 1} 467!2 = !{!"branch_weights", i32 0, i32 1} 468