xref: /llvm-project/llvm/test/Transforms/LoopFlatten/widen-iv.ll (revision dce77a357948709e335910ddc07f9c3f2eb2ac4b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2
3; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),adce,verify' -loop-flatten-widen-iv=true \
4; RUN:     -loop-flatten-version-loops=false -verify-loop-info -verify-dom-info -verify-scev \
5; RUN:     -loop-flatten-cost-threshold=6 | \
6; RUN:     FileCheck %s --check-prefix=CHECK
7
8; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),adce,verify' -loop-flatten-widen-iv=false \
9; RUN:     -loop-flatten-version-loops=false -verify-loop-info -verify-dom-info -verify-scev | \
10; RUN:     FileCheck %s --check-prefix=DONTWIDEN
11
12target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
13
14; DONTWIDEN-NOT:   %flatten.tripcount
15; DONTWIDEN-NOT:   %flatten.trunciv
16
17; Function Attrs: nounwind
18define void @foo(ptr %A, i32 %N, i32 %M) {
19; CHECK-LABEL: @foo(
20; CHECK-NEXT:  entry:
21; CHECK-NEXT:    [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
22; CHECK-NEXT:    br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
23; CHECK:       for.cond1.preheader.lr.ph:
24; CHECK-NEXT:    [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
25; CHECK-NEXT:    br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
26; CHECK:       for.cond1.preheader.us.preheader:
27; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[M]] to i64
28; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[N]] to i64
29; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
30; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
31; CHECK:       for.cond1.preheader.us:
32; CHECK-NEXT:    [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
33; CHECK-NEXT:    br label [[FOR_BODY4_US:%.*]]
34; CHECK:       for.body4.us:
35; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]]
36; CHECK-NEXT:    tail call void @f(ptr [[ARRAYIDX_US]])
37; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
38; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us:
39; CHECK-NEXT:    [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1
40; CHECK-NEXT:    [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
41; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
42; CHECK:       for.cond.cleanup.loopexit:
43; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
44; CHECK:       for.cond.cleanup:
45; CHECK-NEXT:    ret void
46;
47; DONTWIDEN-LABEL: @foo(
48; DONTWIDEN-NEXT:  entry:
49; DONTWIDEN-NEXT:    [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
50; DONTWIDEN-NEXT:    br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
51; DONTWIDEN:       for.cond1.preheader.lr.ph:
52; DONTWIDEN-NEXT:    [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
53; DONTWIDEN-NEXT:    br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
54; DONTWIDEN:       for.cond1.preheader.us.preheader:
55; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
56; DONTWIDEN:       for.cond1.preheader.us:
57; DONTWIDEN-NEXT:    [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
58; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]]
59; DONTWIDEN-NEXT:    br label [[FOR_BODY4_US:%.*]]
60; DONTWIDEN:       for.body4.us:
61; DONTWIDEN-NEXT:    [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
62; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]]
63; DONTWIDEN-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
64; DONTWIDEN-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
65; DONTWIDEN-NEXT:    tail call void @f(ptr [[ARRAYIDX_US]])
66; DONTWIDEN-NEXT:    [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1
67; DONTWIDEN-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M]]
68; DONTWIDEN-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
69; DONTWIDEN:       for.cond1.for.cond.cleanup3_crit_edge.us:
70; DONTWIDEN-NEXT:    [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1
71; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]]
72; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
73; DONTWIDEN:       for.cond.cleanup.loopexit:
74; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
75; DONTWIDEN:       for.cond.cleanup:
76; DONTWIDEN-NEXT:    ret void
77;
78entry:
79  %cmp17 = icmp sgt i32 %N, 0
80  br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup
81
82for.cond1.preheader.lr.ph:
83  %cmp215 = icmp sgt i32 %M, 0
84  br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond.cleanup
85
86for.cond1.preheader.us.preheader:
87  br label %for.cond1.preheader.us
88
89for.cond1.preheader.us:
90  %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
91  %mul.us = mul nsw i32 %i.018.us, %M
92  br label %for.body4.us
93
94for.body4.us:
95  %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
96  %add.us = add nsw i32 %j.016.us, %mul.us
97  %idxprom.us = sext i32 %add.us to i64
98  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
99  tail call void @f(ptr %arrayidx.us) #2
100  %inc.us = add nuw nsw i32 %j.016.us, 1
101  %cmp2.us = icmp slt i32 %inc.us, %M
102  br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
103
104for.cond1.for.cond.cleanup3_crit_edge.us:
105  %inc6.us = add nuw nsw i32 %i.018.us, 1
106  %cmp.us = icmp slt i32 %inc6.us, %N
107  br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup
108
109for.cond.cleanup:
110  ret void
111}
112
113; This test case corresponds to this input:
114;
115;     for (int i = 0; i < N; ++i)
116;       for (int j = 0; j < M; ++j)
117;         f(A[i*M+j]);
118;
119; It is very similar to test case @foo above, but the CFG is slightly
120; different, making the analysis slightly different.
121;
122define void @foo2_sext(ptr nocapture readonly %A, i32 %N, i32 %M) {
123; CHECK-LABEL: @foo2_sext(
124; CHECK-NEXT:  entry:
125; CHECK-NEXT:    [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
126; CHECK-NEXT:    br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
127; CHECK:       for.cond1.preheader.lr.ph:
128; CHECK-NEXT:    [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
129; CHECK-NEXT:    br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]]
130; CHECK:       for.cond1.preheader.preheader:
131; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
132; CHECK:       for.cond1.preheader.us.preheader:
133; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[M]] to i64
134; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[N]] to i64
135; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
136; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
137; CHECK:       for.cond1.preheader.us:
138; CHECK-NEXT:    [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
139; CHECK-NEXT:    br label [[FOR_BODY4_US:%.*]]
140; CHECK:       for.body4.us:
141; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]]
142; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
143; CHECK-NEXT:    tail call void @g(i32 [[TMP2]])
144; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
145; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us:
146; CHECK-NEXT:    [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1
147; CHECK-NEXT:    [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
148; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
149; CHECK:       for.cond1.preheader:
150; CHECK-NEXT:    [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
151; CHECK-NEXT:    [[INC6]] = add nuw nsw i32 [[I_018]], 1
152; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC6]], [[N]]
153; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
154; CHECK:       for.cond.cleanup.loopexit:
155; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
156; CHECK:       for.cond.cleanup.loopexit19:
157; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
158; CHECK:       for.cond.cleanup:
159; CHECK-NEXT:    ret void
160;
161; DONTWIDEN-LABEL: @foo2_sext(
162; DONTWIDEN-NEXT:  entry:
163; DONTWIDEN-NEXT:    [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
164; DONTWIDEN-NEXT:    br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
165; DONTWIDEN:       for.cond1.preheader.lr.ph:
166; DONTWIDEN-NEXT:    [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
167; DONTWIDEN-NEXT:    br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]]
168; DONTWIDEN:       for.cond1.preheader.preheader:
169; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
170; DONTWIDEN:       for.cond1.preheader.us.preheader:
171; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
172; DONTWIDEN:       for.cond1.preheader.us:
173; DONTWIDEN-NEXT:    [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
174; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]]
175; DONTWIDEN-NEXT:    br label [[FOR_BODY4_US:%.*]]
176; DONTWIDEN:       for.body4.us:
177; DONTWIDEN-NEXT:    [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
178; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]]
179; DONTWIDEN-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
180; DONTWIDEN-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
181; DONTWIDEN-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
182; DONTWIDEN-NEXT:    tail call void @g(i32 [[TMP0]])
183; DONTWIDEN-NEXT:    [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1
184; DONTWIDEN-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M]]
185; DONTWIDEN-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
186; DONTWIDEN:       for.cond1.for.cond.cleanup3_crit_edge.us:
187; DONTWIDEN-NEXT:    [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1
188; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]]
189; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
190; DONTWIDEN:       for.cond1.preheader:
191; DONTWIDEN-NEXT:    [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
192; DONTWIDEN-NEXT:    [[INC6]] = add nuw nsw i32 [[I_018]], 1
193; DONTWIDEN-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC6]], [[N]]
194; DONTWIDEN-NEXT:    br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
195; DONTWIDEN:       for.cond.cleanup.loopexit:
196; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
197; DONTWIDEN:       for.cond.cleanup.loopexit19:
198; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
199; DONTWIDEN:       for.cond.cleanup:
200; DONTWIDEN-NEXT:    ret void
201;
202entry:
203  %cmp17 = icmp sgt i32 %N, 0
204  br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup
205
206for.cond1.preheader.lr.ph:
207  %cmp215 = icmp sgt i32 %M, 0
208  br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond1.preheader.preheader
209
210for.cond1.preheader.preheader:
211  br label %for.cond1.preheader
212
213for.cond1.preheader.us.preheader:
214  br label %for.cond1.preheader.us
215
216for.cond1.preheader.us:
217  %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
218  %mul.us = mul nsw i32 %i.018.us, %M
219  br label %for.body4.us
220
221for.body4.us:
222  %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
223  %add.us = add nsw i32 %j.016.us, %mul.us
224  %idxprom.us = sext i32 %add.us to i64
225  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
226  %0 = load i32, ptr %arrayidx.us, align 4
227  tail call void @g(i32 %0)
228  %inc.us = add nuw nsw i32 %j.016.us, 1
229  %cmp2.us = icmp slt i32 %inc.us, %M
230  br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
231
232for.cond1.for.cond.cleanup3_crit_edge.us:
233  %inc6.us = add nuw nsw i32 %i.018.us, 1
234  %cmp.us = icmp slt i32 %inc6.us, %N
235  br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit
236
237for.cond1.preheader:
238  %i.018 = phi i32 [ %inc6, %for.cond1.preheader ], [ 0, %for.cond1.preheader.preheader ]
239  %inc6 = add nuw nsw i32 %i.018, 1
240  %cmp = icmp slt i32 %inc6, %N
241  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit19
242
243for.cond.cleanup.loopexit:
244  br label %for.cond.cleanup
245
246for.cond.cleanup.loopexit19:
247  br label %for.cond.cleanup
248
249for.cond.cleanup:
250  ret void
251}
252
253; This test case corresponds to this input:
254;
255;  void foo2_zext(unsigned *A, ..) {
256;     for (unsigned i = 0; i < N; ++i)
257;       for (unsigned j = 0; j < M; ++j)
258;         f(A[i*M+j]);
259;
260define void @foo2_zext(ptr nocapture readonly %A, i32 %N, i32 %M) {
261; CHECK-LABEL: @foo2_zext(
262; CHECK-NEXT:  entry:
263; CHECK-NEXT:    [[CMP17_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
264; CHECK-NEXT:    br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]]
265; CHECK:       for.cond1.preheader.lr.ph:
266; CHECK-NEXT:    [[CMP215_NOT:%.*]] = icmp eq i32 [[M:%.*]], 0
267; CHECK-NEXT:    br i1 [[CMP215_NOT]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
268; CHECK:       for.cond1.preheader.us.preheader:
269; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[M]] to i64
270; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[N]] to i64
271; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
272; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
273; CHECK:       for.cond1.preheader.preheader:
274; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
275; CHECK:       for.cond1.preheader.us:
276; CHECK-NEXT:    [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
277; CHECK-NEXT:    [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32
278; CHECK-NEXT:    br label [[FOR_BODY4_US:%.*]]
279; CHECK:       for.body4.us:
280; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[FLATTEN_TRUNCIV]] to i64
281; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
282; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
283; CHECK-NEXT:    tail call void @g(i32 [[TMP2]])
284; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
285; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us:
286; CHECK-NEXT:    [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1
287; CHECK-NEXT:    [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]]
288; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
289; CHECK:       for.cond1.preheader:
290; CHECK-NEXT:    [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
291; CHECK-NEXT:    [[INC6]] = add i32 [[I_018]], 1
292; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[INC6]], [[N]]
293; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
294; CHECK:       for.cond.cleanup.loopexit:
295; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
296; CHECK:       for.cond.cleanup.loopexit19:
297; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
298; CHECK:       for.cond.cleanup:
299; CHECK-NEXT:    ret void
300;
301; DONTWIDEN-LABEL: @foo2_zext(
302; DONTWIDEN-NEXT:  entry:
303; DONTWIDEN-NEXT:    [[CMP17_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
304; DONTWIDEN-NEXT:    br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]]
305; DONTWIDEN:       for.cond1.preheader.lr.ph:
306; DONTWIDEN-NEXT:    [[CMP215_NOT:%.*]] = icmp eq i32 [[M:%.*]], 0
307; DONTWIDEN-NEXT:    br i1 [[CMP215_NOT]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
308; DONTWIDEN:       for.cond1.preheader.us.preheader:
309; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
310; DONTWIDEN:       for.cond1.preheader.preheader:
311; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER:%.*]]
312; DONTWIDEN:       for.cond1.preheader.us:
313; DONTWIDEN-NEXT:    [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
314; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_018_US]], [[M]]
315; DONTWIDEN-NEXT:    br label [[FOR_BODY4_US:%.*]]
316; DONTWIDEN:       for.body4.us:
317; DONTWIDEN-NEXT:    [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
318; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add i32 [[J_016_US]], [[MUL_US]]
319; DONTWIDEN-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
320; DONTWIDEN-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
321; DONTWIDEN-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
322; DONTWIDEN-NEXT:    tail call void @g(i32 [[TMP0]])
323; DONTWIDEN-NEXT:    [[INC_US]] = add nuw i32 [[J_016_US]], 1
324; DONTWIDEN-NEXT:    [[CMP2_US:%.*]] = icmp ult i32 [[INC_US]], [[M]]
325; DONTWIDEN-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
326; DONTWIDEN:       for.cond1.for.cond.cleanup3_crit_edge.us:
327; DONTWIDEN-NEXT:    [[INC6_US]] = add i32 [[I_018_US]], 1
328; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp ult i32 [[INC6_US]], [[N]]
329; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
330; DONTWIDEN:       for.cond1.preheader:
331; DONTWIDEN-NEXT:    [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
332; DONTWIDEN-NEXT:    [[INC6]] = add i32 [[I_018]], 1
333; DONTWIDEN-NEXT:    [[CMP:%.*]] = icmp ult i32 [[INC6]], [[N]]
334; DONTWIDEN-NEXT:    br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
335; DONTWIDEN:       for.cond.cleanup.loopexit:
336; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
337; DONTWIDEN:       for.cond.cleanup.loopexit19:
338; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
339; DONTWIDEN:       for.cond.cleanup:
340; DONTWIDEN-NEXT:    ret void
341;
342entry:
343  %cmp17.not = icmp eq i32 %N, 0
344  br i1 %cmp17.not, label %for.cond.cleanup, label %for.cond1.preheader.lr.ph
345
346for.cond1.preheader.lr.ph:
347  %cmp215.not = icmp eq i32 %M, 0
348  br i1 %cmp215.not, label %for.cond1.preheader.preheader, label %for.cond1.preheader.us.preheader
349
350for.cond1.preheader.us.preheader:
351  br label %for.cond1.preheader.us
352
353for.cond1.preheader.preheader:
354  br label %for.cond1.preheader
355
356for.cond1.preheader.us:
357  %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
358  %mul.us = mul i32 %i.018.us, %M
359  br label %for.body4.us
360
361for.body4.us:
362  %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
363  %add.us = add i32 %j.016.us, %mul.us
364  %idxprom.us = zext i32 %add.us to i64
365  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
366  %0 = load i32, ptr %arrayidx.us, align 4
367  tail call void @g(i32 %0)
368  %inc.us = add nuw i32 %j.016.us, 1
369  %cmp2.us = icmp ult i32 %inc.us, %M
370  br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
371
372for.cond1.for.cond.cleanup3_crit_edge.us:
373  %inc6.us = add i32 %i.018.us, 1
374  %cmp.us = icmp ult i32 %inc6.us, %N
375  br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit19
376
377for.cond1.preheader:
378  %i.018 = phi i32 [ %inc6, %for.cond1.preheader ], [ 0, %for.cond1.preheader.preheader ]
379  %inc6 = add i32 %i.018, 1
380  %cmp = icmp ult i32 %inc6, %N
381  br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit
382
383for.cond.cleanup.loopexit:
384  br label %for.cond.cleanup
385
386for.cond.cleanup.loopexit19:
387  br label %for.cond.cleanup
388
389for.cond.cleanup:
390  ret void
391}
392
393define void @zext(i32 %N, ptr nocapture %A, i16 %val) {
394; CHECK-LABEL: @zext(
395; CHECK-NEXT:  entry:
396; CHECK-NEXT:    [[CMP20_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
397; CHECK-NEXT:    br i1 [[CMP20_NOT]], label [[FOR_END9:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
398; CHECK:       for.cond1.preheader.us.preheader:
399; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[N]] to i64
400; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[N]] to i64
401; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
402; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
403; CHECK:       for.cond1.preheader.us:
404; CHECK-NEXT:    [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_INC7_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
405; CHECK-NEXT:    [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32
406; CHECK-NEXT:    br label [[FOR_BODY3_US:%.*]]
407; CHECK:       for.body3.us:
408; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[FLATTEN_TRUNCIV]] to i64
409; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[IDXPROM_US]]
410; CHECK-NEXT:    [[TMP2:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2
411; CHECK-NEXT:    [[ADD5_US:%.*]] = add i16 [[TMP2]], [[VAL:%.*]]
412; CHECK-NEXT:    store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2
413; CHECK-NEXT:    br label [[FOR_COND1_FOR_INC7_CRIT_EDGE_US]]
414; CHECK:       for.cond1.for.inc7_crit_edge.us:
415; CHECK-NEXT:    [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1
416; CHECK-NEXT:    [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]]
417; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END9_LOOPEXIT:%.*]]
418; CHECK:       for.end9.loopexit:
419; CHECK-NEXT:    br label [[FOR_END9]]
420; CHECK:       for.end9:
421; CHECK-NEXT:    ret void
422;
423; DONTWIDEN-LABEL: @zext(
424; DONTWIDEN-NEXT:  entry:
425; DONTWIDEN-NEXT:    [[CMP20_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
426; DONTWIDEN-NEXT:    br i1 [[CMP20_NOT]], label [[FOR_END9:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
427; DONTWIDEN:       for.cond1.preheader.us.preheader:
428; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
429; DONTWIDEN:       for.cond1.preheader.us:
430; DONTWIDEN-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC8_US:%.*]], [[FOR_COND1_FOR_INC7_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
431; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
432; DONTWIDEN-NEXT:    br label [[FOR_BODY3_US:%.*]]
433; DONTWIDEN:       for.body3.us:
434; DONTWIDEN-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY3_US]] ]
435; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
436; DONTWIDEN-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
437; DONTWIDEN-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[IDXPROM_US]]
438; DONTWIDEN-NEXT:    [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2
439; DONTWIDEN-NEXT:    [[ADD5_US:%.*]] = add i16 [[TMP0]], [[VAL:%.*]]
440; DONTWIDEN-NEXT:    store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2
441; DONTWIDEN-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
442; DONTWIDEN-NEXT:    [[CMP2_US:%.*]] = icmp ult i32 [[INC_US]], [[N]]
443; DONTWIDEN-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY3_US]], label [[FOR_COND1_FOR_INC7_CRIT_EDGE_US]]
444; DONTWIDEN:       for.cond1.for.inc7_crit_edge.us:
445; DONTWIDEN-NEXT:    [[INC8_US]] = add i32 [[I_021_US]], 1
446; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp ult i32 [[INC8_US]], [[N]]
447; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END9_LOOPEXIT:%.*]]
448; DONTWIDEN:       for.end9.loopexit:
449; DONTWIDEN-NEXT:    br label [[FOR_END9]]
450; DONTWIDEN:       for.end9:
451; DONTWIDEN-NEXT:    ret void
452;
453entry:
454  %cmp20.not = icmp eq i32 %N, 0
455  br i1 %cmp20.not, label %for.end9, label %for.cond1.preheader.us.preheader
456
457for.cond1.preheader.us.preheader:
458  br label %for.cond1.preheader.us
459
460for.cond1.preheader.us:
461  %i.021.us = phi i32 [ %inc8.us, %for.cond1.for.inc7_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
462  %mul.us = mul i32 %i.021.us, %N
463  br label %for.body3.us
464
465for.body3.us:
466  %j.019.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body3.us ]
467  %add.us = add i32 %j.019.us, %mul.us
468  %idxprom.us = zext i32 %add.us to i64
469  %arrayidx.us = getelementptr inbounds i16, ptr %A, i64 %idxprom.us
470  %0 = load i16, ptr %arrayidx.us, align 2
471  %add5.us = add i16 %0, %val
472  store i16 %add5.us, ptr %arrayidx.us, align 2
473  %inc.us = add nuw i32 %j.019.us, 1
474  %cmp2.us = icmp ult i32 %inc.us, %N
475  br i1 %cmp2.us, label %for.body3.us, label %for.cond1.for.inc7_crit_edge.us
476
477for.cond1.for.inc7_crit_edge.us:
478  %inc8.us = add i32 %i.021.us, 1
479  %cmp.us = icmp ult i32 %inc8.us, %N
480  br i1 %cmp.us, label %for.cond1.preheader.us, label %for.end9.loopexit
481
482for.end9.loopexit:
483  br label %for.end9
484
485for.end9:
486  ret void
487}
488
489; This IR corresponds to this input:
490;
491; void test(char n, char m) {
492;   for(char i = 0; i < n; i++)
493;     for(char j = 0; j < m; j++) {
494;       char x = i*m+j;
495;       use_32(x);
496;     }
497; }
498;
499define void @test(i8 %n, i8 %m) {
500; CHECK-LABEL: @test(
501; CHECK-NEXT:  entry:
502; CHECK-NEXT:    [[CMP25_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
503; CHECK-NEXT:    br i1 [[CMP25_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
504; CHECK:       for.cond3.preheader.lr.ph:
505; CHECK-NEXT:    [[CMP623_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
506; CHECK-NEXT:    br i1 [[CMP623_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
507; CHECK:       for.cond3.preheader.preheader:
508; CHECK-NEXT:    br label [[FOR_COND3_PREHEADER:%.*]]
509; CHECK:       for.cond3.preheader.us.preheader:
510; CHECK-NEXT:    [[TMP0:%.*]] = zext i8 [[M]] to i64
511; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[N]] to i64
512; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
513; CHECK-NEXT:    br label [[FOR_COND3_PREHEADER_US:%.*]]
514; CHECK:       for.cond3.preheader.us:
515; CHECK-NEXT:    [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
516; CHECK-NEXT:    [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8
517; CHECK-NEXT:    br label [[FOR_BODY9_US:%.*]]
518; CHECK:       for.body9.us:
519; CHECK-NEXT:    [[CONV14_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i32
520; CHECK-NEXT:    [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
521; CHECK-NEXT:    br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
522; CHECK:       for.cond3.for.cond.cleanup8_crit_edge.us:
523; CHECK-NEXT:    [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1
524; CHECK-NEXT:    [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
525; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
526; CHECK:       for.cond3.preheader:
527; CHECK-NEXT:    [[I_026:%.*]] = phi i8 [ [[INC16:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
528; CHECK-NEXT:    [[INC16]] = add i8 [[I_026]], 1
529; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[INC16]], [[N]]
530; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
531; CHECK:       for.cond.cleanup.loopexit:
532; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
533; CHECK:       for.cond.cleanup.loopexit1:
534; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
535; CHECK:       for.cond.cleanup:
536; CHECK-NEXT:    ret void
537;
538; DONTWIDEN-LABEL: @test(
539; DONTWIDEN-NEXT:  entry:
540; DONTWIDEN-NEXT:    [[CMP25_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
541; DONTWIDEN-NEXT:    br i1 [[CMP25_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
542; DONTWIDEN:       for.cond3.preheader.lr.ph:
543; DONTWIDEN-NEXT:    [[CMP623_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
544; DONTWIDEN-NEXT:    br i1 [[CMP623_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
545; DONTWIDEN:       for.cond3.preheader.preheader:
546; DONTWIDEN-NEXT:    br label [[FOR_COND3_PREHEADER:%.*]]
547; DONTWIDEN:       for.cond3.preheader.us.preheader:
548; DONTWIDEN-NEXT:    br label [[FOR_COND3_PREHEADER_US:%.*]]
549; DONTWIDEN:       for.cond3.preheader.us:
550; DONTWIDEN-NEXT:    [[I_026_US:%.*]] = phi i8 [ [[INC16_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
551; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul i8 [[I_026_US]], [[M]]
552; DONTWIDEN-NEXT:    br label [[FOR_BODY9_US:%.*]]
553; DONTWIDEN:       for.body9.us:
554; DONTWIDEN-NEXT:    [[J_024_US:%.*]] = phi i8 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ]
555; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add i8 [[J_024_US]], [[MUL_US]]
556; DONTWIDEN-NEXT:    [[CONV14_US:%.*]] = zext i8 [[ADD_US]] to i32
557; DONTWIDEN-NEXT:    [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
558; DONTWIDEN-NEXT:    [[INC_US]] = add nuw i8 [[J_024_US]], 1
559; DONTWIDEN-NEXT:    [[CMP6_US:%.*]] = icmp ult i8 [[INC_US]], [[M]]
560; DONTWIDEN-NEXT:    br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
561; DONTWIDEN:       for.cond3.for.cond.cleanup8_crit_edge.us:
562; DONTWIDEN-NEXT:    [[INC16_US]] = add i8 [[I_026_US]], 1
563; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp ult i8 [[INC16_US]], [[N]]
564; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
565; DONTWIDEN:       for.cond3.preheader:
566; DONTWIDEN-NEXT:    [[I_026:%.*]] = phi i8 [ [[INC16:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
567; DONTWIDEN-NEXT:    [[INC16]] = add i8 [[I_026]], 1
568; DONTWIDEN-NEXT:    [[CMP:%.*]] = icmp ult i8 [[INC16]], [[N]]
569; DONTWIDEN-NEXT:    br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
570; DONTWIDEN:       for.cond.cleanup.loopexit:
571; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
572; DONTWIDEN:       for.cond.cleanup.loopexit1:
573; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
574; DONTWIDEN:       for.cond.cleanup:
575; DONTWIDEN-NEXT:    ret void
576;
577entry:
578  %cmp25.not = icmp eq i8 %n, 0
579  br i1 %cmp25.not, label %for.cond.cleanup, label %for.cond3.preheader.lr.ph
580
581for.cond3.preheader.lr.ph:
582  %cmp623.not = icmp eq i8 %m, 0
583  br i1 %cmp623.not, label %for.cond3.preheader.preheader, label %for.cond3.preheader.us.preheader
584
585for.cond3.preheader.preheader:
586  br label %for.cond3.preheader
587
588for.cond3.preheader.us.preheader:
589  br label %for.cond3.preheader.us
590
591for.cond3.preheader.us:
592  %i.026.us = phi i8 [ %inc16.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ]
593  %mul.us = mul i8 %i.026.us, %m
594  br label %for.body9.us
595
596for.body9.us:
597  %j.024.us = phi i8 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ]
598  %add.us = add i8 %j.024.us, %mul.us
599  %conv14.us = zext i8 %add.us to i32
600  %call.us = tail call i32 @use_32(i32 %conv14.us) #2
601  %inc.us = add nuw i8 %j.024.us, 1
602  %cmp6.us = icmp ult i8 %inc.us, %m
603  br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us
604
605for.cond3.for.cond.cleanup8_crit_edge.us:
606  %inc16.us = add i8 %i.026.us, 1
607  %cmp.us = icmp ult i8 %inc16.us, %n
608  br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup
609
610for.cond3.preheader:
611  %i.026 = phi i8 [ %inc16, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ]
612  %inc16 = add i8 %i.026, 1
613  %cmp = icmp ult i8 %inc16, %n
614  br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup
615
616for.cond.cleanup:
617  ret void
618}
619
620; This IR corresponds to this input:
621;
622; void test3(char n, char m) {
623;   for(char i = 0; i < n; i++)
624;     for(char j = 0; j < m; j++) {
625;       char x = i*m+j;
626;       use_32(x);
627;       use_16(x);
628;       use_32(x);
629;       use_16(x);
630;       use_64(x);
631;     }
632; }
633;
634define void @test3(i8 %n, i8 %m) {
635; CHECK-LABEL: @test3(
636; CHECK-NEXT:  entry:
637; CHECK-NEXT:    [[CMP37_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
638; CHECK-NEXT:    br i1 [[CMP37_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
639; CHECK:       for.cond3.preheader.lr.ph:
640; CHECK-NEXT:    [[CMP635_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
641; CHECK-NEXT:    br i1 [[CMP635_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
642; CHECK:       for.cond3.preheader.preheader:
643; CHECK-NEXT:    br label [[FOR_COND3_PREHEADER:%.*]]
644; CHECK:       for.cond3.preheader.us.preheader:
645; CHECK-NEXT:    [[TMP0:%.*]] = zext i8 [[M]] to i64
646; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[N]] to i64
647; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
648; CHECK-NEXT:    br label [[FOR_COND3_PREHEADER_US:%.*]]
649; CHECK:       for.cond3.preheader.us:
650; CHECK-NEXT:    [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
651; CHECK-NEXT:    [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8
652; CHECK-NEXT:    br label [[FOR_BODY9_US:%.*]]
653; CHECK:       for.body9.us:
654; CHECK-NEXT:    [[CONV14_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i32
655; CHECK-NEXT:    [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
656; CHECK-NEXT:    [[CONV15_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i16
657; CHECK-NEXT:    [[CALL16_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
658; CHECK-NEXT:    [[CALL18_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
659; CHECK-NEXT:    [[CALL20_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
660; CHECK-NEXT:    [[CONV21_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i64
661; CHECK-NEXT:    [[CALL22_US:%.*]] = tail call i32 @use_64(i64 [[CONV21_US]])
662; CHECK-NEXT:    br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
663; CHECK:       for.cond3.for.cond.cleanup8_crit_edge.us:
664; CHECK-NEXT:    [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1
665; CHECK-NEXT:    [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
666; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
667; CHECK:       for.cond3.preheader:
668; CHECK-NEXT:    [[I_038:%.*]] = phi i8 [ [[INC24:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
669; CHECK-NEXT:    [[INC24]] = add i8 [[I_038]], 1
670; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[INC24]], [[N]]
671; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
672; CHECK:       for.cond.cleanup.loopexit:
673; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
674; CHECK:       for.cond.cleanup.loopexit1:
675; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
676; CHECK:       for.cond.cleanup:
677; CHECK-NEXT:    ret void
678;
679; DONTWIDEN-LABEL: @test3(
680; DONTWIDEN-NEXT:  entry:
681; DONTWIDEN-NEXT:    [[CMP37_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
682; DONTWIDEN-NEXT:    br i1 [[CMP37_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
683; DONTWIDEN:       for.cond3.preheader.lr.ph:
684; DONTWIDEN-NEXT:    [[CMP635_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
685; DONTWIDEN-NEXT:    br i1 [[CMP635_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
686; DONTWIDEN:       for.cond3.preheader.preheader:
687; DONTWIDEN-NEXT:    br label [[FOR_COND3_PREHEADER:%.*]]
688; DONTWIDEN:       for.cond3.preheader.us.preheader:
689; DONTWIDEN-NEXT:    br label [[FOR_COND3_PREHEADER_US:%.*]]
690; DONTWIDEN:       for.cond3.preheader.us:
691; DONTWIDEN-NEXT:    [[I_038_US:%.*]] = phi i8 [ [[INC24_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
692; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul i8 [[I_038_US]], [[M]]
693; DONTWIDEN-NEXT:    br label [[FOR_BODY9_US:%.*]]
694; DONTWIDEN:       for.body9.us:
695; DONTWIDEN-NEXT:    [[J_036_US:%.*]] = phi i8 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ]
696; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add i8 [[J_036_US]], [[MUL_US]]
697; DONTWIDEN-NEXT:    [[CONV14_US:%.*]] = zext i8 [[ADD_US]] to i32
698; DONTWIDEN-NEXT:    [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
699; DONTWIDEN-NEXT:    [[CONV15_US:%.*]] = zext i8 [[ADD_US]] to i16
700; DONTWIDEN-NEXT:    [[CALL16_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
701; DONTWIDEN-NEXT:    [[CALL18_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
702; DONTWIDEN-NEXT:    [[CALL20_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
703; DONTWIDEN-NEXT:    [[CONV21_US:%.*]] = zext i8 [[ADD_US]] to i64
704; DONTWIDEN-NEXT:    [[CALL22_US:%.*]] = tail call i32 @use_64(i64 [[CONV21_US]])
705; DONTWIDEN-NEXT:    [[INC_US]] = add nuw i8 [[J_036_US]], 1
706; DONTWIDEN-NEXT:    [[CMP6_US:%.*]] = icmp ult i8 [[INC_US]], [[M]]
707; DONTWIDEN-NEXT:    br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
708; DONTWIDEN:       for.cond3.for.cond.cleanup8_crit_edge.us:
709; DONTWIDEN-NEXT:    [[INC24_US]] = add i8 [[I_038_US]], 1
710; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp ult i8 [[INC24_US]], [[N]]
711; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
712; DONTWIDEN:       for.cond3.preheader:
713; DONTWIDEN-NEXT:    [[I_038:%.*]] = phi i8 [ [[INC24:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
714; DONTWIDEN-NEXT:    [[INC24]] = add i8 [[I_038]], 1
715; DONTWIDEN-NEXT:    [[CMP:%.*]] = icmp ult i8 [[INC24]], [[N]]
716; DONTWIDEN-NEXT:    br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
717; DONTWIDEN:       for.cond.cleanup.loopexit:
718; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
719; DONTWIDEN:       for.cond.cleanup.loopexit1:
720; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
721; DONTWIDEN:       for.cond.cleanup:
722; DONTWIDEN-NEXT:    ret void
723;
724entry:
725  %cmp37.not = icmp eq i8 %n, 0
726  br i1 %cmp37.not, label %for.cond.cleanup, label %for.cond3.preheader.lr.ph
727
728for.cond3.preheader.lr.ph:
729  %cmp635.not = icmp eq i8 %m, 0
730  br i1 %cmp635.not, label %for.cond3.preheader.preheader, label %for.cond3.preheader.us.preheader
731
732for.cond3.preheader.preheader:
733  br label %for.cond3.preheader
734
735for.cond3.preheader.us.preheader:
736  br label %for.cond3.preheader.us
737
738for.cond3.preheader.us:
739  %i.038.us = phi i8 [ %inc24.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ]
740  %mul.us = mul i8 %i.038.us, %m
741  br label %for.body9.us
742
743for.body9.us:
744  %j.036.us = phi i8 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ]
745  %add.us = add i8 %j.036.us, %mul.us
746  %conv14.us = zext i8 %add.us to i32
747  %call.us = tail call i32 @use_32(i32 %conv14.us)
748  %conv15.us = zext i8 %add.us to i16
749  %call16.us = tail call i32 @use_16(i16 %conv15.us)
750  %call18.us = tail call i32 @use_32(i32 %conv14.us)
751  %call20.us = tail call i32 @use_16(i16 %conv15.us)
752  %conv21.us = zext i8 %add.us to i64
753  %call22.us = tail call i32 @use_64(i64 %conv21.us)
754  %inc.us = add nuw i8 %j.036.us, 1
755  %cmp6.us = icmp ult i8 %inc.us, %m
756  br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us
757
758for.cond3.for.cond.cleanup8_crit_edge.us:
759  %inc24.us = add i8 %i.038.us, 1
760  %cmp.us = icmp ult i8 %inc24.us, %n
761  br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup
762
763for.cond3.preheader:
764  %i.038 = phi i8 [ %inc24, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ]
765  %inc24 = add i8 %i.038, 1
766  %cmp = icmp ult i8 %inc24, %n
767  br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup
768
769for.cond.cleanup:
770  ret void
771}
772
773; This IR corresponds to this input:
774;
775; void test4(short n, short m) {
776;   for(short i = 0; i < n; i++)
777;     for(short j = 0; j < m; j++) {
778;       short x = i*m+j;
779;       use_32(x);
780;       use_16(x);
781;       use_32(x);
782;       use_16(x);
783;       use_64(x);
784;     }
785; }
786;
787define void @test4(i16 %n, i16 %m) {
788; CHECK-LABEL: @test4(
789; CHECK-NEXT:  entry:
790; CHECK-NEXT:    [[CMP38:%.*]] = icmp sgt i16 [[N:%.*]], 0
791; CHECK-NEXT:    br i1 [[CMP38]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
792; CHECK:       for.cond3.preheader.lr.ph:
793; CHECK-NEXT:    [[CMP636:%.*]] = icmp sgt i16 [[M:%.*]], 0
794; CHECK-NEXT:    br i1 [[CMP636]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]]
795; CHECK:       for.cond3.preheader.preheader:
796; CHECK-NEXT:    br label [[FOR_COND3_PREHEADER:%.*]]
797; CHECK:       for.cond3.preheader.us.preheader:
798; CHECK-NEXT:    [[TMP0:%.*]] = sext i16 [[M]] to i64
799; CHECK-NEXT:    [[TMP1:%.*]] = sext i16 [[N]] to i64
800; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
801; CHECK-NEXT:    br label [[FOR_COND3_PREHEADER_US:%.*]]
802; CHECK:       for.cond3.preheader.us:
803; CHECK-NEXT:    [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
804; CHECK-NEXT:    [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i16
805; CHECK-NEXT:    br label [[FOR_BODY9_US:%.*]]
806; CHECK:       for.body9.us:
807; CHECK-NEXT:    [[CONV14_US:%.*]] = sext i16 [[FLATTEN_TRUNCIV]] to i32
808; CHECK-NEXT:    [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
809; CHECK-NEXT:    [[CALL15_US:%.*]] = tail call i32 @use_16(i16 [[FLATTEN_TRUNCIV]])
810; CHECK-NEXT:    [[CALL17_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
811; CHECK-NEXT:    [[CALL18_US:%.*]] = tail call i32 @use_16(i16 [[FLATTEN_TRUNCIV]])
812; CHECK-NEXT:    [[CONV19_US:%.*]] = sext i16 [[FLATTEN_TRUNCIV]] to i64
813; CHECK-NEXT:    [[CALL20_US:%.*]] = tail call i32 @use_64(i64 [[CONV19_US]])
814; CHECK-NEXT:    br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
815; CHECK:       for.cond3.for.cond.cleanup8_crit_edge.us:
816; CHECK-NEXT:    [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1
817; CHECK-NEXT:    [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
818; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
819; CHECK:       for.cond3.preheader:
820; CHECK-NEXT:    [[I_039:%.*]] = phi i16 [ [[INC22:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
821; CHECK-NEXT:    [[INC22]] = add i16 [[I_039]], 1
822; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[INC22]], [[N]]
823; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
824; CHECK:       for.cond.cleanup.loopexit:
825; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
826; CHECK:       for.cond.cleanup.loopexit1:
827; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
828; CHECK:       for.cond.cleanup:
829; CHECK-NEXT:    ret void
830;
831; DONTWIDEN-LABEL: @test4(
832; DONTWIDEN-NEXT:  entry:
833; DONTWIDEN-NEXT:    [[CMP38:%.*]] = icmp sgt i16 [[N:%.*]], 0
834; DONTWIDEN-NEXT:    br i1 [[CMP38]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
835; DONTWIDEN:       for.cond3.preheader.lr.ph:
836; DONTWIDEN-NEXT:    [[CMP636:%.*]] = icmp sgt i16 [[M:%.*]], 0
837; DONTWIDEN-NEXT:    br i1 [[CMP636]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]]
838; DONTWIDEN:       for.cond3.preheader.preheader:
839; DONTWIDEN-NEXT:    br label [[FOR_COND3_PREHEADER:%.*]]
840; DONTWIDEN:       for.cond3.preheader.us.preheader:
841; DONTWIDEN-NEXT:    br label [[FOR_COND3_PREHEADER_US:%.*]]
842; DONTWIDEN:       for.cond3.preheader.us:
843; DONTWIDEN-NEXT:    [[I_039_US:%.*]] = phi i16 [ [[INC22_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
844; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul i16 [[I_039_US]], [[M]]
845; DONTWIDEN-NEXT:    br label [[FOR_BODY9_US:%.*]]
846; DONTWIDEN:       for.body9.us:
847; DONTWIDEN-NEXT:    [[J_037_US:%.*]] = phi i16 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ]
848; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add i16 [[J_037_US]], [[MUL_US]]
849; DONTWIDEN-NEXT:    [[CONV14_US:%.*]] = sext i16 [[ADD_US]] to i32
850; DONTWIDEN-NEXT:    [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
851; DONTWIDEN-NEXT:    [[CALL15_US:%.*]] = tail call i32 @use_16(i16 [[ADD_US]])
852; DONTWIDEN-NEXT:    [[CALL17_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
853; DONTWIDEN-NEXT:    [[CALL18_US:%.*]] = tail call i32 @use_16(i16 [[ADD_US]])
854; DONTWIDEN-NEXT:    [[CONV19_US:%.*]] = sext i16 [[ADD_US]] to i64
855; DONTWIDEN-NEXT:    [[CALL20_US:%.*]] = tail call i32 @use_64(i64 [[CONV19_US]])
856; DONTWIDEN-NEXT:    [[INC_US]] = add nuw nsw i16 [[J_037_US]], 1
857; DONTWIDEN-NEXT:    [[CMP6_US:%.*]] = icmp slt i16 [[INC_US]], [[M]]
858; DONTWIDEN-NEXT:    br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
859; DONTWIDEN:       for.cond3.for.cond.cleanup8_crit_edge.us:
860; DONTWIDEN-NEXT:    [[INC22_US]] = add i16 [[I_039_US]], 1
861; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp slt i16 [[INC22_US]], [[N]]
862; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
863; DONTWIDEN:       for.cond3.preheader:
864; DONTWIDEN-NEXT:    [[I_039:%.*]] = phi i16 [ [[INC22:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
865; DONTWIDEN-NEXT:    [[INC22]] = add i16 [[I_039]], 1
866; DONTWIDEN-NEXT:    [[CMP:%.*]] = icmp slt i16 [[INC22]], [[N]]
867; DONTWIDEN-NEXT:    br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
868; DONTWIDEN:       for.cond.cleanup.loopexit:
869; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
870; DONTWIDEN:       for.cond.cleanup.loopexit1:
871; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
872; DONTWIDEN:       for.cond.cleanup:
873; DONTWIDEN-NEXT:    ret void
874;
875entry:
876  %cmp38 = icmp sgt i16 %n, 0
877  br i1 %cmp38, label %for.cond3.preheader.lr.ph, label %for.cond.cleanup
878
879for.cond3.preheader.lr.ph:
880  %cmp636 = icmp sgt i16 %m, 0
881  br i1 %cmp636, label %for.cond3.preheader.us.preheader, label %for.cond3.preheader.preheader
882
883for.cond3.preheader.preheader:
884  br label %for.cond3.preheader
885
886for.cond3.preheader.us.preheader:
887  br label %for.cond3.preheader.us
888
889for.cond3.preheader.us:
890  %i.039.us = phi i16 [ %inc22.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ]
891  %mul.us = mul i16 %i.039.us, %m
892  br label %for.body9.us
893
894for.body9.us:
895  %j.037.us = phi i16 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ]
896  %add.us = add i16 %j.037.us, %mul.us
897  %conv14.us = sext i16 %add.us to i32
898  %call.us = tail call i32 @use_32(i32 %conv14.us) #2
899  %call15.us = tail call i32 @use_16(i16 %add.us) #2
900  %call17.us = tail call i32 @use_32(i32 %conv14.us) #2
901  %call18.us = tail call i32 @use_16(i16 %add.us) #2
902  %conv19.us = sext i16 %add.us to i64
903  %call20.us = tail call i32 @use_64(i64 %conv19.us) #2
904  %inc.us = add nuw nsw i16 %j.037.us, 1
905  %cmp6.us = icmp slt i16 %inc.us, %m
906  br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us
907
908for.cond3.for.cond.cleanup8_crit_edge.us:
909  %inc22.us = add i16 %i.039.us, 1
910  %cmp.us = icmp slt i16 %inc22.us, %n
911  br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup
912
913for.cond3.preheader:
914  %i.039 = phi i16 [ %inc22, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ]
915  %inc22 = add i16 %i.039, 1
916  %cmp = icmp slt i16 %inc22, %n
917  br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup
918
919for.cond.cleanup:
920  ret void
921}
922
923; Identify trip count when it is constant and the IV has been widened.
924define i32 @constTripCount() {
925; CHECK-LABEL: @constTripCount(
926; CHECK-NEXT:  entry:
927; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 20, 20
928; CHECK-NEXT:    br label [[I_LOOP:%.*]]
929; CHECK:       i.loop:
930; CHECK-NEXT:    [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[J_LOOPDONE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
931; CHECK-NEXT:    br label [[J_LOOP:%.*]]
932; CHECK:       j.loop:
933; CHECK-NEXT:    call void @payload()
934; CHECK-NEXT:    br label [[J_LOOPDONE]]
935; CHECK:       j.loopdone:
936; CHECK-NEXT:    [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1
937; CHECK-NEXT:    [[I_ATEND:%.*]] = icmp eq i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]]
938; CHECK-NEXT:    br i1 [[I_ATEND]], label [[I_LOOPDONE:%.*]], label [[I_LOOP]]
939; CHECK:       i.loopdone:
940; CHECK-NEXT:    ret i32 0
941;
942; DONTWIDEN-LABEL: @constTripCount(
943; DONTWIDEN-NEXT:  entry:
944; DONTWIDEN-NEXT:    br label [[I_LOOP:%.*]]
945; DONTWIDEN:       i.loop:
946; DONTWIDEN-NEXT:    [[I:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[J_LOOPDONE:%.*]] ]
947; DONTWIDEN-NEXT:    br label [[J_LOOP:%.*]]
948; DONTWIDEN:       j.loop:
949; DONTWIDEN-NEXT:    [[J:%.*]] = phi i8 [ 0, [[I_LOOP]] ], [ [[J_INC:%.*]], [[J_LOOP]] ]
950; DONTWIDEN-NEXT:    call void @payload()
951; DONTWIDEN-NEXT:    [[J_INC]] = add i8 [[J]], 1
952; DONTWIDEN-NEXT:    [[J_ATEND:%.*]] = icmp eq i8 [[J_INC]], 20
953; DONTWIDEN-NEXT:    br i1 [[J_ATEND]], label [[J_LOOPDONE]], label [[J_LOOP]]
954; DONTWIDEN:       j.loopdone:
955; DONTWIDEN-NEXT:    [[I_INC]] = add i8 [[I]], 1
956; DONTWIDEN-NEXT:    [[I_ATEND:%.*]] = icmp eq i8 [[I_INC]], 20
957; DONTWIDEN-NEXT:    br i1 [[I_ATEND]], label [[I_LOOPDONE:%.*]], label [[I_LOOP]]
958; DONTWIDEN:       i.loopdone:
959; DONTWIDEN-NEXT:    ret i32 0
960;
961entry:
962  br label %i.loop
963
964i.loop:
965  %i = phi i8 [ 0, %entry ], [ %i.inc, %j.loopdone ]
966  br label %j.loop
967
968j.loop:
969  %j = phi i8 [ 0, %i.loop ], [ %j.inc, %j.loop ]
970  call void @payload()
971  %j.inc = add i8 %j, 1
972  %j.atend = icmp eq i8 %j.inc, 20
973  br i1 %j.atend, label %j.loopdone, label %j.loop
974
975j.loopdone:
976  %i.inc = add i8 %i, 1
977  %i.atend = icmp eq i8 %i.inc, 20
978  br i1 %i.atend, label %i.loopdone, label %i.loop
979
980i.loopdone:
981  ret i32 0
982}
983
984; Same as @foo, but M is sext from i16. This used to assert because we thought
985; this sext was from widening and try to look through it.
986define void @foo_M_sext(ptr %A, i32 %N, i16 %M) {
987; CHECK-LABEL: @foo_M_sext(
988; CHECK-NEXT:  entry:
989; CHECK-NEXT:    [[M2:%.*]] = sext i16 [[M:%.*]] to i32
990; CHECK-NEXT:    [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
991; CHECK-NEXT:    br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
992; CHECK:       for.cond1.preheader.lr.ph:
993; CHECK-NEXT:    [[CMP215:%.*]] = icmp sgt i32 [[M2]], 0
994; CHECK-NEXT:    br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
995; CHECK:       for.cond1.preheader.us.preheader:
996; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[M2]] to i64
997; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[N]] to i64
998; CHECK-NEXT:    [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
999; CHECK-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
1000; CHECK:       for.cond1.preheader.us:
1001; CHECK-NEXT:    [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
1002; CHECK-NEXT:    br label [[FOR_BODY4_US:%.*]]
1003; CHECK:       for.body4.us:
1004; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]]
1005; CHECK-NEXT:    tail call void @f(ptr [[ARRAYIDX_US]])
1006; CHECK-NEXT:    br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
1007; CHECK:       for.cond1.for.cond.cleanup3_crit_edge.us:
1008; CHECK-NEXT:    [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1
1009; CHECK-NEXT:    [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
1010; CHECK-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
1011; CHECK:       for.cond.cleanup.loopexit:
1012; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
1013; CHECK:       for.cond.cleanup:
1014; CHECK-NEXT:    ret void
1015;
1016; DONTWIDEN-LABEL: @foo_M_sext(
1017; DONTWIDEN-NEXT:  entry:
1018; DONTWIDEN-NEXT:    [[M2:%.*]] = sext i16 [[M:%.*]] to i32
1019; DONTWIDEN-NEXT:    [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
1020; DONTWIDEN-NEXT:    br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
1021; DONTWIDEN:       for.cond1.preheader.lr.ph:
1022; DONTWIDEN-NEXT:    [[CMP215:%.*]] = icmp sgt i32 [[M2]], 0
1023; DONTWIDEN-NEXT:    br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
1024; DONTWIDEN:       for.cond1.preheader.us.preheader:
1025; DONTWIDEN-NEXT:    br label [[FOR_COND1_PREHEADER_US:%.*]]
1026; DONTWIDEN:       for.cond1.preheader.us:
1027; DONTWIDEN-NEXT:    [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
1028; DONTWIDEN-NEXT:    [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M2]]
1029; DONTWIDEN-NEXT:    br label [[FOR_BODY4_US:%.*]]
1030; DONTWIDEN:       for.body4.us:
1031; DONTWIDEN-NEXT:    [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
1032; DONTWIDEN-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]]
1033; DONTWIDEN-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
1034; DONTWIDEN-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
1035; DONTWIDEN-NEXT:    tail call void @f(ptr [[ARRAYIDX_US]])
1036; DONTWIDEN-NEXT:    [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1
1037; DONTWIDEN-NEXT:    [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M2]]
1038; DONTWIDEN-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
1039; DONTWIDEN:       for.cond1.for.cond.cleanup3_crit_edge.us:
1040; DONTWIDEN-NEXT:    [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1
1041; DONTWIDEN-NEXT:    [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]]
1042; DONTWIDEN-NEXT:    br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
1043; DONTWIDEN:       for.cond.cleanup.loopexit:
1044; DONTWIDEN-NEXT:    br label [[FOR_COND_CLEANUP]]
1045; DONTWIDEN:       for.cond.cleanup:
1046; DONTWIDEN-NEXT:    ret void
1047;
1048entry:
1049  %M2 = sext i16 %M to i32
1050  %cmp17 = icmp sgt i32 %N, 0
1051  br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup
1052
1053for.cond1.preheader.lr.ph:
1054  %cmp215 = icmp sgt i32 %M2, 0
1055  br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond.cleanup
1056
1057for.cond1.preheader.us.preheader:
1058  br label %for.cond1.preheader.us
1059
1060for.cond1.preheader.us:
1061  %i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
1062  %mul.us = mul nsw i32 %i.018.us, %M2
1063  br label %for.body4.us
1064
1065for.body4.us:
1066  %j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
1067  %add.us = add nsw i32 %j.016.us, %mul.us
1068  %idxprom.us = sext i32 %add.us to i64
1069  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
1070  tail call void @f(ptr %arrayidx.us) #2
1071  %inc.us = add nuw nsw i32 %j.016.us, 1
1072  %cmp2.us = icmp slt i32 %inc.us, %M2
1073  br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
1074
1075for.cond1.for.cond.cleanup3_crit_edge.us:
1076  %inc6.us = add nuw nsw i32 %i.018.us, 1
1077  %cmp.us = icmp slt i32 %inc6.us, %N
1078  br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup
1079
1080for.cond.cleanup:
1081  ret void
1082}
1083
1084declare void @payload()
1085declare dso_local i32 @use_32(i32)
1086declare dso_local i32 @use_16(i16)
1087declare dso_local i32 @use_64(i64)
1088declare dso_local void @g(i32)
1089
1090declare dso_local void @f(ptr %0) local_unnamed_addr #1
1091