1a2a0ac42SJingu Kang; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2a2a0ac42SJingu Kang; RUN: opt -passes=loop-bound-split -S < %s | FileCheck %s 3a2a0ac42SJingu Kang 42a26d47aSJingu Kang; The transformation is failed with this test because we can not guarantee the 52a26d47aSJingu Kang; split condition is always true in pre-loop after transformation. 6*dfc4a956SNikita Popovdefine void @variable_split_loop_bound_and_exit_cond_inc_with_sgt(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 72a26d47aSJingu Kang; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_sgt( 8a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 92a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 102a26d47aSJingu Kang; CHECK: loop: 112a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 122a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 132a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 142a26d47aSJingu Kang; CHECK: if.then: 15*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 16*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 17*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 18*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 192a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 202a26d47aSJingu Kang; CHECK: if.else: 212a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 222a26d47aSJingu Kang; CHECK: for.inc: 232a26d47aSJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 242a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[INC]], [[N:%.*]] 252a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 262a26d47aSJingu Kang; CHECK: exit: 272a26d47aSJingu Kang; CHECK-NEXT: ret void 282a26d47aSJingu Kang; 292a26d47aSJingu Kangloop.ph: 302a26d47aSJingu Kang br label %loop 312a26d47aSJingu Kang 322a26d47aSJingu Kangloop: 332a26d47aSJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 342a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 352a26d47aSJingu Kang br i1 %cmp, label %if.then, label %if.else 362a26d47aSJingu Kang 372a26d47aSJingu Kangif.then: 38*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 39*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 40*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 41*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 422a26d47aSJingu Kang br label %for.inc 432a26d47aSJingu Kang 442a26d47aSJingu Kangif.else: 452a26d47aSJingu Kang br label %for.inc 462a26d47aSJingu Kang 472a26d47aSJingu Kangfor.inc: 482a26d47aSJingu Kang %inc = add nuw nsw i64 %iv, 1 492a26d47aSJingu Kang %cond = icmp sgt i64 %inc, %n 502a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 512a26d47aSJingu Kang 522a26d47aSJingu Kangexit: 532a26d47aSJingu Kang ret void 542a26d47aSJingu Kang} 552a26d47aSJingu Kang 562a26d47aSJingu Kang; The transformation works with this test because we can guarantee the split 572a26d47aSJingu Kang; condition is always true in pre-loop after transformation. 58*dfc4a956SNikita Popovdefine void @umax_variable_split_loop_bound_and_exit_cond_inc_with_sgt(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 592a26d47aSJingu Kang; CHECK-LABEL: @umax_variable_split_loop_bound_and_exit_cond_inc_with_sgt( 602a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 612a26d47aSJingu Kang; CHECK-NEXT: [[B:%.*]] = call i64 @llvm.umax.i64(i64 [[A:%.*]], i64 1) 62a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_PH_SPLIT:%.*]] 63a2a0ac42SJingu Kang; CHECK: loop.ph.split: 64a2a0ac42SJingu Kang; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0) 652a26d47aSJingu Kang; CHECK-NEXT: [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 [[B]]) 66a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 67a2a0ac42SJingu Kang; CHECK: loop: 68a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ] 692a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[B]] 70a2a0ac42SJingu Kang; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 71a2a0ac42SJingu Kang; CHECK: if.then: 72*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 73*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 74*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 75*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 76a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 77a2a0ac42SJingu Kang; CHECK: if.else: 78a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 79a2a0ac42SJingu Kang; CHECK: for.inc: 80a2a0ac42SJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 81a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]] 82a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]] 83a2a0ac42SJingu Kang; CHECK: loop.ph.split.split: 844c98070cSJingu Kang; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ] 854c98070cSJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]] 86a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]] 87a2a0ac42SJingu Kang; CHECK: loop.split.preheader: 88a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_SPLIT:%.*]] 89a2a0ac42SJingu Kang; CHECK: loop.split: 904c98070cSJingu Kang; CHECK-NEXT: [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 912a26d47aSJingu Kang; CHECK-NEXT: [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], [[B]] 922a26d47aSJingu Kang; CHECK-NEXT: br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]] 932a26d47aSJingu Kang; CHECK: if.else.split: 942a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 952a26d47aSJingu Kang; CHECK: if.then.split: 96*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]] 97*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4 98*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]] 99*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4 1002a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 1012a26d47aSJingu Kang; CHECK: for.inc.split: 1022a26d47aSJingu Kang; CHECK-NEXT: [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1 1032a26d47aSJingu Kang; CHECK-NEXT: [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]] 1042a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]] 1052a26d47aSJingu Kang; CHECK: exit.loopexit: 1062a26d47aSJingu Kang; CHECK-NEXT: br label [[EXIT]] 1072a26d47aSJingu Kang; CHECK: exit: 1082a26d47aSJingu Kang; CHECK-NEXT: ret void 1092a26d47aSJingu Kang; 1102a26d47aSJingu Kangloop.ph: 1112a26d47aSJingu Kang %b = call i64 @llvm.umax.i64(i64 %a, i64 1) 1122a26d47aSJingu Kang br label %loop 1132a26d47aSJingu Kang 1142a26d47aSJingu Kangloop: 1152a26d47aSJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 1162a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %b 1172a26d47aSJingu Kang br i1 %cmp, label %if.then, label %if.else 1182a26d47aSJingu Kang 1192a26d47aSJingu Kangif.then: 120*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 121*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 122*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 123*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 1242a26d47aSJingu Kang br label %for.inc 1252a26d47aSJingu Kang 1262a26d47aSJingu Kangif.else: 1272a26d47aSJingu Kang br label %for.inc 1282a26d47aSJingu Kang 1292a26d47aSJingu Kangfor.inc: 1302a26d47aSJingu Kang %inc = add nuw nsw i64 %iv, 1 1312a26d47aSJingu Kang %cond = icmp sgt i64 %inc, %n 1322a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 1332a26d47aSJingu Kang 1342a26d47aSJingu Kangexit: 1352a26d47aSJingu Kang ret void 1362a26d47aSJingu Kang} 1372a26d47aSJingu Kang 1382a26d47aSJingu Kang; The transformation works with this test because we can guarantee the split 1392a26d47aSJingu Kang; condition is always true in pre-loop after transformation. 140*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_inc_with_sgt(ptr noalias %src, ptr noalias %dst, i64 %n) { 1412a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_sgt( 1422a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 1432a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP_PH_SPLIT:%.*]] 1442a26d47aSJingu Kang; CHECK: loop.ph.split: 1452a26d47aSJingu Kang; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0) 1462a26d47aSJingu Kang; CHECK-NEXT: [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 10) 1472a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 1482a26d47aSJingu Kang; CHECK: loop: 1492a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ] 1502a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 1512a26d47aSJingu Kang; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1522a26d47aSJingu Kang; CHECK: if.then: 153*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 154*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 155*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 156*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 1572a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 1582a26d47aSJingu Kang; CHECK: if.else: 1592a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 1602a26d47aSJingu Kang; CHECK: for.inc: 1612a26d47aSJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 1622a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]] 1632a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]] 1642a26d47aSJingu Kang; CHECK: loop.ph.split.split: 1654c98070cSJingu Kang; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ] 1664c98070cSJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]] 1672a26d47aSJingu Kang; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]] 1682a26d47aSJingu Kang; CHECK: loop.split.preheader: 1692a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP_SPLIT:%.*]] 1702a26d47aSJingu Kang; CHECK: loop.split: 1714c98070cSJingu Kang; CHECK-NEXT: [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 1722a26d47aSJingu Kang; CHECK-NEXT: [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10 173a2a0ac42SJingu Kang; CHECK-NEXT: br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]] 174a2a0ac42SJingu Kang; CHECK: if.else.split: 175a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 176a2a0ac42SJingu Kang; CHECK: if.then.split: 177*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]] 178*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4 179*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]] 180*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4 181a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 182a2a0ac42SJingu Kang; CHECK: for.inc.split: 183a2a0ac42SJingu Kang; CHECK-NEXT: [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1 184a2a0ac42SJingu Kang; CHECK-NEXT: [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]] 185a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]] 186a2a0ac42SJingu Kang; CHECK: exit.loopexit: 187a2a0ac42SJingu Kang; CHECK-NEXT: br label [[EXIT]] 188a2a0ac42SJingu Kang; CHECK: exit: 189a2a0ac42SJingu Kang; CHECK-NEXT: ret void 190a2a0ac42SJingu Kang; 191a2a0ac42SJingu Kangloop.ph: 192a2a0ac42SJingu Kang br label %loop 193a2a0ac42SJingu Kang 194a2a0ac42SJingu Kangloop: 195a2a0ac42SJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 1962a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 197a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %if.else 198a2a0ac42SJingu Kang 199a2a0ac42SJingu Kangif.then: 200*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 201*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 202*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 203*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 204a2a0ac42SJingu Kang br label %for.inc 205a2a0ac42SJingu Kang 206a2a0ac42SJingu Kangif.else: 207a2a0ac42SJingu Kang br label %for.inc 208a2a0ac42SJingu Kang 209a2a0ac42SJingu Kangfor.inc: 210a2a0ac42SJingu Kang %inc = add nuw nsw i64 %iv, 1 211a2a0ac42SJingu Kang %cond = icmp sgt i64 %inc, %n 212a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 213a2a0ac42SJingu Kang 214a2a0ac42SJingu Kangexit: 215a2a0ac42SJingu Kang ret void 216a2a0ac42SJingu Kang} 217a2a0ac42SJingu Kang 218*dfc4a956SNikita Popovdefine void @variable_split_loop_bound_and_exit_cond_inc_with_eq(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 2192a26d47aSJingu Kang; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_eq( 2202a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 2212a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 2222a26d47aSJingu Kang; CHECK: loop: 2232a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 2242a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 2252a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 2262a26d47aSJingu Kang; CHECK: if.then: 227*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 228*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 229*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 230*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 2312a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 2322a26d47aSJingu Kang; CHECK: if.else: 2332a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 2342a26d47aSJingu Kang; CHECK: for.inc: 2352a26d47aSJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 2362a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[INC]], [[N:%.*]] 2372a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 2382a26d47aSJingu Kang; CHECK: exit: 2392a26d47aSJingu Kang; CHECK-NEXT: ret void 2402a26d47aSJingu Kang; 2412a26d47aSJingu Kangloop.ph: 2422a26d47aSJingu Kang br label %loop 2432a26d47aSJingu Kang 2442a26d47aSJingu Kangloop: 2452a26d47aSJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 2462a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 2472a26d47aSJingu Kang br i1 %cmp, label %if.then, label %if.else 2482a26d47aSJingu Kang 2492a26d47aSJingu Kangif.then: 250*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 251*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 252*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 253*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 2542a26d47aSJingu Kang br label %for.inc 2552a26d47aSJingu Kang 2562a26d47aSJingu Kangif.else: 2572a26d47aSJingu Kang br label %for.inc 2582a26d47aSJingu Kang 2592a26d47aSJingu Kangfor.inc: 2602a26d47aSJingu Kang %inc = add nuw nsw i64 %iv, 1 2612a26d47aSJingu Kang %cond = icmp eq i64 %inc, %n 2622a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 2632a26d47aSJingu Kang 2642a26d47aSJingu Kangexit: 2652a26d47aSJingu Kang ret void 2662a26d47aSJingu Kang} 2672a26d47aSJingu Kang 268*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_inc_with_eq(ptr noalias %src, ptr noalias %dst, i64 %n) { 2692a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_eq( 270a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 271a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_PH_SPLIT:%.*]] 272a2a0ac42SJingu Kang; CHECK: loop.ph.split: 273a2a0ac42SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], -1 2742a26d47aSJingu Kang; CHECK-NEXT: [[NEW_BOUND:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP0]], i64 10) 275a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 276a2a0ac42SJingu Kang; CHECK: loop: 277a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ] 2782a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 279a2a0ac42SJingu Kang; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 280a2a0ac42SJingu Kang; CHECK: if.then: 281*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 282*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 283*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 284*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 285a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 286a2a0ac42SJingu Kang; CHECK: if.else: 287a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 288a2a0ac42SJingu Kang; CHECK: for.inc: 289a2a0ac42SJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 290a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[INC]], [[NEW_BOUND]] 291a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]] 292a2a0ac42SJingu Kang; CHECK: loop.ph.split.split: 2934c98070cSJingu Kang; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ] 2944c98070cSJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]] 295a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]] 296a2a0ac42SJingu Kang; CHECK: loop.split.preheader: 297a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_SPLIT:%.*]] 298a2a0ac42SJingu Kang; CHECK: loop.split: 2994c98070cSJingu Kang; CHECK-NEXT: [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 3002a26d47aSJingu Kang; CHECK-NEXT: [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10 301a2a0ac42SJingu Kang; CHECK-NEXT: br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]] 302a2a0ac42SJingu Kang; CHECK: if.else.split: 303a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 304a2a0ac42SJingu Kang; CHECK: if.then.split: 305*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]] 306*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4 307*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]] 308*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4 309a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 310a2a0ac42SJingu Kang; CHECK: for.inc.split: 311a2a0ac42SJingu Kang; CHECK-NEXT: [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1 312a2a0ac42SJingu Kang; CHECK-NEXT: [[COND_SPLIT:%.*]] = icmp eq i64 [[INC_SPLIT]], [[N]] 313a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]] 314a2a0ac42SJingu Kang; CHECK: exit.loopexit: 315a2a0ac42SJingu Kang; CHECK-NEXT: br label [[EXIT]] 316a2a0ac42SJingu Kang; CHECK: exit: 317a2a0ac42SJingu Kang; CHECK-NEXT: ret void 318a2a0ac42SJingu Kang; 319a2a0ac42SJingu Kangloop.ph: 320a2a0ac42SJingu Kang br label %loop 321a2a0ac42SJingu Kang 322a2a0ac42SJingu Kangloop: 323a2a0ac42SJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 3242a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 325a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %if.else 326a2a0ac42SJingu Kang 327a2a0ac42SJingu Kangif.then: 328*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 329*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 330*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 331*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 332a2a0ac42SJingu Kang br label %for.inc 333a2a0ac42SJingu Kang 334a2a0ac42SJingu Kangif.else: 335a2a0ac42SJingu Kang br label %for.inc 336a2a0ac42SJingu Kang 337a2a0ac42SJingu Kangfor.inc: 338a2a0ac42SJingu Kang %inc = add nuw nsw i64 %iv, 1 339a2a0ac42SJingu Kang %cond = icmp eq i64 %inc, %n 340a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 341a2a0ac42SJingu Kang 342a2a0ac42SJingu Kangexit: 343a2a0ac42SJingu Kang ret void 344a2a0ac42SJingu Kang} 345a2a0ac42SJingu Kang 346*dfc4a956SNikita Popovdefine void @variable_split_loop_bound_and_exit_cond_inc_with_sge(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 3472a26d47aSJingu Kang; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_sge( 3482a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 3492a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 3502a26d47aSJingu Kang; CHECK: loop: 3512a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 3522a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 3532a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 3542a26d47aSJingu Kang; CHECK: if.then: 355*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 356*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 357*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 358*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 3592a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 3602a26d47aSJingu Kang; CHECK: if.else: 3612a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 3622a26d47aSJingu Kang; CHECK: for.inc: 3632a26d47aSJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 3642a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sge i64 [[INC]], [[N:%.*]] 3652a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 3662a26d47aSJingu Kang; CHECK: exit: 3672a26d47aSJingu Kang; CHECK-NEXT: ret void 3682a26d47aSJingu Kang; 3692a26d47aSJingu Kangloop.ph: 3702a26d47aSJingu Kang br label %loop 3712a26d47aSJingu Kang 3722a26d47aSJingu Kangloop: 3732a26d47aSJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 3742a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 3752a26d47aSJingu Kang br i1 %cmp, label %if.then, label %if.else 3762a26d47aSJingu Kang 3772a26d47aSJingu Kangif.then: 378*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 379*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 380*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 381*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 3822a26d47aSJingu Kang br label %for.inc 3832a26d47aSJingu Kang 3842a26d47aSJingu Kangif.else: 3852a26d47aSJingu Kang br label %for.inc 3862a26d47aSJingu Kang 3872a26d47aSJingu Kangfor.inc: 3882a26d47aSJingu Kang %inc = add nuw nsw i64 %iv, 1 3892a26d47aSJingu Kang %cond = icmp sge i64 %inc, %n 3902a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 3912a26d47aSJingu Kang 3922a26d47aSJingu Kangexit: 3932a26d47aSJingu Kang ret void 3942a26d47aSJingu Kang} 3952a26d47aSJingu Kang 396*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_inc_with_sge(ptr noalias %src, ptr noalias %dst, i64 %n) { 3972a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_sge( 398a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 399a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_PH_SPLIT:%.*]] 400a2a0ac42SJingu Kang; CHECK: loop.ph.split: 401a2a0ac42SJingu Kang; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 1) 402a2a0ac42SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[SMAX]], -1 4032a26d47aSJingu Kang; CHECK-NEXT: [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 10) 404a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 405a2a0ac42SJingu Kang; CHECK: loop: 406a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ] 4072a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 408a2a0ac42SJingu Kang; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 409a2a0ac42SJingu Kang; CHECK: if.then: 410*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 411*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 412*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 413*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 414a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 415a2a0ac42SJingu Kang; CHECK: if.else: 416a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 417a2a0ac42SJingu Kang; CHECK: for.inc: 418a2a0ac42SJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 419a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sge i64 [[INC]], [[NEW_BOUND]] 420a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]] 421a2a0ac42SJingu Kang; CHECK: loop.ph.split.split: 4224c98070cSJingu Kang; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ] 4234c98070cSJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]] 424a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]] 425a2a0ac42SJingu Kang; CHECK: loop.split.preheader: 426a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_SPLIT:%.*]] 427a2a0ac42SJingu Kang; CHECK: loop.split: 4284c98070cSJingu Kang; CHECK-NEXT: [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 4292a26d47aSJingu Kang; CHECK-NEXT: [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10 430a2a0ac42SJingu Kang; CHECK-NEXT: br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]] 431a2a0ac42SJingu Kang; CHECK: if.else.split: 432a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 433a2a0ac42SJingu Kang; CHECK: if.then.split: 434*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]] 435*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4 436*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]] 437*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4 438a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 439a2a0ac42SJingu Kang; CHECK: for.inc.split: 440a2a0ac42SJingu Kang; CHECK-NEXT: [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1 441a2a0ac42SJingu Kang; CHECK-NEXT: [[COND_SPLIT:%.*]] = icmp sge i64 [[INC_SPLIT]], [[N]] 442a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]] 443a2a0ac42SJingu Kang; CHECK: exit.loopexit: 444a2a0ac42SJingu Kang; CHECK-NEXT: br label [[EXIT]] 445a2a0ac42SJingu Kang; CHECK: exit: 446a2a0ac42SJingu Kang; CHECK-NEXT: ret void 447a2a0ac42SJingu Kang; 448a2a0ac42SJingu Kangloop.ph: 449a2a0ac42SJingu Kang br label %loop 450a2a0ac42SJingu Kang 451a2a0ac42SJingu Kangloop: 452a2a0ac42SJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 4532a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 454a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %if.else 455a2a0ac42SJingu Kang 456a2a0ac42SJingu Kangif.then: 457*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 458*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 459*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 460*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 461a2a0ac42SJingu Kang br label %for.inc 462a2a0ac42SJingu Kang 463a2a0ac42SJingu Kangif.else: 464a2a0ac42SJingu Kang br label %for.inc 465a2a0ac42SJingu Kang 466a2a0ac42SJingu Kangfor.inc: 467a2a0ac42SJingu Kang %inc = add nuw nsw i64 %iv, 1 468a2a0ac42SJingu Kang %cond = icmp sge i64 %inc, %n 469a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 470a2a0ac42SJingu Kang 471a2a0ac42SJingu Kangexit: 472a2a0ac42SJingu Kang ret void 473a2a0ac42SJingu Kang} 474a2a0ac42SJingu Kang 475*dfc4a956SNikita Popovdefine void @variable_split_loop_bound_and_exit_cond_inc_with_step_is_not_one(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 4762a26d47aSJingu Kang; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_step_is_not_one( 4772a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 4782a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 4792a26d47aSJingu Kang; CHECK: loop: 4802a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 4812a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 4822a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 4832a26d47aSJingu Kang; CHECK: if.then: 484*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 485*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 486*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 487*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 4882a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 4892a26d47aSJingu Kang; CHECK: if.else: 4902a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 4912a26d47aSJingu Kang; CHECK: for.inc: 4922a26d47aSJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 2 4932a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[INC]], [[N:%.*]] 4942a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 4952a26d47aSJingu Kang; CHECK: exit: 4962a26d47aSJingu Kang; CHECK-NEXT: ret void 4972a26d47aSJingu Kang; 4982a26d47aSJingu Kangloop.ph: 4992a26d47aSJingu Kang br label %loop 5002a26d47aSJingu Kang 5012a26d47aSJingu Kangloop: 5022a26d47aSJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 5032a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 5042a26d47aSJingu Kang br i1 %cmp, label %if.then, label %if.else 5052a26d47aSJingu Kang 5062a26d47aSJingu Kangif.then: 507*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 508*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 509*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 510*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 5112a26d47aSJingu Kang br label %for.inc 5122a26d47aSJingu Kang 5132a26d47aSJingu Kangif.else: 5142a26d47aSJingu Kang br label %for.inc 5152a26d47aSJingu Kang 5162a26d47aSJingu Kangfor.inc: 5172a26d47aSJingu Kang %inc = add nuw nsw i64 %iv, 2 5182a26d47aSJingu Kang %cond = icmp sgt i64 %inc, %n 5192a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 5202a26d47aSJingu Kang 5212a26d47aSJingu Kangexit: 5222a26d47aSJingu Kang ret void 5232a26d47aSJingu Kang} 5242a26d47aSJingu Kang 525*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_inc_with_step_is_not_one(ptr noalias %src, ptr noalias %dst, i64 %n) { 5262a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_step_is_not_one( 527a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 528a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_PH_SPLIT:%.*]] 529a2a0ac42SJingu Kang; CHECK: loop.ph.split: 530a2a0ac42SJingu Kang; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 1) 531a2a0ac42SJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = lshr i64 [[SMAX]], 1 5322a26d47aSJingu Kang; CHECK-NEXT: [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 10) 533a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 534a2a0ac42SJingu Kang; CHECK: loop: 535a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ] 5362a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 537a2a0ac42SJingu Kang; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 538a2a0ac42SJingu Kang; CHECK: if.then: 539*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 540*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 541*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 542*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 543a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 544a2a0ac42SJingu Kang; CHECK: if.else: 545a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 546a2a0ac42SJingu Kang; CHECK: for.inc: 547a2a0ac42SJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 2 548a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]] 549a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]] 550a2a0ac42SJingu Kang; CHECK: loop.ph.split.split: 5514c98070cSJingu Kang; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ] 5524c98070cSJingu Kang; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]] 553a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]] 554a2a0ac42SJingu Kang; CHECK: loop.split.preheader: 555a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP_SPLIT:%.*]] 556a2a0ac42SJingu Kang; CHECK: loop.split: 5574c98070cSJingu Kang; CHECK-NEXT: [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 5582a26d47aSJingu Kang; CHECK-NEXT: [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10 559a2a0ac42SJingu Kang; CHECK-NEXT: br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]] 560a2a0ac42SJingu Kang; CHECK: if.else.split: 561a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 562a2a0ac42SJingu Kang; CHECK: if.then.split: 563*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]] 564*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4 565*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]] 566*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4 567a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 568a2a0ac42SJingu Kang; CHECK: for.inc.split: 569a2a0ac42SJingu Kang; CHECK-NEXT: [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 2 570a2a0ac42SJingu Kang; CHECK-NEXT: [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]] 571a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]] 572a2a0ac42SJingu Kang; CHECK: exit.loopexit: 573a2a0ac42SJingu Kang; CHECK-NEXT: br label [[EXIT]] 574a2a0ac42SJingu Kang; CHECK: exit: 575a2a0ac42SJingu Kang; CHECK-NEXT: ret void 576a2a0ac42SJingu Kang; 577a2a0ac42SJingu Kangloop.ph: 578a2a0ac42SJingu Kang br label %loop 579a2a0ac42SJingu Kang 580a2a0ac42SJingu Kangloop: 581a2a0ac42SJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 5822a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 583a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %if.else 584a2a0ac42SJingu Kang 585a2a0ac42SJingu Kangif.then: 586*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 587*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 588*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 589*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 590a2a0ac42SJingu Kang br label %for.inc 591a2a0ac42SJingu Kang 592a2a0ac42SJingu Kangif.else: 593a2a0ac42SJingu Kang br label %for.inc 594a2a0ac42SJingu Kang 595a2a0ac42SJingu Kangfor.inc: 596a2a0ac42SJingu Kang %inc = add nuw nsw i64 %iv, 2 597a2a0ac42SJingu Kang %cond = icmp sgt i64 %inc, %n 598a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 599a2a0ac42SJingu Kang 600a2a0ac42SJingu Kangexit: 601a2a0ac42SJingu Kang ret void 602a2a0ac42SJingu Kang} 603a2a0ac42SJingu Kang 604*dfc4a956SNikita Popovdefine void @variable_split_loop_bound_and_exit_cond_inc_with_ne(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 6052a26d47aSJingu Kang; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_ne( 606a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 607a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 608a2a0ac42SJingu Kang; CHECK: loop: 609a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 6102a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 611a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_INC]] 612a2a0ac42SJingu Kang; CHECK: if.then: 613*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 614*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 615*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 616*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 617a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 618a2a0ac42SJingu Kang; CHECK: for.inc: 619a2a0ac42SJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 620a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp ne i64 [[INC]], [[N:%.*]] 621a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 622a2a0ac42SJingu Kang; CHECK: exit: 623a2a0ac42SJingu Kang; CHECK-NEXT: ret void 624a2a0ac42SJingu Kang; 625a2a0ac42SJingu Kangloop.ph: 626a2a0ac42SJingu Kang br label %loop 627a2a0ac42SJingu Kang 628a2a0ac42SJingu Kangloop: 629a2a0ac42SJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 6302a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 631a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %for.inc 632a2a0ac42SJingu Kang 633a2a0ac42SJingu Kangif.then: 634*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 635*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 636*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 637*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 638a2a0ac42SJingu Kang br label %for.inc 639a2a0ac42SJingu Kang 640a2a0ac42SJingu Kangfor.inc: 641a2a0ac42SJingu Kang %inc = add nuw nsw i64 %iv, 1 642a2a0ac42SJingu Kang %cond = icmp ne i64 %inc, %n 643a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 644a2a0ac42SJingu Kang 645a2a0ac42SJingu Kangexit: 646a2a0ac42SJingu Kang ret void 647a2a0ac42SJingu Kang} 648a2a0ac42SJingu Kang 649*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_inc_with_ne(ptr noalias %src, ptr noalias %dst, i64 %n) { 6502a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_ne( 6512a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 6522a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 6532a26d47aSJingu Kang; CHECK: loop: 6542a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 6552a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 6562a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_INC]] 6572a26d47aSJingu Kang; CHECK: if.then: 658*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 659*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 660*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 661*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 6622a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 6632a26d47aSJingu Kang; CHECK: for.inc: 6642a26d47aSJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 6652a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp ne i64 [[INC]], [[N:%.*]] 6662a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 6672a26d47aSJingu Kang; CHECK: exit: 6682a26d47aSJingu Kang; CHECK-NEXT: ret void 6692a26d47aSJingu Kang; 6702a26d47aSJingu Kangloop.ph: 6712a26d47aSJingu Kang br label %loop 6722a26d47aSJingu Kang 6732a26d47aSJingu Kangloop: 6742a26d47aSJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 6752a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 6762a26d47aSJingu Kang br i1 %cmp, label %if.then, label %for.inc 6772a26d47aSJingu Kang 6782a26d47aSJingu Kangif.then: 679*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 680*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 681*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 682*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 6832a26d47aSJingu Kang br label %for.inc 6842a26d47aSJingu Kang 6852a26d47aSJingu Kangfor.inc: 6862a26d47aSJingu Kang %inc = add nuw nsw i64 %iv, 1 6872a26d47aSJingu Kang %cond = icmp ne i64 %inc, %n 6882a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 6892a26d47aSJingu Kang 6902a26d47aSJingu Kangexit: 6912a26d47aSJingu Kang ret void 6922a26d47aSJingu Kang} 6932a26d47aSJingu Kang 694*dfc4a956SNikita Popovdefine void @varialbe_split_loop_bound_and_exit_cond_dec_with_slt(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 6952a26d47aSJingu Kang; CHECK-LABEL: @varialbe_split_loop_bound_and_exit_cond_dec_with_slt( 696a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 697a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 698a2a0ac42SJingu Kang; CHECK: loop: 699a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 7002a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 701a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]] 702a2a0ac42SJingu Kang; CHECK: if.then: 703*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 704*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 705*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 706*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 707a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_DEC]] 708a2a0ac42SJingu Kang; CHECK: for.dec: 709a2a0ac42SJingu Kang; CHECK-NEXT: [[DEC]] = sub nuw nsw i64 [[IV]], 1 710a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp slt i64 [[DEC]], [[N:%.*]] 711a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 712a2a0ac42SJingu Kang; CHECK: exit: 713a2a0ac42SJingu Kang; CHECK-NEXT: ret void 714a2a0ac42SJingu Kang; 715a2a0ac42SJingu Kangloop.ph: 716a2a0ac42SJingu Kang br label %loop 717a2a0ac42SJingu Kang 718a2a0ac42SJingu Kangloop: 719a2a0ac42SJingu Kang %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ] 7202a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 721a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %for.dec 722a2a0ac42SJingu Kang 723a2a0ac42SJingu Kangif.then: 724*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 725*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 726*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 727*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 728a2a0ac42SJingu Kang br label %for.dec 729a2a0ac42SJingu Kang 730a2a0ac42SJingu Kangfor.dec: 731a2a0ac42SJingu Kang %dec = sub nuw nsw i64 %iv, 1 732a2a0ac42SJingu Kang %cond = icmp slt i64 %dec, %n 733a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 734a2a0ac42SJingu Kang 735a2a0ac42SJingu Kangexit: 736a2a0ac42SJingu Kang ret void 737a2a0ac42SJingu Kang} 738a2a0ac42SJingu Kang 739*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_dec_with_slt(ptr noalias %src, ptr noalias %dst, i64 %n) { 7402a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_dec_with_slt( 741a2a0ac42SJingu Kang; CHECK-NEXT: loop.ph: 742a2a0ac42SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 743a2a0ac42SJingu Kang; CHECK: loop: 744a2a0ac42SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 7452a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 7462a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]] 7472a26d47aSJingu Kang; CHECK: if.then: 748*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 749*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 750*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 751*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 7522a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_DEC]] 7532a26d47aSJingu Kang; CHECK: for.dec: 7542a26d47aSJingu Kang; CHECK-NEXT: [[DEC]] = sub nuw nsw i64 [[IV]], 1 7552a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp slt i64 [[DEC]], [[N:%.*]] 7562a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 7572a26d47aSJingu Kang; CHECK: exit: 7582a26d47aSJingu Kang; CHECK-NEXT: ret void 7592a26d47aSJingu Kang; 7602a26d47aSJingu Kangloop.ph: 7612a26d47aSJingu Kang br label %loop 7622a26d47aSJingu Kang 7632a26d47aSJingu Kangloop: 7642a26d47aSJingu Kang %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ] 7652a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 7662a26d47aSJingu Kang br i1 %cmp, label %if.then, label %for.dec 7672a26d47aSJingu Kang 7682a26d47aSJingu Kangif.then: 769*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 770*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 771*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 772*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 7732a26d47aSJingu Kang br label %for.dec 7742a26d47aSJingu Kang 7752a26d47aSJingu Kangfor.dec: 7762a26d47aSJingu Kang %dec = sub nuw nsw i64 %iv, 1 7772a26d47aSJingu Kang %cond = icmp slt i64 %dec, %n 7782a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 7792a26d47aSJingu Kang 7802a26d47aSJingu Kangexit: 7812a26d47aSJingu Kang ret void 7822a26d47aSJingu Kang} 7832a26d47aSJingu Kang 784*dfc4a956SNikita Popovdefine void @variable_split_loop_bound_and_exit_cond_dec_with_sle(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) { 7852a26d47aSJingu Kang; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_dec_with_sle( 7862a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 7872a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 7882a26d47aSJingu Kang; CHECK: loop: 7892a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 7902a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]] 791a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]] 792a2a0ac42SJingu Kang; CHECK: if.then: 793*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 794*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 795*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 796*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 797a2a0ac42SJingu Kang; CHECK-NEXT: br label [[FOR_DEC]] 798a2a0ac42SJingu Kang; CHECK: for.dec: 799a2a0ac42SJingu Kang; CHECK-NEXT: [[DEC]] = sub nuw nsw i64 [[IV]], 1 800a2a0ac42SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sle i64 [[DEC]], [[N:%.*]] 801a2a0ac42SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 802a2a0ac42SJingu Kang; CHECK: exit: 803a2a0ac42SJingu Kang; CHECK-NEXT: ret void 804a2a0ac42SJingu Kang; 805a2a0ac42SJingu Kangloop.ph: 806a2a0ac42SJingu Kang br label %loop 807a2a0ac42SJingu Kang 808a2a0ac42SJingu Kangloop: 809a2a0ac42SJingu Kang %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ] 8102a26d47aSJingu Kang %cmp = icmp ult i64 %iv, %a 8112a26d47aSJingu Kang br i1 %cmp, label %if.then, label %for.dec 8122a26d47aSJingu Kang 8132a26d47aSJingu Kangif.then: 814*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 815*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 816*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 817*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 8182a26d47aSJingu Kang br label %for.dec 8192a26d47aSJingu Kang 8202a26d47aSJingu Kangfor.dec: 8212a26d47aSJingu Kang %dec = sub nuw nsw i64 %iv, 1 8222a26d47aSJingu Kang %cond = icmp sle i64 %dec, %n 8232a26d47aSJingu Kang br i1 %cond, label %exit, label %loop 8242a26d47aSJingu Kang 8252a26d47aSJingu Kangexit: 8262a26d47aSJingu Kang ret void 8272a26d47aSJingu Kang} 8282a26d47aSJingu Kang 829*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_dec_with_sle(ptr noalias %src, ptr noalias %dst, i64 %n) { 8302a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_dec_with_sle( 8312a26d47aSJingu Kang; CHECK-NEXT: loop.ph: 8322a26d47aSJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 8332a26d47aSJingu Kang; CHECK: loop: 8342a26d47aSJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ] 8352a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 8362a26d47aSJingu Kang; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]] 8372a26d47aSJingu Kang; CHECK: if.then: 838*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 839*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 840*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 841*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 8422a26d47aSJingu Kang; CHECK-NEXT: br label [[FOR_DEC]] 8432a26d47aSJingu Kang; CHECK: for.dec: 8442a26d47aSJingu Kang; CHECK-NEXT: [[DEC]] = sub nuw nsw i64 [[IV]], 1 8452a26d47aSJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sle i64 [[DEC]], [[N:%.*]] 8462a26d47aSJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 8472a26d47aSJingu Kang; CHECK: exit: 8482a26d47aSJingu Kang; CHECK-NEXT: ret void 8492a26d47aSJingu Kang; 8502a26d47aSJingu Kangloop.ph: 8512a26d47aSJingu Kang br label %loop 8522a26d47aSJingu Kang 8532a26d47aSJingu Kangloop: 8542a26d47aSJingu Kang %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ] 8552a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 856a2a0ac42SJingu Kang br i1 %cmp, label %if.then, label %for.dec 857a2a0ac42SJingu Kang 858a2a0ac42SJingu Kangif.then: 859*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 860*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 861*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 862*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 863a2a0ac42SJingu Kang br label %for.dec 864a2a0ac42SJingu Kang 865a2a0ac42SJingu Kangfor.dec: 866a2a0ac42SJingu Kang %dec = sub nuw nsw i64 %iv, 1 867a2a0ac42SJingu Kang %cond = icmp sle i64 %dec, %n 868a2a0ac42SJingu Kang br i1 %cond, label %exit, label %loop 869a2a0ac42SJingu Kang 870a2a0ac42SJingu Kangexit: 871a2a0ac42SJingu Kang ret void 872a2a0ac42SJingu Kang} 873a2a0ac42SJingu Kang 8748eee0202SJingu Kang; LoopBoundSplit pass should ignore phi which is not scevable phi. 875*dfc4a956SNikita Popovdefine void @constant_split_loop_bound_and_exit_cond_inc_with_sgt_and_is_not_scevable_phi(ptr noalias %src, ptr noalias %dst, i64 %n) { 8762a26d47aSJingu Kang; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_sgt_and_is_not_scevable_phi( 8778eee0202SJingu Kang; CHECK-NEXT: loop.ph: 8788eee0202SJingu Kang; CHECK-NEXT: br label [[LOOP_PH_SPLIT:%.*]] 8798eee0202SJingu Kang; CHECK: loop.ph.split: 8808eee0202SJingu Kang; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0) 8812a26d47aSJingu Kang; CHECK-NEXT: [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 10) 8828eee0202SJingu Kang; CHECK-NEXT: br label [[LOOP:%.*]] 8838eee0202SJingu Kang; CHECK: loop: 8848eee0202SJingu Kang; CHECK-NEXT: [[IS_NOT_SCEVABLE_PHI:%.*]] = phi double [ 1.000000e+00, [[FOR_INC:%.*]] ], [ 2.000000e+00, [[LOOP_PH_SPLIT]] ] 8858eee0202SJingu Kang; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC]] ], [ 0, [[LOOP_PH_SPLIT]] ] 8862a26d47aSJingu Kang; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[IV]], 10 8878eee0202SJingu Kang; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 8888eee0202SJingu Kang; CHECK: if.then: 889*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]] 890*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4 891*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]] 892*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4 8938eee0202SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 8948eee0202SJingu Kang; CHECK: if.else: 8958eee0202SJingu Kang; CHECK-NEXT: br label [[FOR_INC]] 8968eee0202SJingu Kang; CHECK: for.inc: 8978eee0202SJingu Kang; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1 8988eee0202SJingu Kang; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]] 8998eee0202SJingu Kang; CHECK-NEXT: br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]] 9008eee0202SJingu Kang; CHECK: loop.ph.split.split: 9014c98070cSJingu Kang; CHECK-NEXT: [[IS_NOT_SCEVABLE_PHI_LCSSA:%.*]] = phi double [ 1.000000e+00, [[FOR_INC]] ] 9024c98070cSJingu Kang; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ] 9034c98070cSJingu Kang; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]] 9048eee0202SJingu Kang; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]] 9058eee0202SJingu Kang; CHECK: loop.split.preheader: 9068eee0202SJingu Kang; CHECK-NEXT: br label [[LOOP_SPLIT:%.*]] 9078eee0202SJingu Kang; CHECK: loop.split: 9084c98070cSJingu Kang; CHECK-NEXT: [[IS_NOT_SCEVABLE_PHI_SPLIT:%.*]] = phi double [ 1.000000e+00, [[FOR_INC_SPLIT:%.*]] ], [ [[IS_NOT_SCEVABLE_PHI_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 9094c98070cSJingu Kang; CHECK-NEXT: [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ] 9102a26d47aSJingu Kang; CHECK-NEXT: [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10 9118eee0202SJingu Kang; CHECK-NEXT: br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]] 9128eee0202SJingu Kang; CHECK: if.else.split: 9138eee0202SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 9148eee0202SJingu Kang; CHECK: if.then.split: 915*dfc4a956SNikita Popov; CHECK-NEXT: [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]] 916*dfc4a956SNikita Popov; CHECK-NEXT: [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4 917*dfc4a956SNikita Popov; CHECK-NEXT: [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]] 918*dfc4a956SNikita Popov; CHECK-NEXT: store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4 9198eee0202SJingu Kang; CHECK-NEXT: br label [[FOR_INC_SPLIT]] 9208eee0202SJingu Kang; CHECK: for.inc.split: 9218eee0202SJingu Kang; CHECK-NEXT: [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1 9228eee0202SJingu Kang; CHECK-NEXT: [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]] 9238eee0202SJingu Kang; CHECK-NEXT: br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]] 9248eee0202SJingu Kang; CHECK: exit.loopexit: 9258eee0202SJingu Kang; CHECK-NEXT: br label [[EXIT]] 9268eee0202SJingu Kang; CHECK: exit: 9278eee0202SJingu Kang; CHECK-NEXT: ret void 9288eee0202SJingu Kang; 9298eee0202SJingu Kangloop.ph: 9308eee0202SJingu Kang br label %loop 9318eee0202SJingu Kang 9328eee0202SJingu Kangloop: 9338eee0202SJingu Kang %is_not_scevable_phi = phi double [ 1.0, %for.inc ], [ 2.0, %loop.ph ] 9348eee0202SJingu Kang %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ] 9352a26d47aSJingu Kang %cmp = icmp ult i64 %iv, 10 9368eee0202SJingu Kang br i1 %cmp, label %if.then, label %if.else 9378eee0202SJingu Kang 9388eee0202SJingu Kangif.then: 939*dfc4a956SNikita Popov %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv 940*dfc4a956SNikita Popov %val = load i64, ptr %src.arrayidx 941*dfc4a956SNikita Popov %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv 942*dfc4a956SNikita Popov store i64 %val, ptr %dst.arrayidx 9438eee0202SJingu Kang br label %for.inc 9448eee0202SJingu Kang 9458eee0202SJingu Kangif.else: 9468eee0202SJingu Kang br label %for.inc 9478eee0202SJingu Kang 9488eee0202SJingu Kangfor.inc: 9498eee0202SJingu Kang %inc = add nuw nsw i64 %iv, 1 9508eee0202SJingu Kang %cond = icmp sgt i64 %inc, %n 9518eee0202SJingu Kang br i1 %cond, label %exit, label %loop 9528eee0202SJingu Kang 9538eee0202SJingu Kangexit: 9548eee0202SJingu Kang ret void 9558eee0202SJingu Kang} 956a2a0ac42SJingu Kang 9572a26d47aSJingu Kangdeclare i64 @llvm.umax.i64(i64, i64) 958