xref: /llvm-project/llvm/test/Transforms/HardwareLoops/scalar-while-strictfp.ll (revision 702e2da15a1c5e728c042afd094eccf1cb3741f0)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes
2; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32>' -S %s -o - | FileCheck %s --check-prefix=CHECK-DEC
3; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32;force-hardware-loop-phi>' -S %s -o - | FileCheck %s --check-prefix=CHECK-PHI
4
5define void @while_lt(i32 %i, i32 %N, ptr nocapture %A) strictfp {
6; CHECK-DEC: Function Attrs: strictfp
7; CHECK-DEC-LABEL: @while_lt(
8; CHECK-DEC-NEXT:  entry:
9; CHECK-DEC-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
10; CHECK-DEC-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
11; CHECK-DEC:       while.body.preheader:
12; CHECK-DEC-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
13; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0:[0-9]+]]
14; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
15; CHECK-DEC:       while.body:
16; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
17; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
18; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
19; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
20; CHECK-DEC-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
21; CHECK-DEC-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
22; CHECK-DEC:       while.end:
23; CHECK-DEC-NEXT:    ret void
24;
25; CHECK-PHI: Function Attrs: strictfp
26; CHECK-PHI-LABEL: @while_lt(
27; CHECK-PHI-NEXT:  entry:
28; CHECK-PHI-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
29; CHECK-PHI-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
30; CHECK-PHI:       while.body.preheader:
31; CHECK-PHI-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
32; CHECK-PHI-NEXT:    [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0:[0-9]+]]
33; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
34; CHECK-PHI:       while.body:
35; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
36; CHECK-PHI-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ]
37; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
38; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
39; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
40; CHECK-PHI-NEXT:    [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1) #[[ATTR0]]
41; CHECK-PHI-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
42; CHECK-PHI-NEXT:    br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]]
43; CHECK-PHI:       while.end:
44; CHECK-PHI-NEXT:    ret void
45;
46entry:
47  %cmp4 = icmp ult i32 %i, %N
48  br i1 %cmp4, label %while.body, label %while.end
49
50while.body:
51  %i.addr.05 = phi i32 [ %inc, %while.body ], [ %i, %entry ]
52  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
53  store i32 %i.addr.05, ptr %arrayidx, align 4
54  %inc = add nuw i32 %i.addr.05, 1
55  %exitcond = icmp eq i32 %inc, %N
56  br i1 %exitcond, label %while.end, label %while.body
57
58while.end:
59  ret void
60}
61
62define void @while_gt(i32 %i, i32 %N, ptr nocapture %A) strictfp {
63; CHECK-DEC: Function Attrs: strictfp
64; CHECK-DEC-LABEL: @while_gt(
65; CHECK-DEC-NEXT:  entry:
66; CHECK-DEC-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
67; CHECK-DEC-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
68; CHECK-DEC:       while.body.preheader:
69; CHECK-DEC-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
70; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0]]
71; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
72; CHECK-DEC:       while.body:
73; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
74; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
75; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
76; CHECK-DEC-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
77; CHECK-DEC-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
78; CHECK-DEC-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
79; CHECK-DEC:       while.end:
80; CHECK-DEC-NEXT:    ret void
81;
82; CHECK-PHI: Function Attrs: strictfp
83; CHECK-PHI-LABEL: @while_gt(
84; CHECK-PHI-NEXT:  entry:
85; CHECK-PHI-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
86; CHECK-PHI-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
87; CHECK-PHI:       while.body.preheader:
88; CHECK-PHI-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
89; CHECK-PHI-NEXT:    [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]]) #[[ATTR0]]
90; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
91; CHECK-PHI:       while.body:
92; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
93; CHECK-PHI-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ]
94; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
95; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
96; CHECK-PHI-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
97; CHECK-PHI-NEXT:    [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1) #[[ATTR0]]
98; CHECK-PHI-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
99; CHECK-PHI-NEXT:    br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]]
100; CHECK-PHI:       while.end:
101; CHECK-PHI-NEXT:    ret void
102;
103entry:
104  %cmp4 = icmp sgt i32 %i, %N
105  br i1 %cmp4, label %while.body, label %while.end
106
107while.body:
108  %i.addr.05 = phi i32 [ %dec, %while.body ], [ %i, %entry ]
109  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
110  store i32 %i.addr.05, ptr %arrayidx, align 4
111  %dec = add nsw i32 %i.addr.05, -1
112  %cmp = icmp sgt i32 %dec, %N
113  br i1 %cmp, label %while.body, label %while.end
114
115while.end:
116  ret void
117}
118
119define void @while_gte(i32 %i, i32 %N, ptr nocapture %A) strictfp {
120; CHECK-DEC: Function Attrs: strictfp
121; CHECK-DEC-LABEL: @while_gte(
122; CHECK-DEC-NEXT:  entry:
123; CHECK-DEC-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
124; CHECK-DEC-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
125; CHECK-DEC:       while.body.preheader:
126; CHECK-DEC-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
127; CHECK-DEC-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
128; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP1]]) #[[ATTR0]]
129; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
130; CHECK-DEC:       while.body:
131; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
132; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
133; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
134; CHECK-DEC-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
135; CHECK-DEC-NEXT:    [[TMP2:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
136; CHECK-DEC-NEXT:    br i1 [[TMP2]], label [[WHILE_BODY]], label [[WHILE_END]]
137; CHECK-DEC:       while.end:
138; CHECK-DEC-NEXT:    ret void
139;
140; CHECK-PHI: Function Attrs: strictfp
141; CHECK-PHI-LABEL: @while_gte(
142; CHECK-PHI-NEXT:  entry:
143; CHECK-PHI-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
144; CHECK-PHI-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
145; CHECK-PHI:       while.body.preheader:
146; CHECK-PHI-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
147; CHECK-PHI-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
148; CHECK-PHI-NEXT:    [[TMP2:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP1]]) #[[ATTR0]]
149; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
150; CHECK-PHI:       while.body:
151; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
152; CHECK-PHI-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ]
153; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
154; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
155; CHECK-PHI-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
156; CHECK-PHI-NEXT:    [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1) #[[ATTR0]]
157; CHECK-PHI-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0
158; CHECK-PHI-NEXT:    br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]]
159; CHECK-PHI:       while.end:
160; CHECK-PHI-NEXT:    ret void
161;
162entry:
163  %cmp4 = icmp slt i32 %i, %N
164  br i1 %cmp4, label %while.end, label %while.body
165
166while.body:
167  %i.addr.05 = phi i32 [ %dec, %while.body ], [ %i, %entry ]
168  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
169  store i32 %i.addr.05, ptr %arrayidx, align 4
170  %dec = add nsw i32 %i.addr.05, -1
171  %cmp = icmp sgt i32 %i.addr.05, %N
172  br i1 %cmp, label %while.body, label %while.end
173
174while.end:
175  ret void
176}
177
178define void @while_ne(i32 %N, ptr nocapture %A) strictfp {
179; CHECK-DEC: Function Attrs: strictfp
180; CHECK-DEC-LABEL: @while_ne(
181; CHECK-DEC-NEXT:  entry:
182; CHECK-DEC-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
183; CHECK-DEC-NEXT:    br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
184; CHECK-DEC:       while.body.preheader:
185; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
186; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
187; CHECK-DEC:       while.body:
188; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
189; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
190; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
191; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
192; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
193; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
194; CHECK-DEC:       while.end:
195; CHECK-DEC-NEXT:    ret void
196;
197; CHECK-PHI: Function Attrs: strictfp
198; CHECK-PHI-LABEL: @while_ne(
199; CHECK-PHI-NEXT:  entry:
200; CHECK-PHI-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
201; CHECK-PHI-NEXT:    br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
202; CHECK-PHI:       while.body.preheader:
203; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
204; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
205; CHECK-PHI:       while.body:
206; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
207; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ]
208; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
209; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
210; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
211; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]]
212; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
213; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]]
214; CHECK-PHI:       while.end:
215; CHECK-PHI-NEXT:    ret void
216;
217entry:
218  %cmp = icmp ne i32 %N, 0
219  br i1 %cmp, label %while.body, label %while.end
220
221while.body:
222  %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
223  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
224  store i32 %i.addr.05, ptr %arrayidx, align 4
225  %inc = add nuw i32 %i.addr.05, 1
226  %exitcond = icmp eq i32 %inc, %N
227  br i1 %exitcond, label %while.end, label %while.body
228
229while.end:
230  ret void
231}
232
233define void @while_eq(i32 %N, ptr nocapture %A) strictfp {
234; CHECK-DEC: Function Attrs: strictfp
235; CHECK-DEC-LABEL: @while_eq(
236; CHECK-DEC-NEXT:  entry:
237; CHECK-DEC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
238; CHECK-DEC-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
239; CHECK-DEC:       while.body.preheader:
240; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
241; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
242; CHECK-DEC:       while.body:
243; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
244; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
245; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
246; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
247; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
248; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
249; CHECK-DEC:       while.end:
250; CHECK-DEC-NEXT:    ret void
251;
252; CHECK-PHI: Function Attrs: strictfp
253; CHECK-PHI-LABEL: @while_eq(
254; CHECK-PHI-NEXT:  entry:
255; CHECK-PHI-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
256; CHECK-PHI-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
257; CHECK-PHI:       while.body.preheader:
258; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
259; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
260; CHECK-PHI:       while.body:
261; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
262; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ]
263; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
264; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
265; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
266; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]]
267; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
268; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]]
269; CHECK-PHI:       while.end:
270; CHECK-PHI-NEXT:    ret void
271;
272entry:
273  %cmp = icmp eq i32 %N, 0
274  br i1 %cmp, label %while.end, label %while.body
275
276while.body:
277  %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
278  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
279  store i32 %i.addr.05, ptr %arrayidx, align 4
280  %inc = add nuw i32 %i.addr.05, 1
281  %exitcond = icmp eq i32 %inc, %N
282  br i1 %exitcond, label %while.end, label %while.body
283
284while.end:
285  ret void
286}
287
288define void @while_preheader_eq(i32 %N, ptr nocapture %A) strictfp {
289; CHECK-DEC: Function Attrs: strictfp
290; CHECK-DEC-LABEL: @while_preheader_eq(
291; CHECK-DEC-NEXT:  entry:
292; CHECK-DEC-NEXT:    br label [[PREHEADER:%.*]]
293; CHECK-DEC:       preheader:
294; CHECK-DEC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
295; CHECK-DEC-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
296; CHECK-DEC:       while.body.preheader:
297; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
298; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
299; CHECK-DEC:       while.body:
300; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
301; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
302; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
303; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
304; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
305; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
306; CHECK-DEC:       while.end:
307; CHECK-DEC-NEXT:    ret void
308;
309; CHECK-PHI: Function Attrs: strictfp
310; CHECK-PHI-LABEL: @while_preheader_eq(
311; CHECK-PHI-NEXT:  entry:
312; CHECK-PHI-NEXT:    br label [[PREHEADER:%.*]]
313; CHECK-PHI:       preheader:
314; CHECK-PHI-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
315; CHECK-PHI-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
316; CHECK-PHI:       while.body.preheader:
317; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
318; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
319; CHECK-PHI:       while.body:
320; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
321; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ]
322; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
323; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
324; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
325; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]]
326; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
327; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]]
328; CHECK-PHI:       while.end:
329; CHECK-PHI-NEXT:    ret void
330;
331entry:
332  br label %preheader
333
334preheader:
335  %cmp = icmp eq i32 %N, 0
336  br i1 %cmp, label %while.end, label %while.body
337
338while.body:
339  %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %preheader ]
340  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
341  store i32 %i.addr.05, ptr %arrayidx, align 4
342  %inc = add nuw i32 %i.addr.05, 1
343  %exitcond = icmp eq i32 %inc, %N
344  br i1 %exitcond, label %while.end, label %while.body
345
346while.end:
347  ret void
348}
349
350define void @nested(ptr nocapture %A, i32 %N) strictfp {
351; CHECK-DEC: Function Attrs: strictfp
352; CHECK-DEC-LABEL: @nested(
353; CHECK-DEC-NEXT:  entry:
354; CHECK-DEC-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
355; CHECK-DEC-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]]
356; CHECK-DEC:       while.cond1.preheader.us:
357; CHECK-DEC-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ]
358; CHECK-DEC-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
359; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
360; CHECK-DEC-NEXT:    br label [[WHILE_BODY3_US:%.*]]
361; CHECK-DEC:       while.body3.us:
362; CHECK-DEC-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
363; CHECK-DEC-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
364; CHECK-DEC-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
365; CHECK-DEC-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
366; CHECK-DEC-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
367; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1) #[[ATTR0]]
368; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
369; CHECK-DEC:       while.cond1.while.end_crit_edge.us:
370; CHECK-DEC-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
371; CHECK-DEC-NEXT:    [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]]
372; CHECK-DEC-NEXT:    br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]]
373; CHECK-DEC:       while.end7:
374; CHECK-DEC-NEXT:    ret void
375;
376; CHECK-PHI: Function Attrs: strictfp
377; CHECK-PHI-LABEL: @nested(
378; CHECK-PHI-NEXT:  entry:
379; CHECK-PHI-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
380; CHECK-PHI-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]]
381; CHECK-PHI:       while.cond1.preheader.us:
382; CHECK-PHI-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ]
383; CHECK-PHI-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
384; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]]) #[[ATTR0]]
385; CHECK-PHI-NEXT:    br label [[WHILE_BODY3_US:%.*]]
386; CHECK-PHI:       while.body3.us:
387; CHECK-PHI-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
388; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_COND1_PREHEADER_US]] ], [ [[TMP2:%.*]], [[WHILE_BODY3_US]] ]
389; CHECK-PHI-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
390; CHECK-PHI-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
391; CHECK-PHI-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
392; CHECK-PHI-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
393; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1) #[[ATTR0]]
394; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
395; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
396; CHECK-PHI:       while.cond1.while.end_crit_edge.us:
397; CHECK-PHI-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
398; CHECK-PHI-NEXT:    [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]]
399; CHECK-PHI-NEXT:    br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]]
400; CHECK-PHI:       while.end7:
401; CHECK-PHI-NEXT:    ret void
402;
403entry:
404  %cmp20 = icmp eq i32 %N, 0
405  br i1 %cmp20, label %while.end7, label %while.cond1.preheader.us
406
407while.cond1.preheader.us:
408  %i.021.us = phi i32 [ %inc6.us, %while.cond1.while.end_crit_edge.us ], [ 0, %entry ]
409  %mul.us = mul i32 %i.021.us, %N
410  br label %while.body3.us
411
412while.body3.us:
413  %j.019.us = phi i32 [ 0, %while.cond1.preheader.us ], [ %inc.us, %while.body3.us ]
414  %add.us = add i32 %j.019.us, %mul.us
415  %arrayidx.us = getelementptr inbounds i32, ptr %A, i32 %add.us
416  store i32 %add.us, ptr %arrayidx.us, align 4
417  %inc.us = add nuw i32 %j.019.us, 1
418  %exitcond = icmp eq i32 %inc.us, %N
419  br i1 %exitcond, label %while.cond1.while.end_crit_edge.us, label %while.body3.us
420
421while.cond1.while.end_crit_edge.us:
422  %inc6.us = add nuw i32 %i.021.us, 1
423  %exitcond23 = icmp eq i32 %inc6.us, %N
424  br i1 %exitcond23, label %while.end7, label %while.cond1.preheader.us
425
426while.end7:
427  ret void
428}
429