xref: /llvm-project/llvm/test/Transforms/IRCE/variable-loop-bounds.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2; RUN: opt -passes=irce -S -verify-loop-info -irce-skip-profitability-checks < %s 2>&1 | FileCheck %s
3
4define void @test_inc_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
5; CHECK-LABEL: define void @test_inc_eq(
6; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[N]], 0
9; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
10; CHECK:       for.body.preheader:
11; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512)
12; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
13; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
14; CHECK:       for.body.preheader1:
15; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
16; CHECK:       for.cond.cleanup.loopexit.loopexit:
17; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
18; CHECK:       for.cond.cleanup.loopexit:
19; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
20; CHECK:       for.cond.cleanup:
21; CHECK-NEXT:    ret void
22; CHECK:       for.body:
23; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
24; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
25; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
26; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
27; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
28; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
29; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
30; CHECK:       if.then:
31; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
32; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
33; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
34; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
35; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
36; CHECK-NEXT:    br label [[FOR_INC]]
37; CHECK:       if.else:
38; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
39; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
40; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
41; CHECK-NEXT:    br label [[FOR_INC]]
42; CHECK:       for.inc:
43; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
44; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], [[N]]
45; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]]
46; CHECK-NEXT:    [[TMP5:%.*]] = xor i1 [[TMP4]], true
47; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]]
48; CHECK:       main.exit.selector:
49; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
50; CHECK-NEXT:    [[TMP6:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]]
51; CHECK-NEXT:    br i1 [[TMP6]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
52; CHECK:       main.pseudo.exit:
53; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
54; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
55; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
56; CHECK:       postloop:
57; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
58; CHECK:       for.body.postloop:
59; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
60; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
61; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
62; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
63; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
64; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
65; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
66; CHECK:       if.else.postloop:
67; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP8]], [[TMP7]]
68; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
69; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
70; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
71; CHECK:       if.then.postloop:
72; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP7]], [[TMP8]]
73; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
74; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
75; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP9]]
76; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
77; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
78; CHECK:       for.inc.postloop:
79; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
80; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp eq i32 [[INC_POSTLOOP]], [[N]]
81; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone [[META5:![0-9]+]]
82;
83entry:
84  %cmp16 = icmp sgt i32 %N, 0
85  br i1 %cmp16, label %for.body, label %for.cond.cleanup
86
87for.cond.cleanup:
88  ret void
89
90for.body:
91  %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
92  %cmp1 = icmp ult i32 %i.017, 512
93  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
94  %0 = load i32, ptr %arrayidx, align 4
95  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
96  %1 = load i32, ptr %arrayidx2, align 4
97  br i1 %cmp1, label %if.then, label %if.else
98
99if.then:
100  %sub = sub i32 %0, %1
101  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
102  %2 = load i32, ptr %arrayidx3, align 4
103  %add = add nsw i32 %sub, %2
104  store i32 %add, ptr %arrayidx3, align 4
105  br label %for.inc
106
107if.else:
108  %add6 = add nsw i32 %1, %0
109  %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
110  store i32 %add6, ptr %arrayidx7, align 4
111  br label %for.inc
112
113for.inc:
114  %inc = add nuw nsw i32 %i.017, 1
115  %exitcond = icmp eq i32 %inc, %N
116  br i1 %exitcond, label %for.cond.cleanup, label %for.body
117}
118
119define void @test_inc_ne(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
120; CHECK-LABEL: define void @test_inc_ne(
121; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) {
122; CHECK-NEXT:  entry:
123; CHECK-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[N]], 0
124; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
125; CHECK:       for.body.preheader:
126; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512)
127; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
128; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
129; CHECK:       for.body.preheader1:
130; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
131; CHECK:       for.cond.cleanup.loopexit.loopexit:
132; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
133; CHECK:       for.cond.cleanup.loopexit:
134; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
135; CHECK:       for.cond.cleanup:
136; CHECK-NEXT:    ret void
137; CHECK:       for.body:
138; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
139; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
140; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
141; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
142; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
143; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
144; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
145; CHECK:       if.then:
146; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
147; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
148; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
149; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
150; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
151; CHECK-NEXT:    br label [[FOR_INC]]
152; CHECK:       if.else:
153; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
154; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
155; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
156; CHECK-NEXT:    br label [[FOR_INC]]
157; CHECK:       for.inc:
158; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
159; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[INC]], [[N]]
160; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]]
161; CHECK-NEXT:    br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
162; CHECK:       main.exit.selector:
163; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
164; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]]
165; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
166; CHECK:       main.pseudo.exit:
167; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
168; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
169; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
170; CHECK:       postloop:
171; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
172; CHECK:       for.body.postloop:
173; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
174; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
175; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
176; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
177; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
178; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
179; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
180; CHECK:       if.else.postloop:
181; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]]
182; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
183; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
184; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
185; CHECK:       if.then.postloop:
186; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]]
187; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
188; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
189; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]]
190; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
191; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
192; CHECK:       for.inc.postloop:
193; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
194; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp ne i32 [[INC_POSTLOOP]], [[N]]
195; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP6:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
196;
197entry:
198  %cmp16 = icmp sgt i32 %N, 0
199  br i1 %cmp16, label %for.body, label %for.cond.cleanup
200
201for.cond.cleanup:
202  ret void
203
204for.body:
205  %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
206  %cmp1 = icmp ult i32 %i.017, 512
207  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
208  %0 = load i32, ptr %arrayidx, align 4
209  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
210  %1 = load i32, ptr %arrayidx2, align 4
211  br i1 %cmp1, label %if.then, label %if.else
212
213if.then:
214  %sub = sub i32 %0, %1
215  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
216  %2 = load i32, ptr %arrayidx3, align 4
217  %add = add nsw i32 %sub, %2
218  store i32 %add, ptr %arrayidx3, align 4
219  br label %for.inc
220
221if.else:
222  %add6 = add nsw i32 %1, %0
223  %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
224  store i32 %add6, ptr %arrayidx7, align 4
225  br label %for.inc
226
227for.inc:
228  %inc = add nuw nsw i32 %i.017, 1
229  %exitcond = icmp ne i32 %inc, %N
230  br i1 %exitcond, label %for.body, label %for.cond.cleanup
231}
232
233define void @test_inc_slt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
234; CHECK-LABEL: define void @test_inc_slt(
235; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) {
236; CHECK-NEXT:  entry:
237; CHECK-NEXT:    [[CMP16:%.*]] = icmp sgt i32 [[N]], 0
238; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
239; CHECK:       for.body.preheader:
240; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[N]], i32 512)
241; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.smax.i32(i32 [[SMIN]], i32 0)
242; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 0, [[EXIT_MAINLOOP_AT]]
243; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
244; CHECK:       for.body.preheader1:
245; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
246; CHECK:       for.cond.cleanup.loopexit.loopexit:
247; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
248; CHECK:       for.cond.cleanup.loopexit:
249; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
250; CHECK:       for.cond.cleanup:
251; CHECK-NEXT:    ret void
252; CHECK:       for.body:
253; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
254; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
255; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
256; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
257; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
258; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
259; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
260; CHECK:       if.then:
261; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
262; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
263; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
264; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
265; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
266; CHECK-NEXT:    br label [[FOR_INC]]
267; CHECK:       if.else:
268; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
269; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
270; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
271; CHECK-NEXT:    br label [[FOR_INC]]
272; CHECK:       for.inc:
273; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
274; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp slt i32 [[INC]], [[N]]
275; CHECK-NEXT:    [[TMP4:%.*]] = icmp slt i32 [[INC]], [[EXIT_MAINLOOP_AT]]
276; CHECK-NEXT:    br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
277; CHECK:       main.exit.selector:
278; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
279; CHECK-NEXT:    [[TMP5:%.*]] = icmp slt i32 [[INC_LCSSA]], [[N]]
280; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
281; CHECK:       main.pseudo.exit:
282; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
283; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
284; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
285; CHECK:       postloop:
286; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
287; CHECK:       for.body.postloop:
288; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
289; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
290; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
291; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
292; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
293; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
294; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
295; CHECK:       if.else.postloop:
296; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]]
297; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
298; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
299; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
300; CHECK:       if.then.postloop:
301; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]]
302; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
303; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
304; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]]
305; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
306; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
307; CHECK:       for.inc.postloop:
308; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
309; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp slt i32 [[INC_POSTLOOP]], [[N]]
310; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP7:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
311;
312entry:
313  %cmp16 = icmp sgt i32 %N, 0
314  br i1 %cmp16, label %for.body, label %for.cond.cleanup
315
316for.cond.cleanup:
317  ret void
318
319for.body:
320  %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
321  %cmp1 = icmp ult i32 %i.017, 512
322  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
323  %0 = load i32, ptr %arrayidx, align 4
324  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
325  %1 = load i32, ptr %arrayidx2, align 4
326  br i1 %cmp1, label %if.then, label %if.else
327
328if.then:
329  %sub = sub i32 %0, %1
330  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
331  %2 = load i32, ptr %arrayidx3, align 4
332  %add = add nsw i32 %sub, %2
333  store i32 %add, ptr %arrayidx3, align 4
334  br label %for.inc
335
336if.else:
337  %add6 = add nsw i32 %1, %0
338  %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
339  store i32 %add6, ptr %arrayidx7, align 4
340  br label %for.inc
341
342for.inc:
343  %inc = add nuw nsw i32 %i.017, 1
344  %exitcond = icmp slt i32 %inc, %N
345  br i1 %exitcond, label %for.body, label %for.cond.cleanup
346}
347
348define void @test_inc_ult(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
349; CHECK-LABEL: define void @test_inc_ult(
350; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[N:%.*]]) {
351; CHECK-NEXT:  entry:
352; CHECK-NEXT:    [[CMP16:%.*]] = icmp ugt i32 [[N]], 0
353; CHECK-NEXT:    br i1 [[CMP16]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
354; CHECK:       for.body.preheader:
355; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = call i32 @llvm.umin.i32(i32 [[N]], i32 512)
356; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 0, [[EXIT_MAINLOOP_AT]]
357; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_BODY_PREHEADER1:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
358; CHECK:       for.body.preheader1:
359; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
360; CHECK:       for.cond.cleanup.loopexit.loopexit:
361; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
362; CHECK:       for.cond.cleanup.loopexit:
363; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
364; CHECK:       for.cond.cleanup:
365; CHECK-NEXT:    ret void
366; CHECK:       for.body:
367; CHECK-NEXT:    [[I_017:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER1]] ]
368; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_017]], 512
369; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017]]
370; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
371; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017]]
372; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
373; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
374; CHECK:       if.then:
375; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP1]], [[TMP2]]
376; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
377; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
378; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[TMP3]]
379; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARRAYIDX3]], align 4
380; CHECK-NEXT:    br label [[FOR_INC]]
381; CHECK:       if.else:
382; CHECK-NEXT:    [[ADD6:%.*]] = add nsw i32 [[TMP2]], [[TMP1]]
383; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017]]
384; CHECK-NEXT:    store i32 [[ADD6]], ptr [[ARRAYIDX7]], align 4
385; CHECK-NEXT:    br label [[FOR_INC]]
386; CHECK:       for.inc:
387; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_017]], 1
388; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ult i32 [[INC]], [[N]]
389; CHECK-NEXT:    [[TMP4:%.*]] = icmp ult i32 [[INC]], [[EXIT_MAINLOOP_AT]]
390; CHECK-NEXT:    br i1 [[TMP4]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
391; CHECK:       main.exit.selector:
392; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[FOR_INC]] ]
393; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i32 [[INC_LCSSA]], [[N]]
394; CHECK-NEXT:    br i1 [[TMP5]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
395; CHECK:       main.pseudo.exit:
396; CHECK-NEXT:    [[I_017_COPY:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
397; CHECK-NEXT:    [[INDVAR_END:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
398; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
399; CHECK:       postloop:
400; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
401; CHECK:       for.body.postloop:
402; CHECK-NEXT:    [[I_017_POSTLOOP:%.*]] = phi i32 [ [[INC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[I_017_COPY]], [[POSTLOOP]] ]
403; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp ult i32 [[I_017_POSTLOOP]], 512
404; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_017_POSTLOOP]]
405; CHECK-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
406; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_017_POSTLOOP]]
407; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
408; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[IF_THEN_POSTLOOP:%.*]], label [[IF_ELSE_POSTLOOP:%.*]]
409; CHECK:       if.else.postloop:
410; CHECK-NEXT:    [[ADD6_POSTLOOP:%.*]] = add nsw i32 [[TMP7]], [[TMP6]]
411; CHECK-NEXT:    [[ARRAYIDX7_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
412; CHECK-NEXT:    store i32 [[ADD6_POSTLOOP]], ptr [[ARRAYIDX7_POSTLOOP]], align 4
413; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
414; CHECK:       if.then.postloop:
415; CHECK-NEXT:    [[SUB_POSTLOOP:%.*]] = sub i32 [[TMP6]], [[TMP7]]
416; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_017_POSTLOOP]]
417; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
418; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[SUB_POSTLOOP]], [[TMP8]]
419; CHECK-NEXT:    store i32 [[ADD_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
420; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
421; CHECK:       for.inc.postloop:
422; CHECK-NEXT:    [[INC_POSTLOOP]] = add nuw nsw i32 [[I_017_POSTLOOP]], 1
423; CHECK-NEXT:    [[EXITCOND_POSTLOOP:%.*]] = icmp ult i32 [[INC_POSTLOOP]], [[N]]
424; CHECK-NEXT:    br i1 [[EXITCOND_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
425;
426entry:
427  %cmp16 = icmp ugt i32 %N, 0
428  br i1 %cmp16, label %for.body, label %for.cond.cleanup
429
430for.cond.cleanup:
431  ret void
432
433for.body:
434  %i.017 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
435  %cmp1 = icmp ult i32 %i.017, 512
436  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.017
437  %0 = load i32, ptr %arrayidx, align 4
438  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %i.017
439  %1 = load i32, ptr %arrayidx2, align 4
440  br i1 %cmp1, label %if.then, label %if.else
441
442if.then:
443  %sub = sub i32 %0, %1
444  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %i.017
445  %2 = load i32, ptr %arrayidx3, align 4
446  %add = add nsw i32 %sub, %2
447  store i32 %add, ptr %arrayidx3, align 4
448  br label %for.inc
449
450if.else:
451  %add6 = add nsw i32 %1, %0
452  %arrayidx7 = getelementptr inbounds i32, ptr %a, i32 %i.017
453  store i32 %add6, ptr %arrayidx7, align 4
454  br label %for.inc
455
456for.inc:
457  %inc = add nuw nsw i32 %i.017, 1
458  %exitcond = icmp ult i32 %inc, %N
459  br i1 %exitcond, label %for.body, label %for.cond.cleanup
460}
461
462define void @signed_var_imm_dec_sgt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
463; CHECK-LABEL: define void @signed_var_imm_dec_sgt(
464; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) {
465; CHECK-NEXT:  entry:
466; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[M]], 1024
467; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
468; CHECK:       for.body.preheader:
469; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
470; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024)
471; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
472; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0)
473; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
474; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]]
475; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
476; CHECK:       for.body.preloop.preheader:
477; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
478; CHECK:       for.cond.cleanup.loopexit.loopexit:
479; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
480; CHECK:       for.cond.cleanup.loopexit:
481; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
482; CHECK:       for.cond.cleanup:
483; CHECK-NEXT:    ret void
484; CHECK:       mainloop:
485; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
486; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
487; CHECK:       for.body.preheader3:
488; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
489; CHECK:       for.body:
490; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
491; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
492; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
493; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
494; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
495; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
496; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
497; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
498; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
499; CHECK:       if.else:
500; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
501; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
502; CHECK-NEXT:    br label [[FOR_INC]]
503; CHECK:       for.inc:
504; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
505; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
506; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
507; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[M]]
508; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]]
509; CHECK-NEXT:    br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
510; CHECK:       main.exit.selector:
511; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
512; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]]
513; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
514; CHECK:       main.pseudo.exit:
515; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
516; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
517; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
518; CHECK:       for.body.preloop:
519; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
520; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
521; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
522; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
523; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
524; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
525; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
526; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
527; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
528; CHECK:       if.else.preloop:
529; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
530; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]]
531; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
532; CHECK:       for.inc.preloop:
533; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
534; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
535; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
536; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[M]]
537; CHECK-NEXT:    [[TMP11:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]]
538; CHECK-NEXT:    br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
539; CHECK:       preloop.exit.selector:
540; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
541; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]]
542; CHECK-NEXT:    br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
543; CHECK:       preloop.pseudo.exit:
544; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
545; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
546; CHECK-NEXT:    br label [[MAINLOOP]]
547; CHECK:       postloop:
548; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
549; CHECK:       for.body.postloop:
550; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
551; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
552; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
553; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
554; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
555; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
556; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]]
557; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
558; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
559; CHECK:       if.else.postloop:
560; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
561; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]]
562; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
563; CHECK:       for.inc.postloop:
564; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
565; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
566; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
567; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp sgt i32 [[DEC_POSTLOOP]], [[M]]
568; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
569;
570entry:
571  %cmp14 = icmp slt i32 %M, 1024
572  br i1 %cmp14, label %for.body, label %for.cond.cleanup
573
574for.cond.cleanup:                                 ; preds = %for.inc, %entry
575  ret void
576
577for.body:                                         ; preds = %entry, %for.inc
578  %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
579  %cmp1 = icmp slt i32 %iv, 1024
580  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
581  %0 = load i32, ptr %arrayidx, align 4
582  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
583  %1 = load i32, ptr %arrayidx2, align 4
584  %mul = mul nsw i32 %1, %0
585  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
586  br i1 %cmp1, label %for.inc, label %if.else
587
588if.else:                                          ; preds = %for.body
589  %2 = load i32, ptr %arrayidx3, align 4
590  %add = add nsw i32 %2, %mul
591  br label %for.inc
592
593for.inc:                                          ; preds = %for.body, %if.else
594  %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
595  store i32 %storemerge, ptr %arrayidx3, align 4
596  %dec = add nsw i32 %iv, -1
597  %cmp = icmp sgt i32 %dec, %M
598  br i1 %cmp, label %for.body, label %for.cond.cleanup
599}
600
601define void @signed_var_imm_dec_sge(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
602; CHECK-LABEL: define void @signed_var_imm_dec_sge(
603; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) {
604; CHECK-NEXT:  entry:
605; CHECK-NEXT:    [[CMP14:%.*]] = icmp sgt i32 [[M]], 1024
606; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
607; CHECK:       for.body.preheader:
608; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
609; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1025)
610; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
611; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1)
612; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
613; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1025, [[EXIT_PRELOOP_AT]]
614; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
615; CHECK:       for.body.preloop.preheader:
616; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
617; CHECK:       for.cond.cleanup.loopexit.loopexit:
618; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
619; CHECK:       for.cond.cleanup.loopexit:
620; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
621; CHECK:       for.cond.cleanup:
622; CHECK-NEXT:    ret void
623; CHECK:       mainloop:
624; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
625; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
626; CHECK:       for.body.preheader3:
627; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
628; CHECK:       for.body:
629; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
630; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
631; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
632; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
633; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
634; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
635; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
636; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
637; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
638; CHECK:       if.else:
639; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
640; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
641; CHECK-NEXT:    br label [[FOR_INC]]
642; CHECK:       for.inc:
643; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
644; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
645; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
646; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[IV]], [[M]]
647; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[IV]], [[EXIT_MAINLOOP_AT]]
648; CHECK-NEXT:    br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
649; CHECK:       main.exit.selector:
650; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
651; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[FOR_INC]] ]
652; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[IV_LCSSA]], [[M]]
653; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
654; CHECK:       main.pseudo.exit:
655; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
656; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
657; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
658; CHECK:       for.body.preloop:
659; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
660; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
661; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
662; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
663; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
664; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
665; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
666; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
667; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
668; CHECK:       if.else.preloop:
669; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
670; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]]
671; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
672; CHECK:       for.inc.preloop:
673; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
674; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
675; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
676; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp sgt i32 [[IV_PRELOOP]], [[M]]
677; CHECK-NEXT:    [[TMP11:%.*]] = icmp sgt i32 [[IV_PRELOOP]], [[EXIT_PRELOOP_AT]]
678; CHECK-NEXT:    br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
679; CHECK:       preloop.exit.selector:
680; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
681; CHECK-NEXT:    [[IV_PRELOOP_LCSSA:%.*]] = phi i32 [ [[IV_PRELOOP]], [[FOR_INC_PRELOOP]] ]
682; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[IV_PRELOOP_LCSSA]], [[M]]
683; CHECK-NEXT:    br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
684; CHECK:       preloop.pseudo.exit:
685; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
686; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1025, [[FOR_BODY_PREHEADER]] ], [ [[IV_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
687; CHECK-NEXT:    br label [[MAINLOOP]]
688; CHECK:       postloop:
689; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
690; CHECK:       for.body.postloop:
691; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
692; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
693; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
694; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
695; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
696; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
697; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]]
698; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
699; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
700; CHECK:       if.else.postloop:
701; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
702; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]]
703; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
704; CHECK:       for.inc.postloop:
705; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
706; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
707; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
708; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp sgt i32 [[IV_POSTLOOP]], [[M]]
709; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
710;
711entry:
712  %cmp14 = icmp sgt i32 %M, 1024
713  br i1 %cmp14, label %for.cond.cleanup, label %for.body
714
715for.cond.cleanup:                                 ; preds = %for.inc, %entry
716  ret void
717
718for.body:                                         ; preds = %entry, %for.inc
719  %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
720  %cmp1 = icmp slt i32 %iv, 1024
721  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
722  %0 = load i32, ptr %arrayidx, align 4
723  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
724  %1 = load i32, ptr %arrayidx2, align 4
725  %mul = mul nsw i32 %1, %0
726  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
727  br i1 %cmp1, label %for.inc, label %if.else
728
729if.else:                                          ; preds = %for.body
730  %2 = load i32, ptr %arrayidx3, align 4
731  %add = add nsw i32 %2, %mul
732  br label %for.inc
733
734for.inc:                                          ; preds = %for.body, %if.else
735  %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
736  store i32 %storemerge, ptr %arrayidx3, align 4
737  %dec = add nsw i32 %iv, -1
738  %cmp = icmp sgt i32 %iv, %M
739  br i1 %cmp, label %for.body, label %for.cond.cleanup
740}
741
742define void @signed_var_imm_dec_slt(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
743; CHECK-LABEL: define void @signed_var_imm_dec_slt(
744; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) {
745; CHECK-NEXT:  entry:
746; CHECK-NEXT:    [[CMP14:%.*]] = icmp sgt i32 [[M]], 1024
747; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
748; CHECK:       for.body.preheader:
749; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
750; CHECK:       for.cond.cleanup.loopexit:
751; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
752; CHECK:       for.cond.cleanup:
753; CHECK-NEXT:    ret void
754; CHECK:       for.body:
755; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ 1024, [[FOR_BODY_PREHEADER]] ]
756; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
757; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
758; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
759; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
760; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
761; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[TMP0]]
762; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
763; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_INC]], label [[IF_ELSE:%.*]]
764; CHECK:       if.else:
765; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
766; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP2]], [[MUL]]
767; CHECK-NEXT:    br label [[FOR_INC]]
768; CHECK:       for.inc:
769; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
770; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
771; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
772; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[IV]], [[M]]
773; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]
774;
775entry:
776  %cmp14 = icmp sgt i32 %M, 1024
777  br i1 %cmp14, label %for.cond.cleanup, label %for.body
778
779for.cond.cleanup:                                 ; preds = %for.inc, %entry
780  ret void
781
782for.body:                                         ; preds = %entry, %for.inc
783  %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
784  %cmp1 = icmp slt i32 %iv, 1024
785  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
786  %0 = load i32, ptr %arrayidx, align 4
787  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
788  %1 = load i32, ptr %arrayidx2, align 4
789  %mul = mul nsw i32 %1, %0
790  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
791  br i1 %cmp1, label %for.inc, label %if.else
792
793if.else:                                          ; preds = %for.body
794  %2 = load i32, ptr %arrayidx3, align 4
795  %add = add nsw i32 %2, %mul
796  br label %for.inc
797
798for.inc:                                          ; preds = %for.body, %if.else
799  %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
800  store i32 %storemerge, ptr %arrayidx3, align 4
801  %dec = add nsw i32 %iv, -1
802  %cmp = icmp slt i32 %iv, %M
803  br i1 %cmp, label %for.cond.cleanup, label %for.body
804}
805
806define void @signed_var_imm_dec_ne(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
807; CHECK-LABEL: define void @signed_var_imm_dec_ne(
808; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) {
809; CHECK-NEXT:  entry:
810; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[M]], 1024
811; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
812; CHECK:       for.body.preheader:
813; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
814; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024)
815; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
816; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0)
817; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
818; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]]
819; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
820; CHECK:       for.body.preloop.preheader:
821; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
822; CHECK:       for.cond.cleanup.loopexit.loopexit:
823; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
824; CHECK:       for.cond.cleanup.loopexit:
825; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
826; CHECK:       for.cond.cleanup:
827; CHECK-NEXT:    ret void
828; CHECK:       mainloop:
829; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
830; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
831; CHECK:       for.body.preheader3:
832; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
833; CHECK:       for.body:
834; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
835; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
836; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
837; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
838; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
839; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
840; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
841; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
842; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
843; CHECK:       if.else:
844; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
845; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
846; CHECK-NEXT:    br label [[FOR_INC]]
847; CHECK:       for.inc:
848; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
849; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
850; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
851; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[DEC]], [[M]]
852; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]]
853; CHECK-NEXT:    br i1 [[TMP6]], label [[FOR_BODY]], label [[MAIN_EXIT_SELECTOR:%.*]]
854; CHECK:       main.exit.selector:
855; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
856; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]]
857; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
858; CHECK:       main.pseudo.exit:
859; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
860; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
861; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
862; CHECK:       for.body.preloop:
863; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
864; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
865; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
866; CHECK-NEXT:    [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
867; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
868; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
869; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP9]], [[TMP8]]
870; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
871; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
872; CHECK:       if.else.preloop:
873; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
874; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP10]], [[MUL_PRELOOP]]
875; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
876; CHECK:       for.inc.preloop:
877; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
878; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
879; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
880; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp ne i32 [[DEC_PRELOOP]], [[M]]
881; CHECK-NEXT:    [[TMP11:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]]
882; CHECK-NEXT:    br i1 [[TMP11]], label [[FOR_BODY_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR:%.*]], !llvm.loop [[LOOP13:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
883; CHECK:       preloop.exit.selector:
884; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
885; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]]
886; CHECK-NEXT:    br i1 [[TMP12]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
887; CHECK:       preloop.pseudo.exit:
888; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
889; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
890; CHECK-NEXT:    br label [[MAINLOOP]]
891; CHECK:       postloop:
892; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
893; CHECK:       for.body.postloop:
894; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
895; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
896; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
897; CHECK-NEXT:    [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
898; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
899; CHECK-NEXT:    [[TMP14:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
900; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP14]], [[TMP13]]
901; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
902; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
903; CHECK:       if.else.postloop:
904; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
905; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP15]], [[MUL_POSTLOOP]]
906; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
907; CHECK:       for.inc.postloop:
908; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
909; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
910; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
911; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp ne i32 [[DEC_POSTLOOP]], [[M]]
912; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_BODY_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP14:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
913;
914entry:
915  %cmp14 = icmp slt i32 %M, 1024
916  br i1 %cmp14, label %for.body, label %for.cond.cleanup
917
918for.cond.cleanup:                                 ; preds = %for.inc, %entry
919  ret void
920
921for.body:                                         ; preds = %entry, %for.inc
922  %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
923  %cmp1 = icmp slt i32 %iv, 1024
924  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
925  %0 = load i32, ptr %arrayidx, align 4
926  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
927  %1 = load i32, ptr %arrayidx2, align 4
928  %mul = mul nsw i32 %1, %0
929  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
930  br i1 %cmp1, label %for.inc, label %if.else
931
932if.else:                                          ; preds = %for.body
933  %2 = load i32, ptr %arrayidx3, align 4
934  %add = add nsw i32 %2, %mul
935  br label %for.inc
936
937for.inc:                                          ; preds = %for.body, %if.else
938  %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
939  store i32 %storemerge, ptr %arrayidx3, align 4
940  %dec = add nsw i32 %iv, -1
941  %cmp = icmp ne i32 %dec, %M
942  br i1 %cmp, label %for.body, label %for.cond.cleanup
943}
944
945define void @signed_var_imm_dec_eq(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %M) {
946; CHECK-LABEL: define void @signed_var_imm_dec_eq(
947; CHECK-SAME: ptr captures(none) [[A:%.*]], ptr readonly captures(none) [[B:%.*]], ptr readonly captures(none) [[C:%.*]], i32 [[M:%.*]]) {
948; CHECK-NEXT:  entry:
949; CHECK-NEXT:    [[CMP14:%.*]] = icmp slt i32 [[M]], 1024
950; CHECK-NEXT:    br i1 [[CMP14]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
951; CHECK:       for.body.preheader:
952; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[M]], 1
953; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 1024)
954; CHECK-NEXT:    [[EXIT_PRELOOP_AT:%.*]] = add nsw i32 [[SMAX]], -1
955; CHECK-NEXT:    [[SMAX1:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP0]], i32 0)
956; CHECK-NEXT:    [[EXIT_MAINLOOP_AT:%.*]] = add nsw i32 [[SMAX1]], -1
957; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 1024, [[EXIT_PRELOOP_AT]]
958; CHECK-NEXT:    br i1 [[TMP1]], label [[FOR_BODY_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
959; CHECK:       for.body.preloop.preheader:
960; CHECK-NEXT:    br label [[FOR_BODY_PRELOOP:%.*]]
961; CHECK:       for.cond.cleanup.loopexit.loopexit:
962; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
963; CHECK:       for.cond.cleanup.loopexit:
964; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
965; CHECK:       for.cond.cleanup:
966; CHECK-NEXT:    ret void
967; CHECK:       mainloop:
968; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
969; CHECK-NEXT:    br i1 [[TMP2]], label [[FOR_BODY_PREHEADER3:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
970; CHECK:       for.body.preheader3:
971; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
972; CHECK:       for.body:
973; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_INC:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[FOR_BODY_PREHEADER3]] ]
974; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[IV]], 1024
975; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV]]
976; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
977; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV]]
978; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
979; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP4]], [[TMP3]]
980; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]
981; CHECK-NEXT:    br i1 true, label [[FOR_INC]], label [[IF_ELSE:%.*]]
982; CHECK:       if.else:
983; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX3]], align 4
984; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[MUL]]
985; CHECK-NEXT:    br label [[FOR_INC]]
986; CHECK:       for.inc:
987; CHECK-NEXT:    [[STOREMERGE:%.*]] = phi i32 [ [[ADD]], [[IF_ELSE]] ], [ [[MUL]], [[FOR_BODY]] ]
988; CHECK-NEXT:    store i32 [[STOREMERGE]], ptr [[ARRAYIDX3]], align 4
989; CHECK-NEXT:    [[DEC]] = add nsw i32 [[IV]], -1
990; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[DEC]], [[M]]
991; CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i32 [[DEC]], [[EXIT_MAINLOOP_AT]]
992; CHECK-NEXT:    [[TMP7:%.*]] = xor i1 [[TMP6]], true
993; CHECK-NEXT:    br i1 [[TMP7]], label [[MAIN_EXIT_SELECTOR:%.*]], label [[FOR_BODY]]
994; CHECK:       main.exit.selector:
995; CHECK-NEXT:    [[DEC_LCSSA:%.*]] = phi i32 [ [[DEC]], [[FOR_INC]] ]
996; CHECK-NEXT:    [[TMP8:%.*]] = icmp sgt i32 [[DEC_LCSSA]], [[M]]
997; CHECK-NEXT:    br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
998; CHECK:       main.pseudo.exit:
999; CHECK-NEXT:    [[IV_COPY:%.*]] = phi i32 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
1000; CHECK-NEXT:    [[INDVAR_END2:%.*]] = phi i32 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[DEC_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
1001; CHECK-NEXT:    br label [[POSTLOOP:%.*]]
1002; CHECK:       for.body.preloop:
1003; CHECK-NEXT:    [[IV_PRELOOP:%.*]] = phi i32 [ [[DEC_PRELOOP:%.*]], [[FOR_INC_PRELOOP:%.*]] ], [ 1024, [[FOR_BODY_PRELOOP_PREHEADER]] ]
1004; CHECK-NEXT:    [[CMP1_PRELOOP:%.*]] = icmp slt i32 [[IV_PRELOOP]], 1024
1005; CHECK-NEXT:    [[ARRAYIDX_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_PRELOOP]]
1006; CHECK-NEXT:    [[TMP9:%.*]] = load i32, ptr [[ARRAYIDX_PRELOOP]], align 4
1007; CHECK-NEXT:    [[ARRAYIDX2_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_PRELOOP]]
1008; CHECK-NEXT:    [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX2_PRELOOP]], align 4
1009; CHECK-NEXT:    [[MUL_PRELOOP:%.*]] = mul nsw i32 [[TMP10]], [[TMP9]]
1010; CHECK-NEXT:    [[ARRAYIDX3_PRELOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_PRELOOP]]
1011; CHECK-NEXT:    br i1 [[CMP1_PRELOOP]], label [[FOR_INC_PRELOOP]], label [[IF_ELSE_PRELOOP:%.*]]
1012; CHECK:       if.else.preloop:
1013; CHECK-NEXT:    [[TMP11:%.*]] = load i32, ptr [[ARRAYIDX3_PRELOOP]], align 4
1014; CHECK-NEXT:    [[ADD_PRELOOP:%.*]] = add nsw i32 [[TMP11]], [[MUL_PRELOOP]]
1015; CHECK-NEXT:    br label [[FOR_INC_PRELOOP]]
1016; CHECK:       for.inc.preloop:
1017; CHECK-NEXT:    [[STOREMERGE_PRELOOP:%.*]] = phi i32 [ [[ADD_PRELOOP]], [[IF_ELSE_PRELOOP]] ], [ [[MUL_PRELOOP]], [[FOR_BODY_PRELOOP]] ]
1018; CHECK-NEXT:    store i32 [[STOREMERGE_PRELOOP]], ptr [[ARRAYIDX3_PRELOOP]], align 4
1019; CHECK-NEXT:    [[DEC_PRELOOP]] = add nsw i32 [[IV_PRELOOP]], -1
1020; CHECK-NEXT:    [[CMP_PRELOOP:%.*]] = icmp eq i32 [[DEC_PRELOOP]], [[M]]
1021; CHECK-NEXT:    [[TMP12:%.*]] = icmp sgt i32 [[DEC_PRELOOP]], [[EXIT_PRELOOP_AT]]
1022; CHECK-NEXT:    [[TMP13:%.*]] = xor i1 [[TMP12]], true
1023; CHECK-NEXT:    br i1 [[TMP13]], label [[PRELOOP_EXIT_SELECTOR:%.*]], label [[FOR_BODY_PRELOOP]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
1024; CHECK:       preloop.exit.selector:
1025; CHECK-NEXT:    [[DEC_PRELOOP_LCSSA:%.*]] = phi i32 [ [[DEC_PRELOOP]], [[FOR_INC_PRELOOP]] ]
1026; CHECK-NEXT:    [[TMP14:%.*]] = icmp sgt i32 [[DEC_PRELOOP_LCSSA]], [[M]]
1027; CHECK-NEXT:    br i1 [[TMP14]], label [[PRELOOP_PSEUDO_EXIT]], label [[FOR_COND_CLEANUP_LOOPEXIT]]
1028; CHECK:       preloop.pseudo.exit:
1029; CHECK-NEXT:    [[IV_PRELOOP_COPY]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
1030; CHECK-NEXT:    [[INDVAR_END]] = phi i32 [ 1024, [[FOR_BODY_PREHEADER]] ], [ [[DEC_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
1031; CHECK-NEXT:    br label [[MAINLOOP]]
1032; CHECK:       postloop:
1033; CHECK-NEXT:    br label [[FOR_BODY_POSTLOOP:%.*]]
1034; CHECK:       for.body.postloop:
1035; CHECK-NEXT:    [[IV_POSTLOOP:%.*]] = phi i32 [ [[DEC_POSTLOOP:%.*]], [[FOR_INC_POSTLOOP:%.*]] ], [ [[IV_COPY]], [[POSTLOOP]] ]
1036; CHECK-NEXT:    [[CMP1_POSTLOOP:%.*]] = icmp slt i32 [[IV_POSTLOOP]], 1024
1037; CHECK-NEXT:    [[ARRAYIDX_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[IV_POSTLOOP]]
1038; CHECK-NEXT:    [[TMP15:%.*]] = load i32, ptr [[ARRAYIDX_POSTLOOP]], align 4
1039; CHECK-NEXT:    [[ARRAYIDX2_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[IV_POSTLOOP]]
1040; CHECK-NEXT:    [[TMP16:%.*]] = load i32, ptr [[ARRAYIDX2_POSTLOOP]], align 4
1041; CHECK-NEXT:    [[MUL_POSTLOOP:%.*]] = mul nsw i32 [[TMP16]], [[TMP15]]
1042; CHECK-NEXT:    [[ARRAYIDX3_POSTLOOP:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV_POSTLOOP]]
1043; CHECK-NEXT:    br i1 [[CMP1_POSTLOOP]], label [[FOR_INC_POSTLOOP]], label [[IF_ELSE_POSTLOOP:%.*]]
1044; CHECK:       if.else.postloop:
1045; CHECK-NEXT:    [[TMP17:%.*]] = load i32, ptr [[ARRAYIDX3_POSTLOOP]], align 4
1046; CHECK-NEXT:    [[ADD_POSTLOOP:%.*]] = add nsw i32 [[TMP17]], [[MUL_POSTLOOP]]
1047; CHECK-NEXT:    br label [[FOR_INC_POSTLOOP]]
1048; CHECK:       for.inc.postloop:
1049; CHECK-NEXT:    [[STOREMERGE_POSTLOOP:%.*]] = phi i32 [ [[ADD_POSTLOOP]], [[IF_ELSE_POSTLOOP]] ], [ [[MUL_POSTLOOP]], [[FOR_BODY_POSTLOOP]] ]
1050; CHECK-NEXT:    store i32 [[STOREMERGE_POSTLOOP]], ptr [[ARRAYIDX3_POSTLOOP]], align 4
1051; CHECK-NEXT:    [[DEC_POSTLOOP]] = add nsw i32 [[IV_POSTLOOP]], -1
1052; CHECK-NEXT:    [[CMP_POSTLOOP:%.*]] = icmp eq i32 [[DEC_POSTLOOP]], [[M]]
1053; CHECK-NEXT:    br i1 [[CMP_POSTLOOP]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], label [[FOR_BODY_POSTLOOP]], !llvm.loop [[LOOP16:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
1054;
1055entry:
1056  %cmp14 = icmp slt i32 %M, 1024
1057  br i1 %cmp14, label %for.body, label %for.cond.cleanup
1058
1059for.cond.cleanup:                                 ; preds = %for.inc, %entry
1060  ret void
1061
1062for.body:                                         ; preds = %entry, %for.inc
1063  %iv = phi i32 [ %dec, %for.inc ], [ 1024, %entry ]
1064  %cmp1 = icmp slt i32 %iv, 1024
1065  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %iv
1066  %0 = load i32, ptr %arrayidx, align 4
1067  %arrayidx2 = getelementptr inbounds i32, ptr %c, i32 %iv
1068  %1 = load i32, ptr %arrayidx2, align 4
1069  %mul = mul nsw i32 %1, %0
1070  %arrayidx3 = getelementptr inbounds i32, ptr %a, i32 %iv
1071  br i1 %cmp1, label %for.inc, label %if.else
1072
1073if.else:                                          ; preds = %for.body
1074  %2 = load i32, ptr %arrayidx3, align 4
1075  %add = add nsw i32 %2, %mul
1076  br label %for.inc
1077
1078for.inc:                                          ; preds = %for.body, %if.else
1079  %storemerge = phi i32 [ %add, %if.else ], [ %mul, %for.body ]
1080  store i32 %storemerge, ptr %arrayidx3, align 4
1081  %dec = add nsw i32 %iv, -1
1082  %cmp = icmp eq i32 %dec, %M
1083  br i1 %cmp, label %for.cond.cleanup, label %for.body
1084}
1085
1086;; Negative test
1087define void @test_dec_bound_with_smaller_start_than_bound(i64 %0) {
1088; CHECK-LABEL: define void @test_dec_bound_with_smaller_start_than_bound(
1089; CHECK-SAME: i64 [[TMP0:%.*]]) {
1090; CHECK-NEXT:  entry:
1091; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1092; CHECK:       for.body:
1093; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
1094; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[IV]], [[TMP0]]
1095; CHECK-NEXT:    br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[FOR_DEC]]
1096; CHECK:       if.else:
1097; CHECK-NEXT:    br label [[FOR_DEC]]
1098; CHECK:       for.dec:
1099; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1
1100; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i64 [[DEC]], 1
1101; CHECK-NEXT:    br i1 [[TMP2]], label [[EXIT:%.*]], label [[FOR_BODY]]
1102; CHECK:       exit:
1103; CHECK-NEXT:    ret void
1104;
1105entry:
1106  br label %for.body
1107
1108for.body:                                                ; preds = %for.dec, %entry
1109  %iv = phi i64 [ %dec, %for.dec ], [ 0, %entry ]
1110  %1 = icmp slt i64 %iv, %0
1111  br i1 %1, label %if.else, label %for.dec
1112
1113if.else:                                                ; preds = %for.body
1114  br label %for.dec
1115
1116for.dec:                                                ; preds = %if.else, %for.body
1117  %dec = sub nuw nsw i64 %iv, 1
1118  %2 = icmp slt i64 %dec, 1
1119  br i1 %2, label %exit, label %for.body
1120
1121exit:                                               ; preds = %for.dec
1122  ret void
1123}
1124
1125;; Negative test
1126define void @test_inc_bound_with_bigger_start_than_bound(i32 %0) {
1127; CHECK-LABEL: define void @test_inc_bound_with_bigger_start_than_bound(
1128; CHECK-SAME: i32 [[TMP0:%.*]]) {
1129; CHECK-NEXT:  entry:
1130; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
1131; CHECK:       for.body:
1132; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 200, [[ENTRY:%.*]] ]
1133; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[IV]], [[TMP0]]
1134; CHECK-NEXT:    br i1 [[TMP1]], label [[IF_ELSE:%.*]], label [[FOR_INC]]
1135; CHECK:       if.else:
1136; CHECK-NEXT:    br label [[FOR_INC]]
1137; CHECK:       for.inc:
1138; CHECK-NEXT:    [[INC]] = add nsw i32 [[IV]], 1
1139; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[INC]], 100
1140; CHECK-NEXT:    br i1 [[TMP2]], label [[EXIT:%.*]], label [[FOR_BODY]]
1141; CHECK:       exit:
1142; CHECK-NEXT:    ret void
1143;
1144entry:
1145  br label %for.body
1146
1147for.body:                                                ; preds = %for.inc, %entry
1148  %iv = phi i32 [ %inc, %for.inc ], [ 200, %entry ]
1149  %1 = icmp slt i32 %iv, %0
1150  br i1 %1, label %if.else, label %for.inc
1151
1152if.else:                                                ; preds = %for.body
1153  br label %for.inc
1154
1155for.inc:                                                ; preds = %if.else, %for.body
1156  %inc = add nsw i32 %iv, 1
1157  %2 = icmp sgt i32 %inc, 100
1158  br i1 %2, label %exit, label %for.body
1159
1160exit:                                                ; preds = %for.inc
1161  ret void
1162}
1163