xref: /llvm-project/llvm/test/Transforms/HardwareLoops/scalar-while.ll (revision 2a58be42396376e8d552158ff801d953c6c1bee3)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
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; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32;force-nested-hardware-loop>' -S %s -o - | FileCheck %s --check-prefix=CHECK-NESTED
5; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32;force-hardware-loop-guard>' -S %s -o - | FileCheck %s --check-prefix=CHECK-GUARD
6; RUN: opt -passes='hardware-loops<force-hardware-loops;hardware-loop-decrement=1;hardware-loop-counter-bitwidth=32;force-hardware-loop-phi;force-hardware-loop-guard>' -S %s -o - | FileCheck %s --check-prefix=CHECK-PHIGUARD
7
8define void @while_lt(i32 %i, i32 %N, ptr nocapture %A) {
9; CHECK-DEC-LABEL: @while_lt(
10; CHECK-DEC-NEXT:  entry:
11; CHECK-DEC-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
12; CHECK-DEC-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
13; CHECK-DEC:       while.body.preheader:
14; CHECK-DEC-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
15; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]])
16; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
17; CHECK-DEC:       while.body:
18; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
19; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
20; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
21; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
22; CHECK-DEC-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
23; CHECK-DEC-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
24; CHECK-DEC:       while.end:
25; CHECK-DEC-NEXT:    ret void
26;
27; CHECK-PHI-LABEL: @while_lt(
28; CHECK-PHI-NEXT:  entry:
29; CHECK-PHI-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
30; CHECK-PHI-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
31; CHECK-PHI:       while.body.preheader:
32; CHECK-PHI-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
33; CHECK-PHI-NEXT:    [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]])
34; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
35; CHECK-PHI:       while.body:
36; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
37; CHECK-PHI-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ]
38; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
39; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
40; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
41; CHECK-PHI-NEXT:    [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1)
42; CHECK-PHI-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
43; CHECK-PHI-NEXT:    br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]]
44; CHECK-PHI:       while.end:
45; CHECK-PHI-NEXT:    ret void
46;
47; CHECK-NESTED-LABEL: @while_lt(
48; CHECK-NESTED-NEXT:  entry:
49; CHECK-NESTED-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
50; CHECK-NESTED-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
51; CHECK-NESTED:       while.body.preheader:
52; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
53; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]])
54; CHECK-NESTED-NEXT:    br label [[WHILE_BODY:%.*]]
55; CHECK-NESTED:       while.body:
56; CHECK-NESTED-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
57; CHECK-NESTED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
58; CHECK-NESTED-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
59; CHECK-NESTED-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
60; CHECK-NESTED-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
61; CHECK-NESTED-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
62; CHECK-NESTED:       while.end:
63; CHECK-NESTED-NEXT:    ret void
64;
65; CHECK-GUARD-LABEL: @while_lt(
66; CHECK-GUARD-NEXT:  entry:
67; CHECK-GUARD-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
68; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
69; CHECK-GUARD-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
70; CHECK-GUARD:       while.body.preheader:
71; CHECK-GUARD-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]])
72; CHECK-GUARD-NEXT:    br label [[WHILE_BODY:%.*]]
73; CHECK-GUARD:       while.body:
74; CHECK-GUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
75; CHECK-GUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
76; CHECK-GUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
77; CHECK-GUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
78; CHECK-GUARD-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
79; CHECK-GUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
80; CHECK-GUARD:       while.end:
81; CHECK-GUARD-NEXT:    ret void
82;
83; CHECK-PHIGUARD-LABEL: @while_lt(
84; CHECK-PHIGUARD-NEXT:  entry:
85; CHECK-PHIGUARD-NEXT:    [[CMP4:%.*]] = icmp ult i32 [[I:%.*]], [[N:%.*]]
86; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = sub i32 [[N]], [[I]]
87; CHECK-PHIGUARD-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
88; CHECK-PHIGUARD:       while.body.preheader:
89; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]])
90; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY:%.*]]
91; CHECK-PHIGUARD:       while.body:
92; CHECK-PHIGUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
93; CHECK-PHIGUARD-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ]
94; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
95; CHECK-PHIGUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
96; CHECK-PHIGUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
97; CHECK-PHIGUARD-NEXT:    [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1)
98; CHECK-PHIGUARD-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
99; CHECK-PHIGUARD-NEXT:    br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]]
100; CHECK-PHIGUARD:       while.end:
101; CHECK-PHIGUARD-NEXT:    ret void
102;
103entry:
104  %cmp4 = icmp ult i32 %i, %N
105  br i1 %cmp4, label %while.body, label %while.end
106
107while.body:
108  %i.addr.05 = phi i32 [ %inc, %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  %inc = add nuw i32 %i.addr.05, 1
112  %exitcond = icmp eq i32 %inc, %N
113  br i1 %exitcond, label %while.end, label %while.body
114
115while.end:
116  ret void
117}
118
119define void @while_gt(i32 %i, i32 %N, ptr nocapture %A) {
120; CHECK-DEC-LABEL: @while_gt(
121; CHECK-DEC-NEXT:  entry:
122; CHECK-DEC-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
123; CHECK-DEC-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
124; CHECK-DEC:       while.body.preheader:
125; CHECK-DEC-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
126; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]])
127; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
128; CHECK-DEC:       while.body:
129; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
130; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
131; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
132; CHECK-DEC-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
133; CHECK-DEC-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
134; CHECK-DEC-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
135; CHECK-DEC:       while.end:
136; CHECK-DEC-NEXT:    ret void
137;
138; CHECK-PHI-LABEL: @while_gt(
139; CHECK-PHI-NEXT:  entry:
140; CHECK-PHI-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
141; CHECK-PHI-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
142; CHECK-PHI:       while.body.preheader:
143; CHECK-PHI-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
144; CHECK-PHI-NEXT:    [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]])
145; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
146; CHECK-PHI:       while.body:
147; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
148; CHECK-PHI-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ]
149; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
150; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
151; CHECK-PHI-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
152; CHECK-PHI-NEXT:    [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1)
153; CHECK-PHI-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
154; CHECK-PHI-NEXT:    br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]]
155; CHECK-PHI:       while.end:
156; CHECK-PHI-NEXT:    ret void
157;
158; CHECK-NESTED-LABEL: @while_gt(
159; CHECK-NESTED-NEXT:  entry:
160; CHECK-NESTED-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
161; CHECK-NESTED-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
162; CHECK-NESTED:       while.body.preheader:
163; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
164; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]])
165; CHECK-NESTED-NEXT:    br label [[WHILE_BODY:%.*]]
166; CHECK-NESTED:       while.body:
167; CHECK-NESTED-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
168; CHECK-NESTED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
169; CHECK-NESTED-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
170; CHECK-NESTED-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
171; CHECK-NESTED-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
172; CHECK-NESTED-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
173; CHECK-NESTED:       while.end:
174; CHECK-NESTED-NEXT:    ret void
175;
176; CHECK-GUARD-LABEL: @while_gt(
177; CHECK-GUARD-NEXT:  entry:
178; CHECK-GUARD-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
179; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
180; CHECK-GUARD-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
181; CHECK-GUARD:       while.body.preheader:
182; CHECK-GUARD-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP0]])
183; CHECK-GUARD-NEXT:    br label [[WHILE_BODY:%.*]]
184; CHECK-GUARD:       while.body:
185; CHECK-GUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
186; CHECK-GUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
187; CHECK-GUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
188; CHECK-GUARD-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
189; CHECK-GUARD-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
190; CHECK-GUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
191; CHECK-GUARD:       while.end:
192; CHECK-GUARD-NEXT:    ret void
193;
194; CHECK-PHIGUARD-LABEL: @while_gt(
195; CHECK-PHIGUARD-NEXT:  entry:
196; CHECK-PHIGUARD-NEXT:    [[CMP4:%.*]] = icmp sgt i32 [[I:%.*]], [[N:%.*]]
197; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = sub i32 [[I]], [[N]]
198; CHECK-PHIGUARD-NEXT:    br i1 [[CMP4]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
199; CHECK-PHIGUARD:       while.body.preheader:
200; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP0]])
201; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY:%.*]]
202; CHECK-PHIGUARD:       while.body:
203; CHECK-PHIGUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
204; CHECK-PHIGUARD-NEXT:    [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP3:%.*]], [[WHILE_BODY]] ]
205; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
206; CHECK-PHIGUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
207; CHECK-PHIGUARD-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
208; CHECK-PHIGUARD-NEXT:    [[TMP3]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP2]], i32 1)
209; CHECK-PHIGUARD-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
210; CHECK-PHIGUARD-NEXT:    br i1 [[TMP4]], label [[WHILE_BODY]], label [[WHILE_END]]
211; CHECK-PHIGUARD:       while.end:
212; CHECK-PHIGUARD-NEXT:    ret void
213;
214entry:
215  %cmp4 = icmp sgt i32 %i, %N
216  br i1 %cmp4, label %while.body, label %while.end
217
218while.body:
219  %i.addr.05 = phi i32 [ %dec, %while.body ], [ %i, %entry ]
220  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
221  store i32 %i.addr.05, ptr %arrayidx, align 4
222  %dec = add nsw i32 %i.addr.05, -1
223  %cmp = icmp sgt i32 %dec, %N
224  br i1 %cmp, label %while.body, label %while.end
225
226while.end:
227  ret void
228}
229
230define void @while_gte(i32 %i, i32 %N, ptr nocapture %A) {
231; CHECK-DEC-LABEL: @while_gte(
232; CHECK-DEC-NEXT:  entry:
233; CHECK-DEC-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
234; CHECK-DEC-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
235; CHECK-DEC:       while.body.preheader:
236; CHECK-DEC-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
237; CHECK-DEC-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
238; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP1]])
239; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
240; CHECK-DEC:       while.body:
241; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
242; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
243; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
244; CHECK-DEC-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
245; CHECK-DEC-NEXT:    [[TMP2:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
246; CHECK-DEC-NEXT:    br i1 [[TMP2]], label [[WHILE_BODY]], label [[WHILE_END]]
247; CHECK-DEC:       while.end:
248; CHECK-DEC-NEXT:    ret void
249;
250; CHECK-PHI-LABEL: @while_gte(
251; CHECK-PHI-NEXT:  entry:
252; CHECK-PHI-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
253; CHECK-PHI-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
254; CHECK-PHI:       while.body.preheader:
255; CHECK-PHI-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
256; CHECK-PHI-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
257; CHECK-PHI-NEXT:    [[TMP2:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP1]])
258; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
259; CHECK-PHI:       while.body:
260; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
261; CHECK-PHI-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ]
262; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
263; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
264; CHECK-PHI-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
265; CHECK-PHI-NEXT:    [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1)
266; CHECK-PHI-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0
267; CHECK-PHI-NEXT:    br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]]
268; CHECK-PHI:       while.end:
269; CHECK-PHI-NEXT:    ret void
270;
271; CHECK-NESTED-LABEL: @while_gte(
272; CHECK-NESTED-NEXT:  entry:
273; CHECK-NESTED-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
274; CHECK-NESTED-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
275; CHECK-NESTED:       while.body.preheader:
276; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
277; CHECK-NESTED-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
278; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP1]])
279; CHECK-NESTED-NEXT:    br label [[WHILE_BODY:%.*]]
280; CHECK-NESTED:       while.body:
281; CHECK-NESTED-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
282; CHECK-NESTED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
283; CHECK-NESTED-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
284; CHECK-NESTED-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
285; CHECK-NESTED-NEXT:    [[TMP2:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
286; CHECK-NESTED-NEXT:    br i1 [[TMP2]], label [[WHILE_BODY]], label [[WHILE_END]]
287; CHECK-NESTED:       while.end:
288; CHECK-NESTED-NEXT:    ret void
289;
290; CHECK-GUARD-LABEL: @while_gte(
291; CHECK-GUARD-NEXT:  entry:
292; CHECK-GUARD-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
293; CHECK-GUARD-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
294; CHECK-GUARD:       while.body.preheader:
295; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
296; CHECK-GUARD-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
297; CHECK-GUARD-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[TMP1]])
298; CHECK-GUARD-NEXT:    br label [[WHILE_BODY:%.*]]
299; CHECK-GUARD:       while.body:
300; CHECK-GUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
301; CHECK-GUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
302; CHECK-GUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
303; CHECK-GUARD-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
304; CHECK-GUARD-NEXT:    [[TMP2:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
305; CHECK-GUARD-NEXT:    br i1 [[TMP2]], label [[WHILE_BODY]], label [[WHILE_END]]
306; CHECK-GUARD:       while.end:
307; CHECK-GUARD-NEXT:    ret void
308;
309; CHECK-PHIGUARD-LABEL: @while_gte(
310; CHECK-PHIGUARD-NEXT:  entry:
311; CHECK-PHIGUARD-NEXT:    [[CMP4:%.*]] = icmp slt i32 [[I:%.*]], [[N:%.*]]
312; CHECK-PHIGUARD-NEXT:    br i1 [[CMP4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
313; CHECK-PHIGUARD:       while.body.preheader:
314; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = add i32 [[I]], 1
315; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = sub i32 [[TMP0]], [[N]]
316; CHECK-PHIGUARD-NEXT:    [[TMP2:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[TMP1]])
317; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY:%.*]]
318; CHECK-PHIGUARD:       while.body:
319; CHECK-PHIGUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[DEC:%.*]], [[WHILE_BODY]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
320; CHECK-PHIGUARD-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ]
321; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
322; CHECK-PHIGUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
323; CHECK-PHIGUARD-NEXT:    [[DEC]] = add nsw i32 [[I_ADDR_05]], -1
324; CHECK-PHIGUARD-NEXT:    [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1)
325; CHECK-PHIGUARD-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0
326; CHECK-PHIGUARD-NEXT:    br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]]
327; CHECK-PHIGUARD:       while.end:
328; CHECK-PHIGUARD-NEXT:    ret void
329;
330entry:
331  %cmp4 = icmp slt i32 %i, %N
332  br i1 %cmp4, label %while.end, label %while.body
333
334while.body:
335  %i.addr.05 = phi i32 [ %dec, %while.body ], [ %i, %entry ]
336  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
337  store i32 %i.addr.05, ptr %arrayidx, align 4
338  %dec = add nsw i32 %i.addr.05, -1
339  %cmp = icmp sgt i32 %i.addr.05, %N
340  br i1 %cmp, label %while.body, label %while.end
341
342while.end:
343  ret void
344}
345
346define void @while_ne(i32 %N, ptr nocapture %A) {
347; CHECK-DEC-LABEL: @while_ne(
348; CHECK-DEC-NEXT:  entry:
349; CHECK-DEC-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
350; CHECK-DEC-NEXT:    br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
351; CHECK-DEC:       while.body.preheader:
352; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
353; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
354; CHECK-DEC:       while.body:
355; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
356; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
357; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
358; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
359; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
360; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
361; CHECK-DEC:       while.end:
362; CHECK-DEC-NEXT:    ret void
363;
364; CHECK-PHI-LABEL: @while_ne(
365; CHECK-PHI-NEXT:  entry:
366; CHECK-PHI-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
367; CHECK-PHI-NEXT:    br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
368; CHECK-PHI:       while.body.preheader:
369; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
370; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
371; CHECK-PHI:       while.body:
372; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
373; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ]
374; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
375; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
376; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
377; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1)
378; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
379; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]]
380; CHECK-PHI:       while.end:
381; CHECK-PHI-NEXT:    ret void
382;
383; CHECK-NESTED-LABEL: @while_ne(
384; CHECK-NESTED-NEXT:  entry:
385; CHECK-NESTED-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
386; CHECK-NESTED-NEXT:    br i1 [[CMP]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
387; CHECK-NESTED:       while.body.preheader:
388; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
389; CHECK-NESTED-NEXT:    br label [[WHILE_BODY:%.*]]
390; CHECK-NESTED:       while.body:
391; CHECK-NESTED-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
392; CHECK-NESTED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
393; CHECK-NESTED-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
394; CHECK-NESTED-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
395; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
396; CHECK-NESTED-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
397; CHECK-NESTED:       while.end:
398; CHECK-NESTED-NEXT:    ret void
399;
400; CHECK-GUARD-LABEL: @while_ne(
401; CHECK-GUARD-NEXT:  entry:
402; CHECK-GUARD-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
403; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = call i1 @llvm.test.set.loop.iterations.i32(i32 [[N]])
404; CHECK-GUARD-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
405; CHECK-GUARD:       while.body.preheader:
406; CHECK-GUARD-NEXT:    br label [[WHILE_BODY:%.*]]
407; CHECK-GUARD:       while.body:
408; CHECK-GUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
409; CHECK-GUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
410; CHECK-GUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
411; CHECK-GUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
412; CHECK-GUARD-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
413; CHECK-GUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
414; CHECK-GUARD:       while.end:
415; CHECK-GUARD-NEXT:    ret void
416;
417; CHECK-PHIGUARD-LABEL: @while_ne(
418; CHECK-PHIGUARD-NEXT:  entry:
419; CHECK-PHIGUARD-NEXT:    [[CMP:%.*]] = icmp ne i32 [[N:%.*]], 0
420; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 [[N]])
421; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
422; CHECK-PHIGUARD-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
423; CHECK-PHIGUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
424; CHECK-PHIGUARD:       while.body.preheader:
425; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY:%.*]]
426; CHECK-PHIGUARD:       while.body:
427; CHECK-PHIGUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
428; CHECK-PHIGUARD-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ]
429; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
430; CHECK-PHIGUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
431; CHECK-PHIGUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
432; CHECK-PHIGUARD-NEXT:    [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1)
433; CHECK-PHIGUARD-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0
434; CHECK-PHIGUARD-NEXT:    br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]]
435; CHECK-PHIGUARD:       while.end:
436; CHECK-PHIGUARD-NEXT:    ret void
437;
438entry:
439  %cmp = icmp ne i32 %N, 0
440  br i1 %cmp, label %while.body, label %while.end
441
442while.body:
443  %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
444  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
445  store i32 %i.addr.05, ptr %arrayidx, align 4
446  %inc = add nuw i32 %i.addr.05, 1
447  %exitcond = icmp eq i32 %inc, %N
448  br i1 %exitcond, label %while.end, label %while.body
449
450while.end:
451  ret void
452}
453
454define void @while_eq(i32 %N, ptr nocapture %A) {
455; CHECK-DEC-LABEL: @while_eq(
456; CHECK-DEC-NEXT:  entry:
457; CHECK-DEC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
458; CHECK-DEC-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
459; CHECK-DEC:       while.body.preheader:
460; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
461; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
462; CHECK-DEC:       while.body:
463; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
464; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
465; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
466; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
467; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
468; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
469; CHECK-DEC:       while.end:
470; CHECK-DEC-NEXT:    ret void
471;
472; CHECK-PHI-LABEL: @while_eq(
473; CHECK-PHI-NEXT:  entry:
474; CHECK-PHI-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
475; CHECK-PHI-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
476; CHECK-PHI:       while.body.preheader:
477; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
478; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
479; CHECK-PHI:       while.body:
480; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
481; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ]
482; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
483; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
484; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
485; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1)
486; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
487; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]]
488; CHECK-PHI:       while.end:
489; CHECK-PHI-NEXT:    ret void
490;
491; CHECK-NESTED-LABEL: @while_eq(
492; CHECK-NESTED-NEXT:  entry:
493; CHECK-NESTED-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
494; CHECK-NESTED-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
495; CHECK-NESTED:       while.body.preheader:
496; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
497; CHECK-NESTED-NEXT:    br label [[WHILE_BODY:%.*]]
498; CHECK-NESTED:       while.body:
499; CHECK-NESTED-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
500; CHECK-NESTED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
501; CHECK-NESTED-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
502; CHECK-NESTED-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
503; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
504; CHECK-NESTED-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
505; CHECK-NESTED:       while.end:
506; CHECK-NESTED-NEXT:    ret void
507;
508; CHECK-GUARD-LABEL: @while_eq(
509; CHECK-GUARD-NEXT:  entry:
510; CHECK-GUARD-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
511; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = call i1 @llvm.test.set.loop.iterations.i32(i32 [[N]])
512; CHECK-GUARD-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
513; CHECK-GUARD:       while.body.preheader:
514; CHECK-GUARD-NEXT:    br label [[WHILE_BODY:%.*]]
515; CHECK-GUARD:       while.body:
516; CHECK-GUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
517; CHECK-GUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
518; CHECK-GUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
519; CHECK-GUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
520; CHECK-GUARD-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
521; CHECK-GUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
522; CHECK-GUARD:       while.end:
523; CHECK-GUARD-NEXT:    ret void
524;
525; CHECK-PHIGUARD-LABEL: @while_eq(
526; CHECK-PHIGUARD-NEXT:  entry:
527; CHECK-PHIGUARD-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
528; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 [[N]])
529; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
530; CHECK-PHIGUARD-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
531; CHECK-PHIGUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
532; CHECK-PHIGUARD:       while.body.preheader:
533; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY:%.*]]
534; CHECK-PHIGUARD:       while.body:
535; CHECK-PHIGUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
536; CHECK-PHIGUARD-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ]
537; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
538; CHECK-PHIGUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
539; CHECK-PHIGUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
540; CHECK-PHIGUARD-NEXT:    [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1)
541; CHECK-PHIGUARD-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0
542; CHECK-PHIGUARD-NEXT:    br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]]
543; CHECK-PHIGUARD:       while.end:
544; CHECK-PHIGUARD-NEXT:    ret void
545;
546entry:
547  %cmp = icmp eq i32 %N, 0
548  br i1 %cmp, label %while.end, label %while.body
549
550while.body:
551  %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
552  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
553  store i32 %i.addr.05, ptr %arrayidx, align 4
554  %inc = add nuw i32 %i.addr.05, 1
555  %exitcond = icmp eq i32 %inc, %N
556  br i1 %exitcond, label %while.end, label %while.body
557
558while.end:
559  ret void
560}
561
562define void @while_preheader_eq(i32 %N, ptr nocapture %A) {
563; CHECK-DEC-LABEL: @while_preheader_eq(
564; CHECK-DEC-NEXT:  entry:
565; CHECK-DEC-NEXT:    br label [[PREHEADER:%.*]]
566; CHECK-DEC:       preheader:
567; CHECK-DEC-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
568; CHECK-DEC-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
569; CHECK-DEC:       while.body.preheader:
570; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
571; CHECK-DEC-NEXT:    br label [[WHILE_BODY:%.*]]
572; CHECK-DEC:       while.body:
573; CHECK-DEC-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
574; CHECK-DEC-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
575; CHECK-DEC-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
576; CHECK-DEC-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
577; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
578; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
579; CHECK-DEC:       while.end:
580; CHECK-DEC-NEXT:    ret void
581;
582; CHECK-PHI-LABEL: @while_preheader_eq(
583; CHECK-PHI-NEXT:  entry:
584; CHECK-PHI-NEXT:    br label [[PREHEADER:%.*]]
585; CHECK-PHI:       preheader:
586; CHECK-PHI-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
587; CHECK-PHI-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
588; CHECK-PHI:       while.body.preheader:
589; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
590; CHECK-PHI-NEXT:    br label [[WHILE_BODY:%.*]]
591; CHECK-PHI:       while.body:
592; CHECK-PHI-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
593; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP2:%.*]], [[WHILE_BODY]] ]
594; CHECK-PHI-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
595; CHECK-PHI-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
596; CHECK-PHI-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
597; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1)
598; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
599; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY]], label [[WHILE_END]]
600; CHECK-PHI:       while.end:
601; CHECK-PHI-NEXT:    ret void
602;
603; CHECK-NESTED-LABEL: @while_preheader_eq(
604; CHECK-NESTED-NEXT:  entry:
605; CHECK-NESTED-NEXT:    br label [[PREHEADER:%.*]]
606; CHECK-NESTED:       preheader:
607; CHECK-NESTED-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
608; CHECK-NESTED-NEXT:    br i1 [[CMP]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
609; CHECK-NESTED:       while.body.preheader:
610; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
611; CHECK-NESTED-NEXT:    br label [[WHILE_BODY:%.*]]
612; CHECK-NESTED:       while.body:
613; CHECK-NESTED-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
614; CHECK-NESTED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
615; CHECK-NESTED-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
616; CHECK-NESTED-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
617; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
618; CHECK-NESTED-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY]], label [[WHILE_END]]
619; CHECK-NESTED:       while.end:
620; CHECK-NESTED-NEXT:    ret void
621;
622; CHECK-GUARD-LABEL: @while_preheader_eq(
623; CHECK-GUARD-NEXT:  entry:
624; CHECK-GUARD-NEXT:    br label [[PREHEADER:%.*]]
625; CHECK-GUARD:       preheader:
626; CHECK-GUARD-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
627; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = call i1 @llvm.test.set.loop.iterations.i32(i32 [[N]])
628; CHECK-GUARD-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
629; CHECK-GUARD:       while.body.preheader:
630; CHECK-GUARD-NEXT:    br label [[WHILE_BODY:%.*]]
631; CHECK-GUARD:       while.body:
632; CHECK-GUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
633; CHECK-GUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
634; CHECK-GUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
635; CHECK-GUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
636; CHECK-GUARD-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
637; CHECK-GUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY]], label [[WHILE_END]]
638; CHECK-GUARD:       while.end:
639; CHECK-GUARD-NEXT:    ret void
640;
641; CHECK-PHIGUARD-LABEL: @while_preheader_eq(
642; CHECK-PHIGUARD-NEXT:  entry:
643; CHECK-PHIGUARD-NEXT:    br label [[PREHEADER:%.*]]
644; CHECK-PHIGUARD:       preheader:
645; CHECK-PHIGUARD-NEXT:    [[CMP:%.*]] = icmp eq i32 [[N:%.*]], 0
646; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = call { i32, i1 } @llvm.test.start.loop.iterations.i32(i32 [[N]])
647; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
648; CHECK-PHIGUARD-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
649; CHECK-PHIGUARD-NEXT:    br i1 [[TMP1]], label [[WHILE_BODY_PREHEADER:%.*]], label [[WHILE_END:%.*]]
650; CHECK-PHIGUARD:       while.body.preheader:
651; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY:%.*]]
652; CHECK-PHIGUARD:       while.body:
653; CHECK-PHIGUARD-NEXT:    [[I_ADDR_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
654; CHECK-PHIGUARD-NEXT:    [[TMP3:%.*]] = phi i32 [ [[TMP2]], [[WHILE_BODY_PREHEADER]] ], [ [[TMP4:%.*]], [[WHILE_BODY]] ]
655; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_ADDR_05]]
656; CHECK-PHIGUARD-NEXT:    store i32 [[I_ADDR_05]], ptr [[ARRAYIDX]], align 4
657; CHECK-PHIGUARD-NEXT:    [[INC]] = add nuw i32 [[I_ADDR_05]], 1
658; CHECK-PHIGUARD-NEXT:    [[TMP4]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP3]], i32 1)
659; CHECK-PHIGUARD-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0
660; CHECK-PHIGUARD-NEXT:    br i1 [[TMP5]], label [[WHILE_BODY]], label [[WHILE_END]]
661; CHECK-PHIGUARD:       while.end:
662; CHECK-PHIGUARD-NEXT:    ret void
663;
664entry:
665  br label %preheader
666
667preheader:
668  %cmp = icmp eq i32 %N, 0
669  br i1 %cmp, label %while.end, label %while.body
670
671while.body:
672  %i.addr.05 = phi i32 [ %inc, %while.body ], [ 0, %preheader ]
673  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.addr.05
674  store i32 %i.addr.05, ptr %arrayidx, align 4
675  %inc = add nuw i32 %i.addr.05, 1
676  %exitcond = icmp eq i32 %inc, %N
677  br i1 %exitcond, label %while.end, label %while.body
678
679while.end:
680  ret void
681}
682
683define void @nested(ptr nocapture %A, i32 %N) {
684; CHECK-DEC-LABEL: @nested(
685; CHECK-DEC-NEXT:  entry:
686; CHECK-DEC-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
687; CHECK-DEC-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]]
688; CHECK-DEC:       while.cond1.preheader.us:
689; CHECK-DEC-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ]
690; CHECK-DEC-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
691; CHECK-DEC-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
692; CHECK-DEC-NEXT:    br label [[WHILE_BODY3_US:%.*]]
693; CHECK-DEC:       while.body3.us:
694; CHECK-DEC-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
695; CHECK-DEC-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
696; CHECK-DEC-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
697; CHECK-DEC-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
698; CHECK-DEC-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
699; CHECK-DEC-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
700; CHECK-DEC-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
701; CHECK-DEC:       while.cond1.while.end_crit_edge.us:
702; CHECK-DEC-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
703; CHECK-DEC-NEXT:    [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]]
704; CHECK-DEC-NEXT:    br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]]
705; CHECK-DEC:       while.end7:
706; CHECK-DEC-NEXT:    ret void
707;
708; CHECK-PHI-LABEL: @nested(
709; CHECK-PHI-NEXT:  entry:
710; CHECK-PHI-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
711; CHECK-PHI-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]]
712; CHECK-PHI:       while.cond1.preheader.us:
713; CHECK-PHI-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ]
714; CHECK-PHI-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
715; CHECK-PHI-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
716; CHECK-PHI-NEXT:    br label [[WHILE_BODY3_US:%.*]]
717; CHECK-PHI:       while.body3.us:
718; CHECK-PHI-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
719; CHECK-PHI-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_COND1_PREHEADER_US]] ], [ [[TMP2:%.*]], [[WHILE_BODY3_US]] ]
720; CHECK-PHI-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
721; CHECK-PHI-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
722; CHECK-PHI-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
723; CHECK-PHI-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
724; CHECK-PHI-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1)
725; CHECK-PHI-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
726; CHECK-PHI-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
727; CHECK-PHI:       while.cond1.while.end_crit_edge.us:
728; CHECK-PHI-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
729; CHECK-PHI-NEXT:    [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]]
730; CHECK-PHI-NEXT:    br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]]
731; CHECK-PHI:       while.end7:
732; CHECK-PHI-NEXT:    ret void
733;
734; CHECK-NESTED-LABEL: @nested(
735; CHECK-NESTED-NEXT:  entry:
736; CHECK-NESTED-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
737; CHECK-NESTED-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US_PREHEADER:%.*]]
738; CHECK-NESTED:       while.cond1.preheader.us.preheader:
739; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
740; CHECK-NESTED-NEXT:    br label [[WHILE_COND1_PREHEADER_US:%.*]]
741; CHECK-NESTED:       while.cond1.preheader.us:
742; CHECK-NESTED-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[WHILE_COND1_PREHEADER_US_PREHEADER]] ]
743; CHECK-NESTED-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
744; CHECK-NESTED-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
745; CHECK-NESTED-NEXT:    br label [[WHILE_BODY3_US:%.*]]
746; CHECK-NESTED:       while.body3.us:
747; CHECK-NESTED-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
748; CHECK-NESTED-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
749; CHECK-NESTED-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
750; CHECK-NESTED-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
751; CHECK-NESTED-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
752; CHECK-NESTED-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
753; CHECK-NESTED-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
754; CHECK-NESTED:       while.cond1.while.end_crit_edge.us:
755; CHECK-NESTED-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
756; CHECK-NESTED-NEXT:    [[TMP1:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
757; CHECK-NESTED-NEXT:    br i1 [[TMP1]], label [[WHILE_COND1_PREHEADER_US]], label [[WHILE_END7]]
758; CHECK-NESTED:       while.end7:
759; CHECK-NESTED-NEXT:    ret void
760;
761; CHECK-GUARD-LABEL: @nested(
762; CHECK-GUARD-NEXT:  entry:
763; CHECK-GUARD-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
764; CHECK-GUARD-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]]
765; CHECK-GUARD:       while.cond1.preheader.us:
766; CHECK-GUARD-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ]
767; CHECK-GUARD-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
768; CHECK-GUARD-NEXT:    call void @llvm.set.loop.iterations.i32(i32 [[N]])
769; CHECK-GUARD-NEXT:    br label [[WHILE_BODY3_US:%.*]]
770; CHECK-GUARD:       while.body3.us:
771; CHECK-GUARD-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
772; CHECK-GUARD-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
773; CHECK-GUARD-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
774; CHECK-GUARD-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
775; CHECK-GUARD-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
776; CHECK-GUARD-NEXT:    [[TMP0:%.*]] = call i1 @llvm.loop.decrement.i32(i32 1)
777; CHECK-GUARD-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
778; CHECK-GUARD:       while.cond1.while.end_crit_edge.us:
779; CHECK-GUARD-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
780; CHECK-GUARD-NEXT:    [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]]
781; CHECK-GUARD-NEXT:    br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]]
782; CHECK-GUARD:       while.end7:
783; CHECK-GUARD-NEXT:    ret void
784;
785; CHECK-PHIGUARD-LABEL: @nested(
786; CHECK-PHIGUARD-NEXT:  entry:
787; CHECK-PHIGUARD-NEXT:    [[CMP20:%.*]] = icmp eq i32 [[N:%.*]], 0
788; CHECK-PHIGUARD-NEXT:    br i1 [[CMP20]], label [[WHILE_END7:%.*]], label [[WHILE_COND1_PREHEADER_US:%.*]]
789; CHECK-PHIGUARD:       while.cond1.preheader.us:
790; CHECK-PHIGUARD-NEXT:    [[I_021_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[WHILE_COND1_WHILE_END_CRIT_EDGE_US:%.*]] ], [ 0, [[ENTRY:%.*]] ]
791; CHECK-PHIGUARD-NEXT:    [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
792; CHECK-PHIGUARD-NEXT:    [[TMP0:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
793; CHECK-PHIGUARD-NEXT:    br label [[WHILE_BODY3_US:%.*]]
794; CHECK-PHIGUARD:       while.body3.us:
795; CHECK-PHIGUARD-NEXT:    [[J_019_US:%.*]] = phi i32 [ 0, [[WHILE_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[WHILE_BODY3_US]] ]
796; CHECK-PHIGUARD-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[WHILE_COND1_PREHEADER_US]] ], [ [[TMP2:%.*]], [[WHILE_BODY3_US]] ]
797; CHECK-PHIGUARD-NEXT:    [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
798; CHECK-PHIGUARD-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[ADD_US]]
799; CHECK-PHIGUARD-NEXT:    store i32 [[ADD_US]], ptr [[ARRAYIDX_US]], align 4
800; CHECK-PHIGUARD-NEXT:    [[INC_US]] = add nuw i32 [[J_019_US]], 1
801; CHECK-PHIGUARD-NEXT:    [[TMP2]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP1]], i32 1)
802; CHECK-PHIGUARD-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
803; CHECK-PHIGUARD-NEXT:    br i1 [[TMP3]], label [[WHILE_BODY3_US]], label [[WHILE_COND1_WHILE_END_CRIT_EDGE_US]]
804; CHECK-PHIGUARD:       while.cond1.while.end_crit_edge.us:
805; CHECK-PHIGUARD-NEXT:    [[INC6_US]] = add nuw i32 [[I_021_US]], 1
806; CHECK-PHIGUARD-NEXT:    [[EXITCOND23:%.*]] = icmp eq i32 [[INC6_US]], [[N]]
807; CHECK-PHIGUARD-NEXT:    br i1 [[EXITCOND23]], label [[WHILE_END7]], label [[WHILE_COND1_PREHEADER_US]]
808; CHECK-PHIGUARD:       while.end7:
809; CHECK-PHIGUARD-NEXT:    ret void
810;
811entry:
812  %cmp20 = icmp eq i32 %N, 0
813  br i1 %cmp20, label %while.end7, label %while.cond1.preheader.us
814
815while.cond1.preheader.us:
816  %i.021.us = phi i32 [ %inc6.us, %while.cond1.while.end_crit_edge.us ], [ 0, %entry ]
817  %mul.us = mul i32 %i.021.us, %N
818  br label %while.body3.us
819
820while.body3.us:
821  %j.019.us = phi i32 [ 0, %while.cond1.preheader.us ], [ %inc.us, %while.body3.us ]
822  %add.us = add i32 %j.019.us, %mul.us
823  %arrayidx.us = getelementptr inbounds i32, ptr %A, i32 %add.us
824  store i32 %add.us, ptr %arrayidx.us, align 4
825  %inc.us = add nuw i32 %j.019.us, 1
826  %exitcond = icmp eq i32 %inc.us, %N
827  br i1 %exitcond, label %while.cond1.while.end_crit_edge.us, label %while.body3.us
828
829while.cond1.while.end_crit_edge.us:
830  %inc6.us = add nuw i32 %i.021.us, 1
831  %exitcond23 = icmp eq i32 %inc6.us, %N
832  br i1 %exitcond23, label %while.end7, label %while.cond1.preheader.us
833
834while.end7:
835  ret void
836}
837