1348 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -p loop-vectorize -force-vector-width=4 -S %s | FileCheck %s3 4; Test cases with trip counts containing UDIV expressions for5; https://github.com/llvm/llvm-project/issues/89958.6 7define i64 @multi_exit_1_exit_count_with_udiv_by_value_in_header(ptr %dst, i64 %N) {8; CHECK-LABEL: define i64 @multi_exit_1_exit_count_with_udiv_by_value_in_header(9; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {10; CHECK-NEXT: entry:11; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)12; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 42, [[N]]13; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SMAX]], i64 [[TMP0]])14; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 115; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 416; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]17; CHECK: vector.ph:18; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 419; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 020; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]21; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]22; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]23; CHECK: vector.body:24; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]25; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]26; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP5]], align 427; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 428; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]29; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]30; CHECK: middle.block:31; CHECK-NEXT: br label [[SCALAR_PH]]32; CHECK: scalar.ph:33; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]34; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]35; CHECK: loop.header:36; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]37; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]38; CHECK-NEXT: store i32 1, ptr [[GEP]], align 439; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]40; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]41; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT:%.*]]42; CHECK: loop.latch:43; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 144; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]45; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]46; CHECK: exit:47; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]48; CHECK-NEXT: ret i64 [[P]]49;50entry:51 br label %loop.header52 53loop.header:54 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]55 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv56 store i32 1, ptr %gep57 %d = udiv i64 42, %N58 %c.1 = icmp slt i64 %iv, %d59 br i1 %c.1, label %loop.latch, label %exit60 61loop.latch:62 %iv.next = add i64 %iv, 163 %c.0 = icmp slt i64 %iv, %N64 br i1 %c.0, label %loop.header, label %exit65 66exit:67 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]68 ret i64 %p69}70 71define i64 @multi_exit_1_exit_count_with_udiv_by_constant_in_header(ptr %dst, i64 %N) {72; CHECK-LABEL: define i64 @multi_exit_1_exit_count_with_udiv_by_constant_in_header(73; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {74; CHECK-NEXT: entry:75; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)76; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 [[N]], 4277; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SMAX]], i64 [[TMP0]])78; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 179; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 480; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]81; CHECK: vector.ph:82; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 483; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 084; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]85; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]86; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]87; CHECK: vector.body:88; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]89; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]90; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP5]], align 491; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 492; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]93; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]94; CHECK: middle.block:95; CHECK-NEXT: br label [[SCALAR_PH]]96; CHECK: scalar.ph:97; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]98; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]99; CHECK: loop.header:100; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]101; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]102; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4103; CHECK-NEXT: [[D:%.*]] = udiv i64 [[N]], 42104; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]105; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT:%.*]]106; CHECK: loop.latch:107; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1108; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]109; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP5:![0-9]+]]110; CHECK: exit:111; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]112; CHECK-NEXT: ret i64 [[P]]113;114entry:115 br label %loop.header116 117loop.header:118 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]119 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv120 store i32 1, ptr %gep121 %d = udiv i64 %N, 42122 %c.1 = icmp slt i64 %iv, %d123 br i1 %c.1, label %loop.latch, label %exit124 125loop.latch:126 %iv.next = add i64 %iv, 1127 %c.0 = icmp slt i64 %iv, %N128 br i1 %c.0, label %loop.header, label %exit129 130exit:131 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]132 ret i64 %p133}134 135define i64 @multi_exit_2_exit_count_with_udiv_by_value_in_block_executed_unconditionally(ptr %A, i64 %N) {136; CHECK-LABEL: define i64 @multi_exit_2_exit_count_with_udiv_by_value_in_block_executed_unconditionally(137; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {138; CHECK-NEXT: entry:139; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)140; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 42, [[N]]141; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SMAX]], i64 [[TMP0]])142; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 1143; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 4144; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[ENTRY:%.*]]145; CHECK: vector.ph:146; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4147; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 0148; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]149; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]150; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]151; CHECK: vector.body:152; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]153; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]154; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP5]], align 4155; CHECK-NEXT: [[TMP7:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], splat (i32 10)156; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i1> [[TMP7]], i32 0157; CHECK-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]158; CHECK: pred.store.if:159; CHECK-NEXT: [[TMP20:%.*]] = add i64 [[IV]], 0160; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP20]]161; CHECK-NEXT: store i32 1, ptr [[TMP9]], align 4162; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]163; CHECK: pred.store.continue:164; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i1> [[TMP7]], i32 1165; CHECK-NEXT: br i1 [[TMP10]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2:%.*]]166; CHECK: pred.store.if1:167; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[IV]], 1168; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP11]]169; CHECK-NEXT: store i32 1, ptr [[TMP12]], align 4170; CHECK-NEXT: br label [[PRED_STORE_CONTINUE2]]171; CHECK: pred.store.continue2:172; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i1> [[TMP7]], i32 2173; CHECK-NEXT: br i1 [[TMP13]], label [[PRED_STORE_IF3:%.*]], label [[PRED_STORE_CONTINUE4:%.*]]174; CHECK: pred.store.if3:175; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[IV]], 2176; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP14]]177; CHECK-NEXT: store i32 1, ptr [[TMP15]], align 4178; CHECK-NEXT: br label [[PRED_STORE_CONTINUE4]]179; CHECK: pred.store.continue4:180; CHECK-NEXT: [[TMP16:%.*]] = extractelement <4 x i1> [[TMP7]], i32 3181; CHECK-NEXT: br i1 [[TMP16]], label [[PRED_STORE_IF5:%.*]], label [[LOOP_LATCH]]182; CHECK: pred.store.if5:183; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[IV]], 3184; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP17]]185; CHECK-NEXT: store i32 1, ptr [[TMP18]], align 4186; CHECK-NEXT: br label [[LOOP_LATCH]]187; CHECK: pred.store.continue6:188; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 4189; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i64 [[IV_NEXT]], [[N_VEC]]190; CHECK-NEXT: br i1 [[TMP19]], label [[MIDDLE_BLOCK:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP6:![0-9]+]]191; CHECK: middle.block:192; CHECK-NEXT: br label [[SCALAR_PH]]193; CHECK: scalar.ph:194; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY1:%.*]] ]195; CHECK-NEXT: br label [[LOOP_HEADER1:%.*]]196; CHECK: loop.header:197; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT1:%.*]], [[LOOP_LATCH1:%.*]] ]198; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV1]]199; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP]], align 4200; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[L]], 10201; CHECK-NEXT: br i1 [[C_2]], label [[THEN:%.*]], label [[CONTINUE:%.*]]202; CHECK: then:203; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4204; CHECK-NEXT: br label [[CONTINUE]]205; CHECK: continue:206; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]207; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV1]], [[D]]208; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH1]], label [[EXIT:%.*]]209; CHECK: loop.latch:210; CHECK-NEXT: [[IV_NEXT1]] = add i64 [[IV1]], 1211; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV1]], [[N]]212; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_HEADER1]], label [[EXIT]], !llvm.loop [[LOOP7:![0-9]+]]213; CHECK: exit:214; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[CONTINUE]] ], [ 0, [[LOOP_LATCH1]] ]215; CHECK-NEXT: ret i64 [[P]]216;217entry:218 br label %loop.header219 220loop.header:221 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]222 %gep = getelementptr inbounds i32, ptr %A, i64 %iv223 %l = load i32, ptr %gep224 %c.2 = icmp eq i32 %l, 10225 br i1 %c.2, label %then, label %continue226 227then:228 store i32 1, ptr %gep229 br label %continue230 231continue:232 %d = udiv i64 42, %N233 %c.1 = icmp slt i64 %iv, %d234 br i1 %c.1, label %loop.latch, label %exit235 236loop.latch:237 %iv.next = add i64 %iv, 1238 %c.0 = icmp slt i64 %iv, %N239 br i1 %c.0, label %loop.header, label %exit240 241exit:242 %p = phi i64 [ 1, %continue ], [ 0, %loop.latch]243 ret i64 %p244}245 246define i64 @multi_exit_2_exit_count_with_udiv_by_constant_in_block_executed_unconditionally(ptr %A, i64 %N) {247; CHECK-LABEL: define i64 @multi_exit_2_exit_count_with_udiv_by_constant_in_block_executed_unconditionally(248; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {249; CHECK-NEXT: entry:250; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)251; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 [[N]], 42252; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SMAX]], i64 [[TMP0]])253; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 1254; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 4255; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[ENTRY:%.*]]256; CHECK: vector.ph:257; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4258; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 0259; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]260; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]261; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]262; CHECK: vector.body:263; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]264; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]265; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP5]], align 4266; CHECK-NEXT: [[TMP7:%.*]] = icmp eq <4 x i32> [[WIDE_LOAD]], splat (i32 10)267; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i1> [[TMP7]], i32 0268; CHECK-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]269; CHECK: pred.store.if:270; CHECK-NEXT: [[TMP20:%.*]] = add i64 [[IV]], 0271; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP20]]272; CHECK-NEXT: store i32 1, ptr [[TMP9]], align 4273; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]274; CHECK: pred.store.continue:275; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i1> [[TMP7]], i32 1276; CHECK-NEXT: br i1 [[TMP10]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2:%.*]]277; CHECK: pred.store.if1:278; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[IV]], 1279; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP11]]280; CHECK-NEXT: store i32 1, ptr [[TMP12]], align 4281; CHECK-NEXT: br label [[PRED_STORE_CONTINUE2]]282; CHECK: pred.store.continue2:283; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x i1> [[TMP7]], i32 2284; CHECK-NEXT: br i1 [[TMP13]], label [[PRED_STORE_IF3:%.*]], label [[PRED_STORE_CONTINUE4:%.*]]285; CHECK: pred.store.if3:286; CHECK-NEXT: [[TMP14:%.*]] = add i64 [[IV]], 2287; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP14]]288; CHECK-NEXT: store i32 1, ptr [[TMP15]], align 4289; CHECK-NEXT: br label [[PRED_STORE_CONTINUE4]]290; CHECK: pred.store.continue4:291; CHECK-NEXT: [[TMP16:%.*]] = extractelement <4 x i1> [[TMP7]], i32 3292; CHECK-NEXT: br i1 [[TMP16]], label [[PRED_STORE_IF5:%.*]], label [[LOOP_LATCH]]293; CHECK: pred.store.if5:294; CHECK-NEXT: [[TMP17:%.*]] = add i64 [[IV]], 3295; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[TMP17]]296; CHECK-NEXT: store i32 1, ptr [[TMP18]], align 4297; CHECK-NEXT: br label [[LOOP_LATCH]]298; CHECK: pred.store.continue6:299; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 4300; CHECK-NEXT: [[TMP19:%.*]] = icmp eq i64 [[IV_NEXT]], [[N_VEC]]301; CHECK-NEXT: br i1 [[TMP19]], label [[MIDDLE_BLOCK:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP8:![0-9]+]]302; CHECK: middle.block:303; CHECK-NEXT: br label [[SCALAR_PH]]304; CHECK: scalar.ph:305; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY1:%.*]] ]306; CHECK-NEXT: br label [[LOOP_HEADER1:%.*]]307; CHECK: loop.header:308; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT1:%.*]], [[LOOP_LATCH1:%.*]] ]309; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV1]]310; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP]], align 4311; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[L]], 10312; CHECK-NEXT: br i1 [[C_2]], label [[THEN:%.*]], label [[CONTINUE:%.*]]313; CHECK: then:314; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4315; CHECK-NEXT: br label [[CONTINUE]]316; CHECK: continue:317; CHECK-NEXT: [[D:%.*]] = udiv i64 [[N]], 42318; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV1]], [[D]]319; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH1]], label [[EXIT:%.*]]320; CHECK: loop.latch:321; CHECK-NEXT: [[IV_NEXT1]] = add i64 [[IV1]], 1322; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV1]], [[N]]323; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_HEADER1]], label [[EXIT]], !llvm.loop [[LOOP9:![0-9]+]]324; CHECK: exit:325; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[CONTINUE]] ], [ 0, [[LOOP_LATCH1]] ]326; CHECK-NEXT: ret i64 [[P]]327;328entry:329 br label %loop.header330 331loop.header:332 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]333 %gep = getelementptr inbounds i32, ptr %A, i64 %iv334 %l = load i32, ptr %gep335 %c.2 = icmp eq i32 %l, 10336 br i1 %c.2, label %then, label %continue337 338then:339 store i32 1, ptr %gep340 br label %continue341 342continue:343 %d = udiv i64 %N, 42344 %c.1 = icmp slt i64 %iv, %d345 br i1 %c.1, label %loop.latch, label %exit346 347loop.latch:348 %iv.next = add i64 %iv, 1349 %c.0 = icmp slt i64 %iv, %N350 br i1 %c.0, label %loop.header, label %exit351 352exit:353 %p = phi i64 [ 1, %continue ], [ 0, %loop.latch]354 ret i64 %p355}356 357define i64 @multi_exit_3_exit_count_with_udiv_by_value_in_block_executed_conditionally(ptr %A, i64 %N) {358; CHECK-LABEL: define i64 @multi_exit_3_exit_count_with_udiv_by_value_in_block_executed_conditionally(359; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {360; CHECK-NEXT: entry:361; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]362; CHECK: loop.header:363; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]364; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]365; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP]], align 4366; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[L]], 10367; CHECK-NEXT: br i1 [[C_2]], label [[THEN:%.*]], label [[LOOP_LATCH]]368; CHECK: then:369; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]370; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]371; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT:%.*]]372; CHECK: loop.latch:373; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4374; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1375; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]376; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_HEADER]], label [[EXIT]]377; CHECK: exit:378; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[THEN]] ], [ 0, [[LOOP_LATCH]] ]379; CHECK-NEXT: ret i64 [[P]]380;381entry:382 br label %loop.header383 384loop.header:385 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]386 %gep = getelementptr inbounds i32, ptr %A, i64 %iv387 %l = load i32, ptr %gep388 %c.2 = icmp eq i32 %l, 10389 br i1 %c.2, label %then, label %loop.latch390 391then:392 %d = udiv i64 42, %N393 %c.1 = icmp slt i64 %iv, %d394 br i1 %c.1, label %loop.latch, label %exit395 396loop.latch:397 store i32 1, ptr %gep398 %iv.next = add i64 %iv, 1399 %c.0 = icmp slt i64 %iv, %N400 br i1 %c.0, label %loop.header, label %exit401 402exit:403 %p = phi i64 [ 1, %then ], [ 0, %loop.latch]404 ret i64 %p405}406 407define i64 @multi_exit_3_exit_count_with_udiv_by_constant_in_block_executed_conditionally(ptr %A, i64 %N) {408; CHECK-LABEL: define i64 @multi_exit_3_exit_count_with_udiv_by_constant_in_block_executed_conditionally(409; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {410; CHECK-NEXT: entry:411; CHECK-NEXT: [[D:%.*]] = udiv i64 [[N]], 42412; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]413; CHECK: loop.header:414; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]415; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]416; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP]], align 4417; CHECK-NEXT: [[C_2:%.*]] = icmp ne i32 [[L]], 10418; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]419; CHECK-NEXT: [[OR_COND:%.*]] = select i1 [[C_2]], i1 true, i1 [[C_1]]420; CHECK-NEXT: br i1 [[OR_COND]], label [[LOOP_LATCH]], label [[EXIT:%.*]]421; CHECK: loop.latch:422; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4423; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1424; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]425; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_HEADER]], label [[EXIT]]426; CHECK: exit:427; CHECK-NEXT: [[P:%.*]] = phi i64 [ 0, [[LOOP_LATCH]] ], [ 1, [[LOOP_HEADER]] ]428; CHECK-NEXT: ret i64 [[P]]429;430entry:431 br label %loop.header432 433loop.header:434 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]435 %gep = getelementptr inbounds i32, ptr %A, i64 %iv436 %l = load i32, ptr %gep437 %c.2 = icmp eq i32 %l, 10438 br i1 %c.2, label %then, label %loop.latch439 440then:441 %d = udiv i64 %N, 42442 %c.1 = icmp slt i64 %iv, %d443 br i1 %c.1, label %loop.latch, label %exit444 445loop.latch:446 store i32 1, ptr %gep447 %iv.next = add i64 %iv, 1448 %c.0 = icmp slt i64 %iv, %N449 br i1 %c.0, label %loop.header, label %exit450 451exit:452 %p = phi i64 [ 1, %then ], [ 0, %loop.latch]453 ret i64 %p454}455 456define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch(ptr %dst, i64 %N) {457; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch(458; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {459; CHECK-NEXT: entry:460; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.umax.i64(i64 [[N]], i64 1)461; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 42, [[TMP10]]462; CHECK-NEXT: [[TMP8:%.*]] = freeze i64 [[TMP0]]463; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)464; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP8]], i64 [[SMAX]])465; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 1466; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 4467; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]468; CHECK: vector.ph:469; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4470; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 0471; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]472; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]473; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]474; CHECK: vector.body:475; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]476; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]477; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP5]], align 4478; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4479; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]480; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]481; CHECK: middle.block:482; CHECK-NEXT: br label [[SCALAR_PH]]483; CHECK: scalar.ph:484; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]485; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]486; CHECK: loop.header:487; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]488; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]489; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4490; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]491; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]492; CHECK: loop.latch:493; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1494; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]495; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]496; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP11:![0-9]+]]497; CHECK: exit:498; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]499; CHECK-NEXT: ret i64 [[P]]500;501entry:502 br label %loop.header503 504loop.header:505 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]506 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv507 store i32 1, ptr %gep508 %c.0 = icmp slt i64 %iv, %N509 br i1 %c.0, label %loop.latch, label %exit510 511loop.latch:512 %iv.next = add i64 %iv, 1513 %d = udiv i64 42, %N514 %c.1 = icmp slt i64 %iv, %d515 br i1 %c.1, label %loop.header, label %exit516 517exit:518 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]519 ret i64 %p520}521 522declare void @foo()523 524define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch_call_before_loop(ptr %dst, i64 %N) {525; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch_call_before_loop(526; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {527; CHECK-NEXT: entry:528; CHECK-NEXT: call void @foo()529; CHECK-NEXT: [[TMP0:%.*]] = freeze i64 [[N]]530; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP0]], i64 1)531; CHECK-NEXT: [[TMP2:%.*]] = udiv i64 42, [[TMP1]]532; CHECK-NEXT: [[TMP3:%.*]] = freeze i64 [[TMP2]]533; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)534; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP3]], i64 [[SMAX]])535; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[UMIN]], 1536; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP4]], 4537; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]538; CHECK: vector.ph:539; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP4]], 4540; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[N_MOD_VF]], 0541; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 4, i64 [[N_MOD_VF]]542; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP4]], [[TMP6]]543; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]544; CHECK: vector.body:545; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]546; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]547; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP8]], align 4548; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4549; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]550; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]551; CHECK: middle.block:552; CHECK-NEXT: br label [[SCALAR_PH]]553; CHECK: scalar.ph:554; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]555; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]556; CHECK: loop.header:557; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]558; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]559; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4560; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]561; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]562; CHECK: loop.latch:563; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1564; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]565; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]566; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP13:![0-9]+]]567; CHECK: exit:568; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]569; CHECK-NEXT: ret i64 [[P]]570;571entry:572 call void @foo()573 br label %loop.header574 575loop.header:576 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]577 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv578 store i32 1, ptr %gep579 %c.0 = icmp slt i64 %iv, %N580 br i1 %c.0, label %loop.latch, label %exit581 582loop.latch:583 %iv.next = add i64 %iv, 1584 %d = udiv i64 42, %N585 %c.1 = icmp slt i64 %iv, %d586 br i1 %c.1, label %loop.header, label %exit587 588exit:589 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]590 ret i64 %p591}592 593define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch_loop_may_not_execute(ptr %dst, i64 %N, i1 %c) {594; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch_loop_may_not_execute(595; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]], i1 [[C:%.*]]) {596; CHECK-NEXT: entry:597; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER_PREHEADER:%.*]], label [[EXIT:%.*]]598; CHECK: loop.header.preheader:599; CHECK-NEXT: [[TMP0:%.*]] = freeze i64 [[N]]600; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP0]], i64 1)601; CHECK-NEXT: [[TMP2:%.*]] = udiv i64 42, [[TMP1]]602; CHECK-NEXT: [[TMP3:%.*]] = freeze i64 [[TMP2]]603; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)604; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP3]], i64 [[SMAX]])605; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[UMIN]], 1606; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP4]], 4607; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]608; CHECK: vector.ph:609; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP4]], 4610; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[N_MOD_VF]], 0611; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 4, i64 [[N_MOD_VF]]612; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP4]], [[TMP6]]613; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]614; CHECK: vector.body:615; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]616; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]617; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP8]], align 4618; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4619; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]620; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]621; CHECK: middle.block:622; CHECK-NEXT: br label [[SCALAR_PH]]623; CHECK: scalar.ph:624; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[LOOP_HEADER_PREHEADER]] ]625; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]626; CHECK: loop.header:627; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]628; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]629; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4630; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]631; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT_LOOPEXIT:%.*]]632; CHECK: loop.latch:633; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1634; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]635; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]636; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP15:![0-9]+]]637; CHECK: exit.loopexit:638; CHECK-NEXT: [[P_PH:%.*]] = phi i64 [ 0, [[LOOP_LATCH]] ], [ 1, [[LOOP_HEADER]] ]639; CHECK-NEXT: br label [[EXIT]]640; CHECK: exit:641; CHECK-NEXT: [[P:%.*]] = phi i64 [ 2, [[ENTRY:%.*]] ], [ [[P_PH]], [[EXIT_LOOPEXIT]] ]642; CHECK-NEXT: ret i64 [[P]]643;644entry:645 br i1 %c, label %loop.header, label %exit646 647loop.header:648 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]649 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv650 store i32 1, ptr %gep651 %c.0 = icmp slt i64 %iv, %N652 br i1 %c.0, label %loop.latch, label %exit653 654loop.latch:655 %iv.next = add i64 %iv, 1656 %d = udiv i64 42, %N657 %c.1 = icmp slt i64 %iv, %d658 br i1 %c.1, label %loop.header, label %exit659 660exit:661 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch], [ 2, %entry ]662 ret i64 %p663}664 665define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch_different_bounds(ptr %dst, i64 %N, i64 %M) {666; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch_different_bounds(667; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]], i64 [[M:%.*]]) {668; CHECK-NEXT: entry:669; CHECK-NEXT: [[TMP0:%.*]] = freeze i64 [[M]]670; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP0]], i64 1)671; CHECK-NEXT: [[TMP2:%.*]] = udiv i64 42, [[TMP1]]672; CHECK-NEXT: [[TMP3:%.*]] = freeze i64 [[TMP2]]673; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)674; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP3]], i64 [[SMAX]])675; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[UMIN]], 1676; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP4]], 4677; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]678; CHECK: vector.ph:679; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP4]], 4680; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[N_MOD_VF]], 0681; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i64 4, i64 [[N_MOD_VF]]682; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP4]], [[TMP6]]683; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]684; CHECK: vector.body:685; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]686; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]687; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP8]], align 4688; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4689; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]690; CHECK-NEXT: br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]691; CHECK: middle.block:692; CHECK-NEXT: br label [[SCALAR_PH]]693; CHECK: scalar.ph:694; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]695; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]696; CHECK: loop.header:697; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]698; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]699; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4700; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]701; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]702; CHECK: loop.latch:703; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1704; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[M]]705; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]706; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP17:![0-9]+]]707; CHECK: exit:708; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]709; CHECK-NEXT: ret i64 [[P]]710;711entry:712 br label %loop.header713 714loop.header:715 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]716 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv717 store i32 1, ptr %gep718 %c.0 = icmp slt i64 %iv, %N719 br i1 %c.0, label %loop.latch, label %exit720 721loop.latch:722 %iv.next = add i64 %iv, 1723 %d = udiv i64 42, %M724 %c.1 = icmp slt i64 %iv, %d725 br i1 %c.1, label %loop.header, label %exit726 727exit:728 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]729 ret i64 %p730}731 732define i64 @multi_exit_4_exit_count_with_udiv_by_frozen_value_in_latch(ptr %dst, i64 %N) {733; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_frozen_value_in_latch(734; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {735; CHECK-NEXT: entry:736; CHECK-NEXT: [[FR_N:%.*]] = freeze i64 [[N]]737; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.umax.i64(i64 [[FR_N]], i64 1)738; CHECK-NEXT: [[TMP2:%.*]] = udiv i64 42, [[TMP1]]739; CHECK-NEXT: [[TMP10:%.*]] = freeze i64 [[TMP2]]740; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)741; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP10]], i64 [[SMAX]])742; CHECK-NEXT: [[TMP3:%.*]] = add nuw nsw i64 [[UMIN]], 1743; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP3]], 4744; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]745; CHECK: vector.ph:746; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP3]], 4747; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[N_MOD_VF]], 0748; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i64 4, i64 [[N_MOD_VF]]749; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP3]], [[TMP5]]750; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]751; CHECK: vector.body:752; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]753; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]754; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP7]], align 4755; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4756; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]757; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]758; CHECK: middle.block:759; CHECK-NEXT: br label [[SCALAR_PH]]760; CHECK: scalar.ph:761; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]762; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]763; CHECK: loop.header:764; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]765; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]766; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4767; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]768; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]769; CHECK: loop.latch:770; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1771; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[FR_N]]772; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]773; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP19:![0-9]+]]774; CHECK: exit:775; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]776; CHECK-NEXT: ret i64 [[P]]777;778entry:779 %fr.N = freeze i64 %N780 br label %loop.header781 782loop.header:783 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]784 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv785 store i32 1, ptr %gep786 %c.0 = icmp slt i64 %iv, %N787 br i1 %c.0, label %loop.latch, label %exit788 789loop.latch:790 %iv.next = add i64 %iv, 1791 %d = udiv i64 42, %fr.N792 %c.1 = icmp slt i64 %iv, %d793 br i1 %c.1, label %loop.header, label %exit794 795exit:796 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]797 ret i64 %p798}799 800 801define i64 @multi_exit_4_exit_count_with_udiv_by_constant_in_latch(ptr %dst, i64 %N) {802; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_constant_in_latch(803; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {804; CHECK-NEXT: entry:805; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)806; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 [[N]], 42807; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SMAX]], i64 [[TMP0]])808; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 1809; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 4810; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]811; CHECK: vector.ph:812; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4813; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 0814; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]815; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]816; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]817; CHECK: vector.body:818; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[LOOP_HEADER]] ]819; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]820; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[GEP]], align 4821; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4822; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]823; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP20:![0-9]+]]824; CHECK: middle.block:825; CHECK-NEXT: br label [[SCALAR_PH]]826; CHECK: scalar.ph:827; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]828; CHECK-NEXT: br label [[LOOP_HEADER1:%.*]]829; CHECK: loop.header:830; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]831; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV1]]832; CHECK-NEXT: store i32 1, ptr [[GEP1]], align 4833; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV1]], [[N]]834; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]835; CHECK: loop.latch:836; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 1837; CHECK-NEXT: [[D:%.*]] = udiv i64 [[N]], 42838; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV1]], [[D]]839; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER1]], label [[EXIT]], !llvm.loop [[LOOP21:![0-9]+]]840; CHECK: exit:841; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER1]] ], [ 0, [[LOOP_LATCH]] ]842; CHECK-NEXT: ret i64 [[P]]843;844entry:845 br label %loop.header846 847loop.header:848 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]849 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv850 store i32 1, ptr %gep851 %c.0 = icmp slt i64 %iv, %N852 br i1 %c.0, label %loop.latch, label %exit853 854loop.latch:855 %iv.next = add i64 %iv, 1856 %d = udiv i64 %N, 42857 %c.1 = icmp slt i64 %iv, %d858 br i1 %c.1, label %loop.header, label %exit859 860exit:861 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]862 ret i64 %p863}864 865define void @single_exit_tc_with_udiv(ptr %dst, i64 %N) {866; CHECK-LABEL: define void @single_exit_tc_with_udiv(867; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {868; CHECK-NEXT: entry:869; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 42, [[N]]870; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 1871; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP1]], 4872; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]873; CHECK: vector.ph:874; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4875; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[N_MOD_VF]]876; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]877; CHECK: vector.body:878; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]879; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]880; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP3]], align 4881; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4882; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]883; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]884; CHECK: middle.block:885; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP1]], [[N_VEC]]886; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]]887; CHECK: scalar.ph:888; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]889; CHECK-NEXT: br label [[LOOP:%.*]]890; CHECK: loop:891; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]892; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]893; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4894; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1895; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]896; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]897; CHECK-NEXT: br i1 [[C_1]], label [[LOOP]], label [[EXIT]], !llvm.loop [[LOOP23:![0-9]+]]898; CHECK: exit:899; CHECK-NEXT: ret void900;901entry:902 br label %loop903 904loop:905 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]906 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv907 store i32 1, ptr %gep908 %iv.next = add i64 %iv, 1909 %d = udiv i64 42, %N910 %c.1 = icmp slt i64 %iv, %d911 br i1 %c.1, label %loop, label %exit912 913exit:914 ret void915}916 917define i64 @multi_exit_4_exit_count_with_urem_by_value_in_latch(ptr %dst, i64 %N) {918; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_urem_by_value_in_latch(919; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {920; CHECK-NEXT: entry:921; CHECK-NEXT: [[TMP12:%.*]] = call i64 @llvm.umax.i64(i64 [[N]], i64 1)922; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 42, [[TMP12]]923; CHECK-NEXT: [[TMP1:%.*]] = mul nuw i64 [[N]], [[TMP0]]924; CHECK-NEXT: [[TMP2:%.*]] = sub i64 42, [[TMP1]]925; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP2]], i64 0)926; CHECK-NEXT: [[TMP10:%.*]] = freeze i64 [[SMAX1]]927; CHECK-NEXT: [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)928; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP10]], i64 [[SMAX2]])929; CHECK-NEXT: [[TMP3:%.*]] = add nuw i64 [[UMIN]], 1930; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP3]], 4931; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]932; CHECK: vector.ph:933; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP3]], 4934; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[N_MOD_VF]], 0935; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i64 4, i64 [[N_MOD_VF]]936; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP3]], [[TMP5]]937; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]938; CHECK: vector.body:939; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]940; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]941; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP7]], align 4942; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4943; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]944; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]]945; CHECK: middle.block:946; CHECK-NEXT: br label [[SCALAR_PH]]947; CHECK: scalar.ph:948; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]949; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]950; CHECK: loop.header:951; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]952; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]953; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4954; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]955; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]956; CHECK: loop.latch:957; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1958; CHECK-NEXT: [[D:%.*]] = urem i64 42, [[N]]959; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]960; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP25:![0-9]+]]961; CHECK: exit:962; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]963; CHECK-NEXT: ret i64 [[P]]964;965entry:966 br label %loop.header967 968loop.header:969 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]970 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv971 store i32 1, ptr %gep972 %c.0 = icmp slt i64 %iv, %N973 br i1 %c.0, label %loop.latch, label %exit974 975loop.latch:976 %iv.next = add i64 %iv, 1977 %d = urem i64 42, %N978 %c.1 = icmp slt i64 %iv, %d979 br i1 %c.1, label %loop.header, label %exit980 981exit:982 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]983 ret i64 %p984}985 986define i64 @multi_exit_4_exit_count_with_urem_by_constant_in_latch(ptr %dst, i64 %N) {987; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_urem_by_constant_in_latch(988; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {989; CHECK-NEXT: entry:990; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)991; CHECK-NEXT: [[TMP0:%.*]] = urem i64 [[N]], 42992; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)993; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[SMAX]], i64 [[SMAX1]])994; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[UMIN]], 1995; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 4996; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]997; CHECK: vector.ph:998; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 4999; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 01000; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]1001; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]1002; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1003; CHECK: vector.body:1004; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[LOOP_HEADER]] ]1005; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]1006; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[GEP]], align 41007; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 41008; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]1009; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP26:![0-9]+]]1010; CHECK: middle.block:1011; CHECK-NEXT: br label [[SCALAR_PH]]1012; CHECK: scalar.ph:1013; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]1014; CHECK-NEXT: br label [[LOOP_HEADER1:%.*]]1015; CHECK: loop.header:1016; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1017; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV1]]1018; CHECK-NEXT: store i32 1, ptr [[GEP1]], align 41019; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV1]], [[N]]1020; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]1021; CHECK: loop.latch:1022; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV1]], 11023; CHECK-NEXT: [[D:%.*]] = urem i64 [[N]], 421024; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV1]], [[D]]1025; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER1]], label [[EXIT]], !llvm.loop [[LOOP27:![0-9]+]]1026; CHECK: exit:1027; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER1]] ], [ 0, [[LOOP_LATCH]] ]1028; CHECK-NEXT: ret i64 [[P]]1029;1030entry:1031 br label %loop.header1032 1033loop.header:1034 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]1035 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv1036 store i32 1, ptr %gep1037 %c.0 = icmp slt i64 %iv, %N1038 br i1 %c.0, label %loop.latch, label %exit1039 1040loop.latch:1041 %iv.next = add i64 %iv, 11042 %d = urem i64 %N, 421043 %c.1 = icmp slt i64 %iv, %d1044 br i1 %c.1, label %loop.header, label %exit1045 1046exit:1047 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]1048 ret i64 %p1049}1050 1051define i64 @multi_exit_4_exit_count_with_srem_by_value_in_latch(ptr %dst, i64 %N) {1052; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_srem_by_value_in_latch(1053; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {1054; CHECK-NEXT: entry:1055; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1056; CHECK: loop.header:1057; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1058; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]1059; CHECK-NEXT: store i32 1, ptr [[GEP]], align 41060; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]1061; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]1062; CHECK: loop.latch:1063; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 11064; CHECK-NEXT: [[D:%.*]] = srem i64 42, [[N]]1065; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]1066; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]]1067; CHECK: exit:1068; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]1069; CHECK-NEXT: ret i64 [[P]]1070;1071entry:1072 br label %loop.header1073 1074loop.header:1075 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]1076 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv1077 store i32 1, ptr %gep1078 %c.0 = icmp slt i64 %iv, %N1079 br i1 %c.0, label %loop.latch, label %exit1080 1081loop.latch:1082 %iv.next = add i64 %iv, 11083 %d = srem i64 42, %N1084 %c.1 = icmp slt i64 %iv, %d1085 br i1 %c.1, label %loop.header, label %exit1086 1087exit:1088 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]1089 ret i64 %p1090}1091 1092define i64 @multi_exit_4_exit_count_with_sdiv_by_value_in_latch(ptr %dst, i64 %N) {1093; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_sdiv_by_value_in_latch(1094; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {1095; CHECK-NEXT: entry:1096; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1097; CHECK: loop.header:1098; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1099; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]1100; CHECK-NEXT: store i32 1, ptr [[GEP]], align 41101; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]1102; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]1103; CHECK: loop.latch:1104; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 11105; CHECK-NEXT: [[D:%.*]] = sdiv i64 42, [[N]]1106; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]1107; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]]1108; CHECK: exit:1109; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]1110; CHECK-NEXT: ret i64 [[P]]1111;1112entry:1113 br label %loop.header1114 1115loop.header:1116 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]1117 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv1118 store i32 1, ptr %gep1119 %c.0 = icmp slt i64 %iv, %N1120 br i1 %c.0, label %loop.latch, label %exit1121 1122loop.latch:1123 %iv.next = add i64 %iv, 11124 %d = sdiv i64 42, %N1125 %c.1 = icmp slt i64 %iv, %d1126 br i1 %c.1, label %loop.header, label %exit1127 1128exit:1129 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]1130 ret i64 %p1131}1132 1133define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch1(ptr %dst, i64 %N) {1134; CHECK-LABEL: define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch1(1135; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {1136; CHECK-NEXT: entry:1137; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.umax.i64(i64 [[N]], i64 1)1138; CHECK-NEXT: [[TMP9:%.*]] = udiv i64 42, [[TMP8]]1139; CHECK-NEXT: [[TMP10:%.*]] = freeze i64 [[TMP9]]1140; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)1141; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP10]], i64 [[SMAX]])1142; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[UMIN]], 11143; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP1]], 41144; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]1145; CHECK: vector.ph:1146; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 41147; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[N_MOD_VF]], 01148; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 4, i64 [[N_MOD_VF]]1149; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[TMP3]]1150; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]1151; CHECK: vector.body:1152; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]1153; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]1154; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP5]], align 41155; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 41156; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]1157; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]]1158; CHECK: middle.block:1159; CHECK-NEXT: br label [[SCALAR_PH]]1160; CHECK: scalar.ph:1161; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]1162; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1163; CHECK: loop.header:1164; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1165; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]1166; CHECK-NEXT: store i32 1, ptr [[GEP]], align 41167; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]1168; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]1169; CHECK: loop.latch:1170; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 11171; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[N]]1172; CHECK-NEXT: [[X:%.*]] = sub i64 100, [[D]]1173; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]1174; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP29:![0-9]+]]1175; CHECK: exit:1176; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]1177; CHECK-NEXT: ret i64 [[P]]1178;1179entry:1180 br label %loop.header1181 1182loop.header:1183 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]1184 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv1185 store i32 1, ptr %gep1186 %c.0 = icmp slt i64 %iv, %N1187 br i1 %c.0, label %loop.latch, label %exit1188 1189loop.latch:1190 %iv.next = add i64 %iv, 11191 %d = udiv i64 42, %N1192 %x = sub i64 100, %d1193 %c.1 = icmp slt i64 %iv, %d1194 br i1 %c.1, label %loop.header, label %exit1195 1196exit:1197 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]1198 ret i64 %p1199}1200 1201define i64 @multi_exit_exit_count_with_udiv_by_0_in_latch(ptr %dst, i64 %N) {1202; CHECK-LABEL: define i64 @multi_exit_exit_count_with_udiv_by_0_in_latch(1203; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]]) {1204; CHECK-NEXT: entry:1205; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1206; CHECK: loop.header:1207; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1208; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]1209; CHECK-NEXT: store i32 1, ptr [[GEP]], align 41210; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]1211; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]1212; CHECK: loop.latch:1213; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 11214; CHECK-NEXT: [[D:%.*]] = udiv i64 42, 01215; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]1216; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]]1217; CHECK: exit:1218; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]1219; CHECK-NEXT: ret i64 [[P]]1220;1221entry:1222 br label %loop.header1223 1224loop.header:1225 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]1226 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv1227 store i32 1, ptr %gep1228 %c.0 = icmp slt i64 %iv, %N1229 br i1 %c.0, label %loop.latch, label %exit1230 1231loop.latch:1232 %iv.next = add i64 %iv, 11233 %d = udiv i64 42, 01234 %c.1 = icmp slt i64 %iv, %d1235 br i1 %c.1, label %loop.header, label %exit1236 1237exit:1238 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]1239 ret i64 %p1240}1241 1242define i64 @multi_exit_count_with_udiv_by_value_in_latch_different_bounds_divisor_non_zero_may_be_poison(ptr %dst, i64 %N, i64 %M) {1243; CHECK-LABEL: define i64 @multi_exit_count_with_udiv_by_value_in_latch_different_bounds_divisor_non_zero_may_be_poison(1244; CHECK-SAME: ptr [[DST:%.*]], i64 [[N:%.*]], i64 [[M:%.*]]) {1245; CHECK-NEXT: entry:1246; CHECK-NEXT: [[M_1:%.*]] = call i64 @llvm.umax.i64(i64 [[M]], i64 1)1247; CHECK-NEXT: [[TMP9:%.*]] = freeze i64 [[M_1]]1248; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP9]], i64 1)1249; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 42, [[TMP10]]1250; CHECK-NEXT: [[TMP1:%.*]] = freeze i64 [[TMP0]]1251; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N]], i64 0)1252; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP1]], i64 [[SMAX]])1253; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[UMIN]], 11254; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP2]], 41255; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]1256; CHECK: vector.ph:1257; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 41258; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[N_MOD_VF]], 01259; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 4, i64 [[N_MOD_VF]]1260; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[TMP4]]1261; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]1262; CHECK: vector.body:1263; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]1264; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDEX]]1265; CHECK-NEXT: store <4 x i32> splat (i32 1), ptr [[TMP6]], align 41266; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 41267; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]1268; CHECK-NEXT: br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]]1269; CHECK: middle.block:1270; CHECK-NEXT: br label [[SCALAR_PH]]1271; CHECK: scalar.ph:1272; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]1273; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]1274; CHECK: loop.header:1275; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1276; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]1277; CHECK-NEXT: store i32 1, ptr [[GEP]], align 41278; CHECK-NEXT: [[C_0:%.*]] = icmp slt i64 [[IV]], [[N]]1279; CHECK-NEXT: br i1 [[C_0]], label [[LOOP_LATCH]], label [[EXIT:%.*]]1280; CHECK: loop.latch:1281; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 11282; CHECK-NEXT: [[D:%.*]] = udiv i64 42, [[M_1]]1283; CHECK-NEXT: [[C_1:%.*]] = icmp slt i64 [[IV]], [[D]]1284; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP31:![0-9]+]]1285; CHECK: exit:1286; CHECK-NEXT: [[P:%.*]] = phi i64 [ 1, [[LOOP_HEADER]] ], [ 0, [[LOOP_LATCH]] ]1287; CHECK-NEXT: ret i64 [[P]]1288;1289entry:1290 %M.1 = call i64 @llvm.umax.i64(i64 %M, i64 1)1291 br label %loop.header1292 1293loop.header:1294 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]1295 %gep = getelementptr inbounds i32, ptr %dst, i64 %iv1296 store i32 1, ptr %gep1297 %c.0 = icmp slt i64 %iv, %N1298 br i1 %c.0, label %loop.latch, label %exit1299 1300loop.latch:1301 %iv.next = add i64 %iv, 11302 %d = udiv i64 42, %M.11303 %c.1 = icmp slt i64 %iv, %d1304 br i1 %c.1, label %loop.header, label %exit1305 1306exit:1307 %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch]1308 ret i64 %p1309}1310 1311declare i64 @llvm.umax.i64(i64, i64)1312 1313 1314;.1315; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}1316; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}1317; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}1318; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}1319; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}1320; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}1321; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}1322; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]}1323; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]}1324; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]}1325; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]}1326; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META1]]}1327; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]}1328; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META1]]}1329; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META1]], [[META2]]}1330; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META2]], [[META1]]}1331; CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META1]], [[META2]]}1332; CHECK: [[LOOP17]] = distinct !{[[LOOP17]], [[META2]], [[META1]]}1333; CHECK: [[LOOP18]] = distinct !{[[LOOP18]], [[META1]], [[META2]]}1334; CHECK: [[LOOP19]] = distinct !{[[LOOP19]], [[META2]], [[META1]]}1335; CHECK: [[LOOP20]] = distinct !{[[LOOP20]], [[META1]], [[META2]]}1336; CHECK: [[LOOP21]] = distinct !{[[LOOP21]], [[META2]], [[META1]]}1337; CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META1]], [[META2]]}1338; CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META2]], [[META1]]}1339; CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META1]], [[META2]]}1340; CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META2]], [[META1]]}1341; CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META1]], [[META2]]}1342; CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META2]], [[META1]]}1343; CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META1]], [[META2]]}1344; CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META2]], [[META1]]}1345; CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META1]], [[META2]]}1346; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]}1347;.1348