xref: /llvm-project/llvm/test/Transforms/LoopBoundSplit/loop-bound-split.ll (revision dfc4a956f3df59287e0cf6652c0f72621aca6a6f)
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