1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -unroll-count=4 -verify-dom-info -S | FileCheck %s 3 4; REQUIRES: asserts 5; The tests below are for verifying dom tree after runtime unrolling 6; with multiple exit/exiting blocks. 7 8; We explicitly set the unroll count so that expensiveTripCount computation is allowed. 9 10declare i1 @unknown(i32) readonly nounwind willreturn 11 12; mergedexit block has edges from loop exit blocks. 13define i64 @test1() { 14; CHECK-LABEL: @test1( 15; CHECK-NEXT: entry: 16; CHECK-NEXT: br label [[PREHEADER:%.*]] 17; CHECK: preheader: 18; CHECK-NEXT: [[TRIP:%.*]] = zext i32 undef to i64 19; CHECK-NEXT: br label [[HEADER:%.*]] 20; CHECK: header: 21; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2, [[PREHEADER]] ], [ [[ADD_IV_3:%.*]], [[LATCH_3:%.*]] ] 22; CHECK-NEXT: [[ADD_IV:%.*]] = add nuw nsw i64 [[IV]], 2 23; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ADD_IV]], [[TRIP]] 24; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH:%.*]], label [[HEADEREXIT:%.*]] 25; CHECK: latch: 26; CHECK-NEXT: [[SHFT:%.*]] = ashr i64 [[ADD_IV]], 1 27; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[SHFT]], [[TRIP]] 28; CHECK-NEXT: br i1 [[CMP2]], label [[HEADER_1:%.*]], label [[LATCHEXIT:%.*]] 29; CHECK: header.1: 30; CHECK-NEXT: [[ADD_IV_1:%.*]] = add nuw nsw i64 [[ADD_IV]], 2 31; CHECK-NEXT: [[CMP1_1:%.*]] = icmp ult i64 [[ADD_IV_1]], [[TRIP]] 32; CHECK-NEXT: br i1 [[CMP1_1]], label [[LATCH_1:%.*]], label [[HEADEREXIT]] 33; CHECK: latch.1: 34; CHECK-NEXT: [[SHFT_1:%.*]] = ashr i64 [[ADD_IV_1]], 1 35; CHECK-NEXT: [[CMP2_1:%.*]] = icmp ult i64 [[SHFT_1]], [[TRIP]] 36; CHECK-NEXT: br i1 [[CMP2_1]], label [[HEADER_2:%.*]], label [[LATCHEXIT]] 37; CHECK: header.2: 38; CHECK-NEXT: [[ADD_IV_2:%.*]] = add nuw nsw i64 [[ADD_IV_1]], 2 39; CHECK-NEXT: [[CMP1_2:%.*]] = icmp ult i64 [[ADD_IV_2]], [[TRIP]] 40; CHECK-NEXT: br i1 [[CMP1_2]], label [[LATCH_2:%.*]], label [[HEADEREXIT]] 41; CHECK: latch.2: 42; CHECK-NEXT: [[SHFT_2:%.*]] = ashr i64 [[ADD_IV_2]], 1 43; CHECK-NEXT: [[CMP2_2:%.*]] = icmp ult i64 [[SHFT_2]], [[TRIP]] 44; CHECK-NEXT: br i1 [[CMP2_2]], label [[HEADER_3:%.*]], label [[LATCHEXIT]] 45; CHECK: header.3: 46; CHECK-NEXT: [[ADD_IV_3]] = add nuw nsw i64 [[ADD_IV_2]], 2 47; CHECK-NEXT: [[CMP1_3:%.*]] = icmp ult i64 [[ADD_IV_3]], [[TRIP]] 48; CHECK-NEXT: br i1 [[CMP1_3]], label [[LATCH_3]], label [[HEADEREXIT]] 49; CHECK: latch.3: 50; CHECK-NEXT: [[SHFT_3:%.*]] = ashr i64 [[ADD_IV_3]], 1 51; CHECK-NEXT: [[CMP2_3:%.*]] = icmp ult i64 [[SHFT_3]], [[TRIP]] 52; CHECK-NEXT: br i1 [[CMP2_3]], label [[HEADER]], label [[LATCHEXIT]], !llvm.loop [[LOOP0:![0-9]+]] 53; CHECK: headerexit: 54; CHECK-NEXT: [[ADDPHI:%.*]] = phi i64 [ [[ADD_IV]], [[HEADER]] ], [ [[ADD_IV_1]], [[HEADER_1]] ], [ [[ADD_IV_2]], [[HEADER_2]] ], [ [[ADD_IV_3]], [[HEADER_3]] ] 55; CHECK-NEXT: br label [[MERGEDEXIT:%.*]] 56; CHECK: latchexit: 57; CHECK-NEXT: [[SHFTPHI:%.*]] = phi i64 [ [[SHFT]], [[LATCH]] ], [ [[SHFT_1]], [[LATCH_1]] ], [ [[SHFT_2]], [[LATCH_2]] ], [ [[SHFT_3]], [[LATCH_3]] ] 58; CHECK-NEXT: br label [[MERGEDEXIT]] 59; CHECK: mergedexit: 60; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[ADDPHI]], [[HEADEREXIT]] ], [ [[SHFTPHI]], [[LATCHEXIT]] ] 61; CHECK-NEXT: ret i64 [[RETVAL]] 62; 63entry: 64 br label %preheader 65 66preheader: ; preds = %bb 67 %trip = zext i32 undef to i64 68 br label %header 69 70header: ; preds = %latch, %preheader 71 %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ] 72 %add.iv = add nuw nsw i64 %iv, 2 73 %cmp1 = icmp ult i64 %add.iv, %trip 74 br i1 %cmp1, label %latch, label %headerexit 75 76latch: ; preds = %header 77 %shft = ashr i64 %add.iv, 1 78 %cmp2 = icmp ult i64 %shft, %trip 79 br i1 %cmp2, label %header, label %latchexit 80 81headerexit: ; preds = %header 82 %addphi = phi i64 [ %add.iv, %header ] 83 br label %mergedexit 84 85latchexit: ; preds = %latch 86 %shftphi = phi i64 [ %shft, %latch ] 87 br label %mergedexit 88 89mergedexit: ; preds = %latchexit, %headerexit 90 %retval = phi i64 [ %addphi, %headerexit ], [ %shftphi, %latchexit ] 91 ret i64 %retval 92} 93 94; mergedexit has edges from loop exit blocks and a block outside the loop. 95define void @test2(i1 %cond, i32 %n) { 96; CHECK-LABEL: @test2( 97; CHECK-NEXT: entry: 98; CHECK-NEXT: br i1 [[COND:%.*]], label [[PREHEADER:%.*]], label [[MERGEDEXIT:%.*]] 99; CHECK: preheader: 100; CHECK-NEXT: [[TRIP:%.*]] = zext i32 [[N:%.*]] to i64 101; CHECK-NEXT: br label [[HEADER:%.*]] 102; CHECK: header: 103; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2, [[PREHEADER]] ], [ [[ADD_IV_3:%.*]], [[LATCH_3:%.*]] ] 104; CHECK-NEXT: [[ADD_IV:%.*]] = add nuw nsw i64 [[IV]], 2 105; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ADD_IV]], [[TRIP]] 106; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH:%.*]], label [[HEADEREXIT:%.*]] 107; CHECK: latch: 108; CHECK-NEXT: [[SHFT:%.*]] = ashr i64 [[ADD_IV]], 1 109; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[SHFT]], [[TRIP]] 110; CHECK-NEXT: br i1 [[CMP2]], label [[HEADER_1:%.*]], label [[LATCHEXIT:%.*]] 111; CHECK: header.1: 112; CHECK-NEXT: [[ADD_IV_1:%.*]] = add nuw nsw i64 [[ADD_IV]], 2 113; CHECK-NEXT: [[CMP1_1:%.*]] = icmp ult i64 [[ADD_IV_1]], [[TRIP]] 114; CHECK-NEXT: br i1 [[CMP1_1]], label [[LATCH_1:%.*]], label [[HEADEREXIT]] 115; CHECK: latch.1: 116; CHECK-NEXT: [[SHFT_1:%.*]] = ashr i64 [[ADD_IV_1]], 1 117; CHECK-NEXT: [[CMP2_1:%.*]] = icmp ult i64 [[SHFT_1]], [[TRIP]] 118; CHECK-NEXT: br i1 [[CMP2_1]], label [[HEADER_2:%.*]], label [[LATCHEXIT]] 119; CHECK: header.2: 120; CHECK-NEXT: [[ADD_IV_2:%.*]] = add nuw nsw i64 [[ADD_IV_1]], 2 121; CHECK-NEXT: [[CMP1_2:%.*]] = icmp ult i64 [[ADD_IV_2]], [[TRIP]] 122; CHECK-NEXT: br i1 [[CMP1_2]], label [[LATCH_2:%.*]], label [[HEADEREXIT]] 123; CHECK: latch.2: 124; CHECK-NEXT: [[SHFT_2:%.*]] = ashr i64 [[ADD_IV_2]], 1 125; CHECK-NEXT: [[CMP2_2:%.*]] = icmp ult i64 [[SHFT_2]], [[TRIP]] 126; CHECK-NEXT: br i1 [[CMP2_2]], label [[HEADER_3:%.*]], label [[LATCHEXIT]] 127; CHECK: header.3: 128; CHECK-NEXT: [[ADD_IV_3]] = add nuw nsw i64 [[ADD_IV_2]], 2 129; CHECK-NEXT: [[CMP1_3:%.*]] = icmp ult i64 [[ADD_IV_3]], [[TRIP]] 130; CHECK-NEXT: br i1 [[CMP1_3]], label [[LATCH_3]], label [[HEADEREXIT]] 131; CHECK: latch.3: 132; CHECK-NEXT: [[SHFT_3:%.*]] = ashr i64 [[ADD_IV_3]], 1 133; CHECK-NEXT: [[CMP2_3:%.*]] = icmp ult i64 [[SHFT_3]], [[TRIP]] 134; CHECK-NEXT: br i1 [[CMP2_3]], label [[HEADER]], label [[LATCHEXIT]], !llvm.loop [[LOOP2:![0-9]+]] 135; CHECK: headerexit: 136; CHECK-NEXT: br label [[MERGEDEXIT]] 137; CHECK: latchexit: 138; CHECK-NEXT: br label [[MERGEDEXIT]] 139; CHECK: mergedexit: 140; CHECK-NEXT: ret void 141; 142entry: 143 br i1 %cond, label %preheader, label %mergedexit 144 145preheader: ; preds = %entry 146 %trip = zext i32 %n to i64 147 br label %header 148 149header: ; preds = %latch, %preheader 150 %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ] 151 %add.iv = add nuw nsw i64 %iv, 2 152 %cmp1 = icmp ult i64 %add.iv, %trip 153 br i1 %cmp1, label %latch, label %headerexit 154 155latch: ; preds = %header 156 %shft = ashr i64 %add.iv, 1 157 %cmp2 = icmp ult i64 %shft, %trip 158 br i1 %cmp2, label %header, label %latchexit 159 160headerexit: ; preds = %header 161 br label %mergedexit 162 163latchexit: ; preds = %latch 164 br label %mergedexit 165 166mergedexit: ; preds = %latchexit, %headerexit, %entry 167 ret void 168} 169 170 171; exitsucc is from loop exit block only. 172define i64 @test3(i32 %n) { 173; CHECK-LABEL: @test3( 174; CHECK-NEXT: entry: 175; CHECK-NEXT: br label [[PREHEADER:%.*]] 176; CHECK: preheader: 177; CHECK-NEXT: [[TRIP:%.*]] = zext i32 [[N:%.*]] to i64 178; CHECK-NEXT: br label [[HEADER:%.*]] 179; CHECK: header: 180; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 2, [[PREHEADER]] ], [ [[ADD_IV_3:%.*]], [[LATCH_3:%.*]] ] 181; CHECK-NEXT: [[ADD_IV:%.*]] = add nuw nsw i64 [[IV]], 2 182; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[ADD_IV]], [[TRIP]] 183; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH:%.*]], label [[HEADEREXIT:%.*]] 184; CHECK: latch: 185; CHECK-NEXT: [[SHFT:%.*]] = ashr i64 [[ADD_IV]], 1 186; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[SHFT]], [[TRIP]] 187; CHECK-NEXT: br i1 [[CMP2]], label [[HEADER_1:%.*]], label [[LATCHEXIT:%.*]] 188; CHECK: header.1: 189; CHECK-NEXT: [[ADD_IV_1:%.*]] = add nuw nsw i64 [[ADD_IV]], 2 190; CHECK-NEXT: [[CMP1_1:%.*]] = icmp ult i64 [[ADD_IV_1]], [[TRIP]] 191; CHECK-NEXT: br i1 [[CMP1_1]], label [[LATCH_1:%.*]], label [[HEADEREXIT]] 192; CHECK: latch.1: 193; CHECK-NEXT: [[SHFT_1:%.*]] = ashr i64 [[ADD_IV_1]], 1 194; CHECK-NEXT: [[CMP2_1:%.*]] = icmp ult i64 [[SHFT_1]], [[TRIP]] 195; CHECK-NEXT: br i1 [[CMP2_1]], label [[HEADER_2:%.*]], label [[LATCHEXIT]] 196; CHECK: header.2: 197; CHECK-NEXT: [[ADD_IV_2:%.*]] = add nuw nsw i64 [[ADD_IV_1]], 2 198; CHECK-NEXT: [[CMP1_2:%.*]] = icmp ult i64 [[ADD_IV_2]], [[TRIP]] 199; CHECK-NEXT: br i1 [[CMP1_2]], label [[LATCH_2:%.*]], label [[HEADEREXIT]] 200; CHECK: latch.2: 201; CHECK-NEXT: [[SHFT_2:%.*]] = ashr i64 [[ADD_IV_2]], 1 202; CHECK-NEXT: [[CMP2_2:%.*]] = icmp ult i64 [[SHFT_2]], [[TRIP]] 203; CHECK-NEXT: br i1 [[CMP2_2]], label [[HEADER_3:%.*]], label [[LATCHEXIT]] 204; CHECK: header.3: 205; CHECK-NEXT: [[ADD_IV_3]] = add nuw nsw i64 [[ADD_IV_2]], 2 206; CHECK-NEXT: [[CMP1_3:%.*]] = icmp ult i64 [[ADD_IV_3]], [[TRIP]] 207; CHECK-NEXT: br i1 [[CMP1_3]], label [[LATCH_3]], label [[HEADEREXIT]] 208; CHECK: latch.3: 209; CHECK-NEXT: [[SHFT_3:%.*]] = ashr i64 [[ADD_IV_3]], 1 210; CHECK-NEXT: [[CMP2_3:%.*]] = icmp ult i64 [[SHFT_3]], [[TRIP]] 211; CHECK-NEXT: br i1 [[CMP2_3]], label [[HEADER]], label [[LATCHEXIT]], !llvm.loop [[LOOP3:![0-9]+]] 212; CHECK: headerexit: 213; CHECK-NEXT: br label [[EXITSUCC:%.*]] 214; CHECK: latchexit: 215; CHECK-NEXT: [[SHFTPHI:%.*]] = phi i64 [ [[SHFT]], [[LATCH]] ], [ [[SHFT_1]], [[LATCH_1]] ], [ [[SHFT_2]], [[LATCH_2]] ], [ [[SHFT_3]], [[LATCH_3]] ] 216; CHECK-NEXT: ret i64 [[SHFTPHI]] 217; CHECK: exitsucc: 218; CHECK-NEXT: ret i64 96 219; 220entry: 221 br label %preheader 222 223preheader: ; preds = %bb 224 %trip = zext i32 %n to i64 225 br label %header 226 227header: ; preds = %latch, %preheader 228 %iv = phi i64 [ 2, %preheader ], [ %add.iv, %latch ] 229 %add.iv = add nuw nsw i64 %iv, 2 230 %cmp1 = icmp ult i64 %add.iv, %trip 231 br i1 %cmp1, label %latch, label %headerexit 232 233latch: ; preds = %header 234 %shft = ashr i64 %add.iv, 1 235 %cmp2 = icmp ult i64 %shft, %trip 236 br i1 %cmp2, label %header, label %latchexit 237 238headerexit: ; preds = %header 239 br label %exitsucc 240 241latchexit: ; preds = %latch 242 %shftphi = phi i64 [ %shft, %latch ] 243 ret i64 %shftphi 244 245exitsucc: ; preds = %headerexit 246 ret i64 96 247} 248 249; exit block (%default) has an exiting block and another exit block as predecessors. 250define void @test4(i16 %c3) { 251; CHECK-LABEL: @test4( 252; CHECK-NEXT: preheader: 253; CHECK-NEXT: [[C1:%.*]] = zext i32 undef to i64 254; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[C1]], i64 1) 255; CHECK-NEXT: [[TMP0:%.*]] = freeze i64 [[UMAX]] 256; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], -1 257; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP0]], 3 258; CHECK-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 259; CHECK-NEXT: br i1 [[LCMP_MOD]], label [[HEADER_PROL_PREHEADER:%.*]], label [[HEADER_PROL_LOOPEXIT:%.*]] 260; CHECK: header.prol.preheader: 261; CHECK-NEXT: br label [[HEADER_PROL:%.*]] 262; CHECK: header.prol: 263; CHECK-NEXT: [[INDVARS_IV_PROL:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[INDVARS_IV_NEXT_PROL:%.*]], [[LATCH_PROL:%.*]] ] 264; CHECK-NEXT: [[PROL_ITER:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_NEXT:%.*]], [[LATCH_PROL]] ] 265; CHECK-NEXT: br label [[EXITING_PROL:%.*]] 266; CHECK: exiting.prol: 267; CHECK-NEXT: switch i16 [[C3:%.*]], label [[DEFAULT_LOOPEXIT_LOOPEXIT1:%.*]] [ 268; CHECK-NEXT: i16 45, label [[OTHEREXIT_LOOPEXIT2:%.*]] 269; CHECK-NEXT: i16 95, label [[LATCH_PROL]] 270; CHECK-NEXT: ] 271; CHECK: latch.prol: 272; CHECK-NEXT: [[INDVARS_IV_NEXT_PROL]] = add nuw nsw i64 [[INDVARS_IV_PROL]], 1 273; CHECK-NEXT: [[C2_PROL:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_PROL]], [[C1]] 274; CHECK-NEXT: [[PROL_ITER_NEXT]] = add i64 [[PROL_ITER]], 1 275; CHECK-NEXT: [[PROL_ITER_CMP:%.*]] = icmp ne i64 [[PROL_ITER_NEXT]], [[XTRAITER]] 276; CHECK-NEXT: br i1 [[PROL_ITER_CMP]], label [[HEADER_PROL]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP4:![0-9]+]] 277; CHECK: header.prol.loopexit.unr-lcssa: 278; CHECK-NEXT: [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PROL]], [[LATCH_PROL]] ] 279; CHECK-NEXT: br label [[HEADER_PROL_LOOPEXIT]] 280; CHECK: header.prol.loopexit: 281; CHECK-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ 0, [[PREHEADER:%.*]] ], [ [[INDVARS_IV_UNR_PH]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] 282; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], 3 283; CHECK-NEXT: br i1 [[TMP2]], label [[LATCHEXIT:%.*]], label [[PREHEADER_NEW:%.*]] 284; CHECK: preheader.new: 285; CHECK-NEXT: br label [[HEADER:%.*]] 286; CHECK: header: 287; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_UNR]], [[PREHEADER_NEW]] ], [ [[INDVARS_IV_NEXT_3:%.*]], [[LATCH_3:%.*]] ] 288; CHECK-NEXT: br label [[EXITING:%.*]] 289; CHECK: exiting: 290; CHECK-NEXT: switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT:%.*]] [ 291; CHECK-NEXT: i16 45, label [[OTHEREXIT_LOOPEXIT:%.*]] 292; CHECK-NEXT: i16 95, label [[LATCH:%.*]] 293; CHECK-NEXT: ] 294; CHECK: latch: 295; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 296; CHECK-NEXT: br label [[EXITING_1:%.*]] 297; CHECK: exiting.1: 298; CHECK-NEXT: switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT]] [ 299; CHECK-NEXT: i16 45, label [[OTHEREXIT_LOOPEXIT]] 300; CHECK-NEXT: i16 95, label [[LATCH_1:%.*]] 301; CHECK-NEXT: ] 302; CHECK: latch.1: 303; CHECK-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT]], 1 304; CHECK-NEXT: br label [[EXITING_2:%.*]] 305; CHECK: exiting.2: 306; CHECK-NEXT: switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT]] [ 307; CHECK-NEXT: i16 45, label [[OTHEREXIT_LOOPEXIT]] 308; CHECK-NEXT: i16 95, label [[LATCH_2:%.*]] 309; CHECK-NEXT: ] 310; CHECK: latch.2: 311; CHECK-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_1]], 1 312; CHECK-NEXT: br label [[EXITING_3:%.*]] 313; CHECK: exiting.3: 314; CHECK-NEXT: switch i16 [[C3]], label [[DEFAULT_LOOPEXIT_LOOPEXIT]] [ 315; CHECK-NEXT: i16 45, label [[OTHEREXIT_LOOPEXIT]] 316; CHECK-NEXT: i16 95, label [[LATCH_3]] 317; CHECK-NEXT: ] 318; CHECK: latch.3: 319; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nuw nsw i64 [[INDVARS_IV_NEXT_2]], 1 320; CHECK-NEXT: [[C2_3:%.*]] = icmp ult i64 [[INDVARS_IV_NEXT_3]], [[C1]] 321; CHECK-NEXT: br i1 [[C2_3]], label [[HEADER]], label [[LATCHEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP5:![0-9]+]] 322; CHECK: latchexit.unr-lcssa: 323; CHECK-NEXT: br label [[LATCHEXIT]] 324; CHECK: latchexit: 325; CHECK-NEXT: ret void 326; CHECK: default.loopexit.loopexit: 327; CHECK-NEXT: br label [[DEFAULT_LOOPEXIT:%.*]] 328; CHECK: default.loopexit.loopexit1: 329; CHECK-NEXT: br label [[DEFAULT_LOOPEXIT]] 330; CHECK: default.loopexit: 331; CHECK-NEXT: br label [[DEFAULT:%.*]] 332; CHECK: default: 333; CHECK-NEXT: ret void 334; CHECK: otherexit.loopexit: 335; CHECK-NEXT: br label [[OTHEREXIT:%.*]] 336; CHECK: otherexit.loopexit2: 337; CHECK-NEXT: br label [[OTHEREXIT]] 338; CHECK: otherexit: 339; CHECK-NEXT: br label [[DEFAULT]] 340; 341preheader: 342 %c1 = zext i32 undef to i64 343 br label %header 344 345header: ; preds = %latch, %preheader 346 %indvars.iv = phi i64 [ 0, %preheader ], [ %indvars.iv.next, %latch ] 347 br label %exiting 348 349exiting: ; preds = %header 350 switch i16 %c3, label %default [ 351 i16 45, label %otherexit 352 i16 95, label %latch 353 ] 354 355latch: ; preds = %exiting 356 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 357 %c2 = icmp ult i64 %indvars.iv.next, %c1 358 br i1 %c2, label %header, label %latchexit 359 360latchexit: ; preds = %latch 361 ret void 362 363default: ; preds = %otherexit, %exiting 364 ret void 365 366otherexit: ; preds = %exiting 367 br label %default 368} 369 370; exit block (%exitB) has an exiting block and another exit block as predecessors. 371; exiting block comes from inner loop. 372define void @test5() { 373; CHECK-LABEL: @test5( 374; CHECK-NEXT: bb: 375; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i32 undef, 79 376; CHECK-NEXT: br i1 [[TMP]], label [[OUTERLATCHEXIT:%.*]], label [[BB1:%.*]] 377; CHECK: bb1: 378; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 undef 379; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], -1 380; CHECK-NEXT: [[XTRAITER:%.*]] = and i32 [[TMP0]], 3 381; CHECK-NEXT: [[LCMP_MOD:%.*]] = icmp ne i32 [[XTRAITER]], 0 382; CHECK-NEXT: br i1 [[LCMP_MOD]], label [[OUTERH_PROL_PREHEADER:%.*]], label [[OUTERH_PROL_LOOPEXIT:%.*]] 383; CHECK: outerH.prol.preheader: 384; CHECK-NEXT: br label [[OUTERH_PROL:%.*]] 385; CHECK: outerH.prol: 386; CHECK-NEXT: [[TMP4_PROL:%.*]] = phi i32 [ [[TMP6_PROL:%.*]], [[OUTERLATCH_PROL:%.*]] ], [ undef, [[OUTERH_PROL_PREHEADER]] ] 387; CHECK-NEXT: [[PROL_ITER:%.*]] = phi i32 [ 0, [[OUTERH_PROL_PREHEADER]] ], [ [[PROL_ITER_NEXT:%.*]], [[OUTERLATCH_PROL]] ] 388; CHECK-NEXT: br label [[INNERH_PROL:%.*]] 389; CHECK: innerH.prol: 390; CHECK-NEXT: [[C1_PROL:%.*]] = call i1 @unknown(i32 0) 391; CHECK-NEXT: br i1 [[C1_PROL]], label [[INNEREXITING_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1:%.*]] 392; CHECK: innerexiting.prol: 393; CHECK-NEXT: [[C2_PROL:%.*]] = call i1 @unknown(i32 0) 394; CHECK-NEXT: br i1 [[C2_PROL]], label [[INNERLATCH_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2:%.*]] 395; CHECK: innerLatch.prol: 396; CHECK-NEXT: br i1 false, label [[INNERH_1_PROL:%.*]], label [[OUTERLATCH_PROL]] 397; CHECK: innerH.1.prol: 398; CHECK-NEXT: [[C1_1_PROL:%.*]] = call i1 @unknown(i32 0) 399; CHECK-NEXT: br i1 [[C1_1_PROL]], label [[INNEREXITING_1_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1]] 400; CHECK: innerexiting.1.prol: 401; CHECK-NEXT: [[C2_1_PROL:%.*]] = call i1 @unknown(i32 0) 402; CHECK-NEXT: br i1 [[C2_1_PROL]], label [[INNERLATCH_1_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2]] 403; CHECK: innerLatch.1.prol: 404; CHECK-NEXT: br i1 false, label [[INNERH_2_PROL:%.*]], label [[OUTERLATCH_PROL]] 405; CHECK: innerH.2.prol: 406; CHECK-NEXT: [[C1_2_PROL:%.*]] = call i1 @unknown(i32 0) 407; CHECK-NEXT: br i1 [[C1_2_PROL]], label [[INNEREXITING_2_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1]] 408; CHECK: innerexiting.2.prol: 409; CHECK-NEXT: [[C2_2_PROL:%.*]] = call i1 @unknown(i32 0) 410; CHECK-NEXT: br i1 [[C2_2_PROL]], label [[INNERLATCH_2_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2]] 411; CHECK: innerLatch.2.prol: 412; CHECK-NEXT: br i1 false, label [[INNERH_3_PROL:%.*]], label [[OUTERLATCH_PROL]] 413; CHECK: innerH.3.prol: 414; CHECK-NEXT: [[C1_3_PROL:%.*]] = call i1 @unknown(i32 0) 415; CHECK-NEXT: br i1 [[C1_3_PROL]], label [[INNEREXITING_3_PROL:%.*]], label [[OTHEREXITB_LOOPEXIT1]] 416; CHECK: innerexiting.3.prol: 417; CHECK-NEXT: [[C2_3_PROL:%.*]] = call i1 @unknown(i32 0) 418; CHECK-NEXT: br i1 [[C2_3_PROL]], label [[INNERLATCH_3_PROL:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT2]] 419; CHECK: innerLatch.3.prol: 420; CHECK-NEXT: br i1 false, label [[INNERH_PROL]], label [[OUTERLATCH_PROL]], !llvm.loop [[LOOP6:![0-9]+]] 421; CHECK: outerLatch.prol: 422; CHECK-NEXT: [[TMP6_PROL]] = add i32 [[TMP4_PROL]], 1 423; CHECK-NEXT: [[TMP7_PROL:%.*]] = icmp sgt i32 [[TMP6_PROL]], 79 424; CHECK-NEXT: [[PROL_ITER_NEXT]] = add i32 [[PROL_ITER]], 1 425; CHECK-NEXT: [[PROL_ITER_CMP:%.*]] = icmp ne i32 [[PROL_ITER_NEXT]], [[XTRAITER]] 426; CHECK-NEXT: br i1 [[PROL_ITER_CMP]], label [[OUTERH_PROL]], label [[OUTERH_PROL_LOOPEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP7:![0-9]+]] 427; CHECK: outerH.prol.loopexit.unr-lcssa: 428; CHECK-NEXT: [[TMP4_UNR_PH:%.*]] = phi i32 [ [[TMP6_PROL]], [[OUTERLATCH_PROL]] ] 429; CHECK-NEXT: br label [[OUTERH_PROL_LOOPEXIT]] 430; CHECK: outerH.prol.loopexit: 431; CHECK-NEXT: [[TMP4_UNR:%.*]] = phi i32 [ undef, [[BB1]] ], [ [[TMP4_UNR_PH]], [[OUTERH_PROL_LOOPEXIT_UNR_LCSSA]] ] 432; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3 433; CHECK-NEXT: br i1 [[TMP2]], label [[OUTERLATCHEXIT_LOOPEXIT:%.*]], label [[BB1_NEW:%.*]] 434; CHECK: bb1.new: 435; CHECK-NEXT: br label [[OUTERH:%.*]] 436; CHECK: outerH: 437; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP4_UNR]], [[BB1_NEW]] ], [ [[TMP6_3:%.*]], [[OUTERLATCH_3:%.*]] ] 438; CHECK-NEXT: br label [[INNERH:%.*]] 439; CHECK: innerH: 440; CHECK-NEXT: [[C1:%.*]] = call i1 @unknown(i32 0) 441; CHECK-NEXT: br i1 [[C1]], label [[INNEREXITING:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT:%.*]] 442; CHECK: innerexiting: 443; CHECK-NEXT: [[C2:%.*]] = call i1 @unknown(i32 0) 444; CHECK-NEXT: br i1 [[C2]], label [[INNERLATCH:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT:%.*]] 445; CHECK: innerLatch: 446; CHECK-NEXT: br i1 false, label [[INNERH_1:%.*]], label [[OUTERLATCH:%.*]] 447; CHECK: innerH.1: 448; CHECK-NEXT: [[C1_1:%.*]] = call i1 @unknown(i32 0) 449; CHECK-NEXT: br i1 [[C1_1]], label [[INNEREXITING_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT]] 450; CHECK: innerexiting.1: 451; CHECK-NEXT: [[C2_1:%.*]] = call i1 @unknown(i32 0) 452; CHECK-NEXT: br i1 [[C2_1]], label [[INNERLATCH_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT]] 453; CHECK: innerLatch.1: 454; CHECK-NEXT: br i1 false, label [[INNERH_2:%.*]], label [[OUTERLATCH]] 455; CHECK: innerH.2: 456; CHECK-NEXT: [[C1_2:%.*]] = call i1 @unknown(i32 0) 457; CHECK-NEXT: br i1 [[C1_2]], label [[INNEREXITING_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT]] 458; CHECK: innerexiting.2: 459; CHECK-NEXT: [[C2_2:%.*]] = call i1 @unknown(i32 0) 460; CHECK-NEXT: br i1 [[C2_2]], label [[INNERLATCH_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT]] 461; CHECK: innerLatch.2: 462; CHECK-NEXT: br i1 false, label [[INNERH_3:%.*]], label [[OUTERLATCH]] 463; CHECK: innerH.3: 464; CHECK-NEXT: [[C1_3:%.*]] = call i1 @unknown(i32 0) 465; CHECK-NEXT: br i1 [[C1_3]], label [[INNEREXITING_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT]] 466; CHECK: innerexiting.3: 467; CHECK-NEXT: [[C2_3:%.*]] = call i1 @unknown(i32 0) 468; CHECK-NEXT: br i1 [[C2_3]], label [[INNERLATCH_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT]] 469; CHECK: innerLatch.3: 470; CHECK-NEXT: br i1 false, label [[INNERH]], label [[OUTERLATCH]], !llvm.loop [[LOOP6]] 471; CHECK: outerLatch: 472; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP4]], 1 473; CHECK-NEXT: br label [[INNERH_14:%.*]] 474; CHECK: innerH.14: 475; CHECK-NEXT: [[C1_13:%.*]] = call i1 @unknown(i32 0) 476; CHECK-NEXT: br i1 [[C1_13]], label [[INNEREXITING_16:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18:%.*]] 477; CHECK: innerexiting.16: 478; CHECK-NEXT: [[C2_15:%.*]] = call i1 @unknown(i32 0) 479; CHECK-NEXT: br i1 [[C2_15]], label [[INNERLATCH_17:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19:%.*]] 480; CHECK: innerLatch.17: 481; CHECK-NEXT: br i1 false, label [[INNERH_1_1:%.*]], label [[OUTERLATCH_1:%.*]] 482; CHECK: innerH.1.1: 483; CHECK-NEXT: [[C1_1_1:%.*]] = call i1 @unknown(i32 0) 484; CHECK-NEXT: br i1 [[C1_1_1]], label [[INNEREXITING_1_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18]] 485; CHECK: innerexiting.1.1: 486; CHECK-NEXT: [[C2_1_1:%.*]] = call i1 @unknown(i32 0) 487; CHECK-NEXT: br i1 [[C2_1_1]], label [[INNERLATCH_1_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19]] 488; CHECK: innerLatch.1.1: 489; CHECK-NEXT: br i1 false, label [[INNERH_2_1:%.*]], label [[OUTERLATCH_1]] 490; CHECK: innerH.2.1: 491; CHECK-NEXT: [[C1_2_1:%.*]] = call i1 @unknown(i32 0) 492; CHECK-NEXT: br i1 [[C1_2_1]], label [[INNEREXITING_2_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18]] 493; CHECK: innerexiting.2.1: 494; CHECK-NEXT: [[C2_2_1:%.*]] = call i1 @unknown(i32 0) 495; CHECK-NEXT: br i1 [[C2_2_1]], label [[INNERLATCH_2_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19]] 496; CHECK: innerLatch.2.1: 497; CHECK-NEXT: br i1 false, label [[INNERH_3_1:%.*]], label [[OUTERLATCH_1]] 498; CHECK: innerH.3.1: 499; CHECK-NEXT: [[C1_3_1:%.*]] = call i1 @unknown(i32 0) 500; CHECK-NEXT: br i1 [[C1_3_1]], label [[INNEREXITING_3_1:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT18]] 501; CHECK: innerexiting.3.1: 502; CHECK-NEXT: [[C2_3_1:%.*]] = call i1 @unknown(i32 0) 503; CHECK-NEXT: br i1 [[C2_3_1]], label [[INNERLATCH_3_1:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT19]] 504; CHECK: innerLatch.3.1: 505; CHECK-NEXT: br i1 false, label [[INNERH_14]], label [[OUTERLATCH_1]], !llvm.loop [[LOOP6]] 506; CHECK: outerLatch.1: 507; CHECK-NEXT: [[TMP6_1:%.*]] = add i32 [[TMP6]], 1 508; CHECK-NEXT: br label [[INNERH_29:%.*]] 509; CHECK: innerH.29: 510; CHECK-NEXT: [[C1_28:%.*]] = call i1 @unknown(i32 0) 511; CHECK-NEXT: br i1 [[C1_28]], label [[INNEREXITING_211:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20:%.*]] 512; CHECK: innerexiting.211: 513; CHECK-NEXT: [[C2_210:%.*]] = call i1 @unknown(i32 0) 514; CHECK-NEXT: br i1 [[C2_210]], label [[INNERLATCH_212:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21:%.*]] 515; CHECK: innerLatch.212: 516; CHECK-NEXT: br i1 false, label [[INNERH_1_2:%.*]], label [[OUTERLATCH_2:%.*]] 517; CHECK: innerH.1.2: 518; CHECK-NEXT: [[C1_1_2:%.*]] = call i1 @unknown(i32 0) 519; CHECK-NEXT: br i1 [[C1_1_2]], label [[INNEREXITING_1_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20]] 520; CHECK: innerexiting.1.2: 521; CHECK-NEXT: [[C2_1_2:%.*]] = call i1 @unknown(i32 0) 522; CHECK-NEXT: br i1 [[C2_1_2]], label [[INNERLATCH_1_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21]] 523; CHECK: innerLatch.1.2: 524; CHECK-NEXT: br i1 false, label [[INNERH_2_2:%.*]], label [[OUTERLATCH_2]] 525; CHECK: innerH.2.2: 526; CHECK-NEXT: [[C1_2_2:%.*]] = call i1 @unknown(i32 0) 527; CHECK-NEXT: br i1 [[C1_2_2]], label [[INNEREXITING_2_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20]] 528; CHECK: innerexiting.2.2: 529; CHECK-NEXT: [[C2_2_2:%.*]] = call i1 @unknown(i32 0) 530; CHECK-NEXT: br i1 [[C2_2_2]], label [[INNERLATCH_2_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21]] 531; CHECK: innerLatch.2.2: 532; CHECK-NEXT: br i1 false, label [[INNERH_3_2:%.*]], label [[OUTERLATCH_2]] 533; CHECK: innerH.3.2: 534; CHECK-NEXT: [[C1_3_2:%.*]] = call i1 @unknown(i32 0) 535; CHECK-NEXT: br i1 [[C1_3_2]], label [[INNEREXITING_3_2:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT20]] 536; CHECK: innerexiting.3.2: 537; CHECK-NEXT: [[C2_3_2:%.*]] = call i1 @unknown(i32 0) 538; CHECK-NEXT: br i1 [[C2_3_2]], label [[INNERLATCH_3_2:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT21]] 539; CHECK: innerLatch.3.2: 540; CHECK-NEXT: br i1 false, label [[INNERH_29]], label [[OUTERLATCH_2]], !llvm.loop [[LOOP6]] 541; CHECK: outerLatch.2: 542; CHECK-NEXT: [[TMP6_2:%.*]] = add i32 [[TMP6_1]], 1 543; CHECK-NEXT: br label [[INNERH_314:%.*]] 544; CHECK: innerH.314: 545; CHECK-NEXT: [[C1_313:%.*]] = call i1 @unknown(i32 0) 546; CHECK-NEXT: br i1 [[C1_313]], label [[INNEREXITING_316:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22:%.*]] 547; CHECK: innerexiting.316: 548; CHECK-NEXT: [[C2_315:%.*]] = call i1 @unknown(i32 0) 549; CHECK-NEXT: br i1 [[C2_315]], label [[INNERLATCH_317:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23:%.*]] 550; CHECK: innerLatch.317: 551; CHECK-NEXT: br i1 false, label [[INNERH_1_3:%.*]], label [[OUTERLATCH_3]] 552; CHECK: innerH.1.3: 553; CHECK-NEXT: [[C1_1_3:%.*]] = call i1 @unknown(i32 0) 554; CHECK-NEXT: br i1 [[C1_1_3]], label [[INNEREXITING_1_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22]] 555; CHECK: innerexiting.1.3: 556; CHECK-NEXT: [[C2_1_3:%.*]] = call i1 @unknown(i32 0) 557; CHECK-NEXT: br i1 [[C2_1_3]], label [[INNERLATCH_1_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23]] 558; CHECK: innerLatch.1.3: 559; CHECK-NEXT: br i1 false, label [[INNERH_2_3:%.*]], label [[OUTERLATCH_3]] 560; CHECK: innerH.2.3: 561; CHECK-NEXT: [[C1_2_3:%.*]] = call i1 @unknown(i32 0) 562; CHECK-NEXT: br i1 [[C1_2_3]], label [[INNEREXITING_2_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22]] 563; CHECK: innerexiting.2.3: 564; CHECK-NEXT: [[C2_2_3:%.*]] = call i1 @unknown(i32 0) 565; CHECK-NEXT: br i1 [[C2_2_3]], label [[INNERLATCH_2_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23]] 566; CHECK: innerLatch.2.3: 567; CHECK-NEXT: br i1 false, label [[INNERH_3_3:%.*]], label [[OUTERLATCH_3]] 568; CHECK: innerH.3.3: 569; CHECK-NEXT: [[C1_3_3:%.*]] = call i1 @unknown(i32 0) 570; CHECK-NEXT: br i1 [[C1_3_3]], label [[INNEREXITING_3_3:%.*]], label [[OTHEREXITB_LOOPEXIT_LOOPEXIT22]] 571; CHECK: innerexiting.3.3: 572; CHECK-NEXT: [[C2_3_3:%.*]] = call i1 @unknown(i32 0) 573; CHECK-NEXT: br i1 [[C2_3_3]], label [[INNERLATCH_3_3:%.*]], label [[EXITB_LOOPEXIT_LOOPEXIT_LOOPEXIT23]] 574; CHECK: innerLatch.3.3: 575; CHECK-NEXT: br i1 false, label [[INNERH_314]], label [[OUTERLATCH_3]], !llvm.loop [[LOOP6]] 576; CHECK: outerLatch.3: 577; CHECK-NEXT: [[TMP6_3]] = add i32 [[TMP6_2]], 1 578; CHECK-NEXT: [[TMP7_3:%.*]] = icmp sgt i32 [[TMP6_3]], 79 579; CHECK-NEXT: br i1 [[TMP7_3]], label [[OUTERLATCHEXIT_LOOPEXIT_UNR_LCSSA:%.*]], label [[OUTERH]], !llvm.loop [[LOOP8:![0-9]+]] 580; CHECK: outerLatchExit.loopexit.unr-lcssa: 581; CHECK-NEXT: br label [[OUTERLATCHEXIT_LOOPEXIT]] 582; CHECK: outerLatchExit.loopexit: 583; CHECK-NEXT: br label [[OUTERLATCHEXIT]] 584; CHECK: outerLatchExit: 585; CHECK-NEXT: ret void 586; CHECK: exitB.loopexit.loopexit.loopexit: 587; CHECK-NEXT: br label [[EXITB_LOOPEXIT_LOOPEXIT:%.*]] 588; CHECK: exitB.loopexit.loopexit.loopexit19: 589; CHECK-NEXT: br label [[EXITB_LOOPEXIT_LOOPEXIT]] 590; CHECK: exitB.loopexit.loopexit.loopexit21: 591; CHECK-NEXT: br label [[EXITB_LOOPEXIT_LOOPEXIT]] 592; CHECK: exitB.loopexit.loopexit.loopexit23: 593; CHECK-NEXT: br label [[EXITB_LOOPEXIT_LOOPEXIT]] 594; CHECK: exitB.loopexit.loopexit: 595; CHECK-NEXT: br label [[EXITB_LOOPEXIT:%.*]] 596; CHECK: exitB.loopexit.loopexit2: 597; CHECK-NEXT: br label [[EXITB_LOOPEXIT]] 598; CHECK: exitB.loopexit: 599; CHECK-NEXT: br label [[EXITB:%.*]] 600; CHECK: exitB: 601; CHECK-NEXT: ret void 602; CHECK: otherexitB.loopexit.loopexit: 603; CHECK-NEXT: br label [[OTHEREXITB_LOOPEXIT:%.*]] 604; CHECK: otherexitB.loopexit.loopexit18: 605; CHECK-NEXT: br label [[OTHEREXITB_LOOPEXIT]] 606; CHECK: otherexitB.loopexit.loopexit20: 607; CHECK-NEXT: br label [[OTHEREXITB_LOOPEXIT]] 608; CHECK: otherexitB.loopexit.loopexit22: 609; CHECK-NEXT: br label [[OTHEREXITB_LOOPEXIT]] 610; CHECK: otherexitB.loopexit: 611; CHECK-NEXT: br label [[OTHEREXITB:%.*]] 612; CHECK: otherexitB.loopexit1: 613; CHECK-NEXT: br label [[OTHEREXITB]] 614; CHECK: otherexitB: 615; CHECK-NEXT: br label [[EXITB]] 616; 617bb: 618 %tmp = icmp sgt i32 undef, 79 619 br i1 %tmp, label %outerLatchExit, label %bb1 620 621bb1: ; preds = %bb 622 br label %outerH 623 624outerH: ; preds = %outerLatch, %bb1 625 %tmp4 = phi i32 [ %tmp6, %outerLatch ], [ undef, %bb1 ] 626 br label %innerH 627 628innerH: ; preds = %innerLatch, %outerH 629 %c1 = call i1 @unknown(i32 0) 630 br i1 %c1, label %innerexiting, label %otherexitB 631 632innerexiting: ; preds = %innerH 633 %c2 = call i1 @unknown(i32 0) 634 br i1 %c2, label %innerLatch, label %exitB 635 636innerLatch: ; preds = %innerexiting 637 %tmp13 = fcmp olt double undef, 2.000000e+00 638 br i1 %tmp13, label %innerH, label %outerLatch 639 640outerLatch: ; preds = %innerLatch 641 %tmp6 = add i32 %tmp4, 1 642 %tmp7 = icmp sgt i32 %tmp6, 79 643 br i1 %tmp7, label %outerLatchExit, label %outerH 644 645outerLatchExit: ; preds = %outerLatch, %bb 646 ret void 647 648exitB: ; preds = %innerexiting, %otherexitB 649 ret void 650 651otherexitB: ; preds = %innerH 652 br label %exitB 653 654} 655 656; Blocks reachable from exits (not_zero44) have the IDom as the block within the loop (Header). 657; Update the IDom to the preheader. 658define void @test6(i64 %start) { 659; CHECK-LABEL: @test6( 660; CHECK-NEXT: entry: 661; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[START:%.*]], 2 662; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 616) 663; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[SMAX]], -1 664; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[TMP1]], [[START]] 665; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 1 666; CHECK-NEXT: [[TMP4:%.*]] = add nuw i64 [[TMP3]], 1 667; CHECK-NEXT: [[TMP5:%.*]] = freeze i64 [[TMP4]] 668; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], -1 669; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP5]], 3 670; CHECK-NEXT: [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0 671; CHECK-NEXT: br i1 [[LCMP_MOD]], label [[HEADER_PROL_PREHEADER:%.*]], label [[HEADER_PROL_LOOPEXIT:%.*]] 672; CHECK: header.prol.preheader: 673; CHECK-NEXT: br label [[HEADER_PROL:%.*]] 674; CHECK: header.prol: 675; CHECK-NEXT: [[INDVARS_IV_PROL:%.*]] = phi i64 [ [[START]], [[HEADER_PROL_PREHEADER]] ], [ [[INDVARS_IV_NEXT_PROL:%.*]], [[LATCH_PROL:%.*]] ] 676; CHECK-NEXT: [[PROL_ITER:%.*]] = phi i64 [ 0, [[HEADER_PROL_PREHEADER]] ], [ [[PROL_ITER_NEXT:%.*]], [[LATCH_PROL]] ] 677; CHECK-NEXT: [[IV_I32_PROL:%.*]] = trunc i64 [[INDVARS_IV_PROL]] to i32 678; CHECK-NEXT: [[C1_PROL:%.*]] = call i1 @unknown(i32 [[IV_I32_PROL]]) 679; CHECK-NEXT: br i1 [[C1_PROL]], label [[LATCH_PROL]], label [[OTHEREXIT_LOOPEXIT1:%.*]] 680; CHECK: latch.prol: 681; CHECK-NEXT: [[INDVARS_IV_NEXT_PROL]] = add nsw i64 [[INDVARS_IV_PROL]], 2 682; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT_PROL]], 616 683; CHECK-NEXT: [[PROL_ITER_NEXT]] = add i64 [[PROL_ITER]], 1 684; CHECK-NEXT: [[PROL_ITER_CMP:%.*]] = icmp ne i64 [[PROL_ITER_NEXT]], [[XTRAITER]] 685; CHECK-NEXT: br i1 [[PROL_ITER_CMP]], label [[HEADER_PROL]], label [[HEADER_PROL_LOOPEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP9:![0-9]+]] 686; CHECK: header.prol.loopexit.unr-lcssa: 687; CHECK-NEXT: [[INDVARS_IV_UNR_PH:%.*]] = phi i64 [ [[INDVARS_IV_NEXT_PROL]], [[LATCH_PROL]] ] 688; CHECK-NEXT: br label [[HEADER_PROL_LOOPEXIT]] 689; CHECK: header.prol.loopexit: 690; CHECK-NEXT: [[INDVARS_IV_UNR:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INDVARS_IV_UNR_PH]], [[HEADER_PROL_LOOPEXIT_UNR_LCSSA]] ] 691; CHECK-NEXT: [[TMP8:%.*]] = icmp ult i64 [[TMP6]], 3 692; CHECK-NEXT: br i1 [[TMP8]], label [[LATCHEXIT:%.*]], label [[ENTRY_NEW:%.*]] 693; CHECK: entry.new: 694; CHECK-NEXT: br label [[HEADER:%.*]] 695; CHECK: header: 696; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_UNR]], [[ENTRY_NEW]] ], [ [[INDVARS_IV_NEXT_3:%.*]], [[LATCH_3:%.*]] ] 697; CHECK-NEXT: [[IV_I32:%.*]] = trunc i64 [[INDVARS_IV]] to i32 698; CHECK-NEXT: [[C1:%.*]] = call i1 @unknown(i32 [[IV_I32]]) 699; CHECK-NEXT: br i1 [[C1]], label [[LATCH:%.*]], label [[OTHEREXIT_LOOPEXIT:%.*]] 700; CHECK: latch: 701; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nsw i64 [[INDVARS_IV]], 2 702; CHECK-NEXT: [[IV_I32_1:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32 703; CHECK-NEXT: [[C1_1:%.*]] = call i1 @unknown(i32 [[IV_I32_1]]) 704; CHECK-NEXT: br i1 [[C1_1]], label [[LATCH_1:%.*]], label [[OTHEREXIT_LOOPEXIT]] 705; CHECK: latch.1: 706; CHECK-NEXT: [[INDVARS_IV_NEXT_1:%.*]] = add nsw i64 [[INDVARS_IV_NEXT]], 2 707; CHECK-NEXT: [[IV_I32_2:%.*]] = trunc i64 [[INDVARS_IV_NEXT_1]] to i32 708; CHECK-NEXT: [[C1_2:%.*]] = call i1 @unknown(i32 [[IV_I32_2]]) 709; CHECK-NEXT: br i1 [[C1_2]], label [[LATCH_2:%.*]], label [[OTHEREXIT_LOOPEXIT]] 710; CHECK: latch.2: 711; CHECK-NEXT: [[INDVARS_IV_NEXT_2:%.*]] = add nsw i64 [[INDVARS_IV_NEXT_1]], 2 712; CHECK-NEXT: [[IV_I32_3:%.*]] = trunc i64 [[INDVARS_IV_NEXT_2]] to i32 713; CHECK-NEXT: [[C1_3:%.*]] = call i1 @unknown(i32 [[IV_I32_3]]) 714; CHECK-NEXT: br i1 [[C1_3]], label [[LATCH_3]], label [[OTHEREXIT_LOOPEXIT]] 715; CHECK: latch.3: 716; CHECK-NEXT: [[INDVARS_IV_NEXT_3]] = add nsw i64 [[INDVARS_IV_NEXT_2]], 2 717; CHECK-NEXT: [[TMP9:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT_3]], 616 718; CHECK-NEXT: br i1 [[TMP9]], label [[HEADER]], label [[LATCHEXIT_UNR_LCSSA:%.*]], !llvm.loop [[LOOP10:![0-9]+]] 719; CHECK: latchexit.unr-lcssa: 720; CHECK-NEXT: br label [[LATCHEXIT]] 721; CHECK: latchexit: 722; CHECK-NEXT: br label [[LATCHEXITSUCC:%.*]] 723; CHECK: otherexit.loopexit: 724; CHECK-NEXT: br label [[OTHEREXIT:%.*]] 725; CHECK: otherexit.loopexit1: 726; CHECK-NEXT: br label [[OTHEREXIT]] 727; CHECK: otherexit: 728; CHECK-NEXT: br label [[OTHEREXITSUCC:%.*]] 729; CHECK: otherexitsucc: 730; CHECK-NEXT: br label [[NOT_ZERO44:%.*]] 731; CHECK: not_zero44: 732; CHECK-NEXT: unreachable 733; CHECK: latchexitsucc: 734; CHECK-NEXT: br label [[NOT_ZERO44]] 735; 736entry: 737 br label %header 738 739header: ; preds = %latch, %entry 740 %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %latch ] 741 %iv.i32 = trunc i64 %indvars.iv to i32 742 %c1 = call i1 @unknown(i32 %iv.i32) 743 br i1 %c1, label %latch, label %otherexit 744 745latch: ; preds = %header 746 %indvars.iv.next = add nsw i64 %indvars.iv, 2 747 %0 = icmp slt i64 %indvars.iv.next, 616 748 br i1 %0, label %header, label %latchexit 749 750latchexit: ; preds = %latch 751 br label %latchexitsucc 752 753otherexit: ; preds = %header 754 br label %otherexitsucc 755 756otherexitsucc: ; preds = %otherexit 757 br label %not_zero44 758 759not_zero44: ; preds = %latchexitsucc, %otherexitsucc 760 unreachable 761 762latchexitsucc: ; preds = %latchexit 763 br label %not_zero44 764} 765 766