1; RUN: opt -loop-idiom -mtriple=x86_64 -mcpu=core-avx2 < %s -S | FileCheck -check-prefix=LZCNT --check-prefix=ALL %s
2; RUN: opt -loop-idiom -mtriple=x86_64 -mcpu=corei7 < %s -S | FileCheck -check-prefix=NOLZCNT --check-prefix=ALL %s
3
4; Recognize CTLZ builtin pattern.
5; Here we'll just convert loop to countable,
6; so do not insert builtin if CPU do not support CTLZ
7;
8; int ctlz_and_other(int n, char *a)
9; {
10;   n = n >= 0 ? n : -n;
11;   int i = 0, n0 = n;
12;   while(n >>= 1) {
13;     a[i] = (n0 & (1 << i)) ? 1 : 0;
14;     i++;
15;   }
16;   return i;
17; }
18;
19; LZCNT:  entry
20; LZCNT:  %0 = call i32 @llvm.ctlz.i32(i32 %shr8, i1 true)
21; LZCNT-NEXT:  %1 = sub i32 32, %0
22; LZCNT-NEXT:  %2 = zext i32 %1 to i64
23; LZCNT:  %indvars.iv.next.lcssa = phi i64 [ %2, %while.body ]
24; LZCNT:  %4 = trunc i64 %indvars.iv.next.lcssa to i32
25; LZCNT:  %i.0.lcssa = phi i32 [ 0, %entry ], [ %4, %while.end.loopexit ]
26; LZCNT:  ret i32 %i.0.lcssa
27
28; NOLZCNT:  entry
29; NOLZCNT-NOT:  @llvm.ctlz
30
31; Function Attrs: norecurse nounwind uwtable
32define i32 @ctlz_and_other(i32 %n, i8* nocapture %a) {
33entry:
34  %c = icmp sgt i32 %n, 0
35  %negn = sub nsw i32 0, %n
36  %abs_n = select i1 %c, i32 %n, i32 %negn
37  %shr8 = lshr i32 %abs_n, 1
38  %tobool9 = icmp eq i32 %shr8, 0
39  br i1 %tobool9, label %while.end, label %while.body.preheader
40
41while.body.preheader:                             ; preds = %entry
42  br label %while.body
43
44while.body:                                       ; preds = %while.body.preheader, %while.body
45  %indvars.iv = phi i64 [ %indvars.iv.next, %while.body ], [ 0, %while.body.preheader ]
46  %shr11 = phi i32 [ %shr, %while.body ], [ %shr8, %while.body.preheader ]
47  %0 = trunc i64 %indvars.iv to i32
48  %shl = shl i32 1, %0
49  %and = and i32 %shl, %abs_n
50  %tobool1 = icmp ne i32 %and, 0
51  %conv = zext i1 %tobool1 to i8
52  %arrayidx = getelementptr inbounds i8, i8* %a, i64 %indvars.iv
53  store i8 %conv, i8* %arrayidx, align 1
54  %indvars.iv.next = add nuw i64 %indvars.iv, 1
55  %shr = ashr i32 %shr11, 1
56  %tobool = icmp eq i32 %shr, 0
57  br i1 %tobool, label %while.end.loopexit, label %while.body
58
59while.end.loopexit:                               ; preds = %while.body
60  %1 = trunc i64 %indvars.iv.next to i32
61  br label %while.end
62
63while.end:                                        ; preds = %while.end.loopexit, %entry
64  %i.0.lcssa = phi i32 [ 0, %entry ], [ %1, %while.end.loopexit ]
65  ret i32 %i.0.lcssa
66}
67
68; Recognize CTLZ builtin pattern.
69; Here it will replace the loop -
70; assume builtin is always profitable.
71;
72; int ctlz_zero_check(int n)
73; {
74;   n = n >= 0 ? n : -n;
75;   int i = 0;
76;   while(n) {
77;     n >>= 1;
78;     i++;
79;   }
80;   return i;
81; }
82;
83; ALL:  entry
84; ALL:  %0 = call i32 @llvm.ctlz.i32(i32 %abs_n, i1 true)
85; ALL-NEXT:  %1 = sub i32 32, %0
86; ALL:  %inc.lcssa = phi i32 [ %1, %while.body ]
87; ALL:  %i.0.lcssa = phi i32 [ 0, %entry ], [ %inc.lcssa, %while.end.loopexit ]
88; ALL:  ret i32 %i.0.lcssa
89
90; Function Attrs: norecurse nounwind readnone uwtable
91define i32 @ctlz_zero_check(i32 %n) {
92entry:
93  %c = icmp sgt i32 %n, 0
94  %negn = sub nsw i32 0, %n
95  %abs_n = select i1 %c, i32 %n, i32 %negn
96  %tobool4 = icmp eq i32 %abs_n, 0
97  br i1 %tobool4, label %while.end, label %while.body.preheader
98
99while.body.preheader:                             ; preds = %entry
100  br label %while.body
101
102while.body:                                       ; preds = %while.body.preheader, %while.body
103  %i.06 = phi i32 [ %inc, %while.body ], [ 0, %while.body.preheader ]
104  %n.addr.05 = phi i32 [ %shr, %while.body ], [ %abs_n, %while.body.preheader ]
105  %shr = ashr i32 %n.addr.05, 1
106  %inc = add nsw i32 %i.06, 1
107  %tobool = icmp eq i32 %shr, 0
108  br i1 %tobool, label %while.end.loopexit, label %while.body
109
110while.end.loopexit:                               ; preds = %while.body
111  br label %while.end
112
113while.end:                                        ; preds = %while.end.loopexit, %entry
114  %i.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.end.loopexit ]
115  ret i32 %i.0.lcssa
116}
117
118; Recognize CTLZ builtin pattern.
119; Here it will replace the loop -
120; assume builtin is always profitable.
121;
122; int ctlz_zero_check_lshr(int n)
123; {
124;   int i = 0;
125;   while(n) {
126;     n >>= 1;
127;     i++;
128;   }
129;   return i;
130; }
131;
132; ALL:  entry
133; ALL:  %0 = call i32 @llvm.ctlz.i32(i32 %n, i1 true)
134; ALL-NEXT:  %1 = sub i32 32, %0
135; ALL:  %inc.lcssa = phi i32 [ %1, %while.body ]
136; ALL:  %i.0.lcssa = phi i32 [ 0, %entry ], [ %inc.lcssa, %while.end.loopexit ]
137; ALL:  ret i32 %i.0.lcssa
138
139; Function Attrs: norecurse nounwind readnone uwtable
140define i32 @ctlz_zero_check_lshr(i32 %n) {
141entry:
142  %tobool4 = icmp eq i32 %n, 0
143  br i1 %tobool4, label %while.end, label %while.body.preheader
144
145while.body.preheader:                             ; preds = %entry
146  br label %while.body
147
148while.body:                                       ; preds = %while.body.preheader, %while.body
149  %i.06 = phi i32 [ %inc, %while.body ], [ 0, %while.body.preheader ]
150  %n.addr.05 = phi i32 [ %shr, %while.body ], [ %n, %while.body.preheader ]
151  %shr = lshr i32 %n.addr.05, 1
152  %inc = add nsw i32 %i.06, 1
153  %tobool = icmp eq i32 %shr, 0
154  br i1 %tobool, label %while.end.loopexit, label %while.body
155
156while.end.loopexit:                               ; preds = %while.body
157  br label %while.end
158
159while.end:                                        ; preds = %while.end.loopexit, %entry
160  %i.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.end.loopexit ]
161  ret i32 %i.0.lcssa
162}
163
164; Recognize CTLZ builtin pattern.
165; Here it will replace the loop -
166; assume builtin is always profitable.
167;
168; int ctlz(int n)
169; {
170;   n = n >= 0 ? n : -n;
171;   int i = 0;
172;   while(n >>= 1) {
173;     i++;
174;   }
175;   return i;
176; }
177;
178; ALL:  entry
179; ALL:  %0 = ashr i32 %abs_n, 1
180; ALL-NEXT:  %1 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
181; ALL-NEXT:  %2 = sub i32 32, %1
182; ALL-NEXT:  %3 = add i32 %2, 1
183; ALL:  %i.0.lcssa = phi i32 [ %2, %while.cond ]
184; ALL:  ret i32 %i.0.lcssa
185
186; Function Attrs: norecurse nounwind readnone uwtable
187define i32 @ctlz(i32 %n) {
188entry:
189  %c = icmp sgt i32 %n, 0
190  %negn = sub nsw i32 0, %n
191  %abs_n = select i1 %c, i32 %n, i32 %negn
192  br label %while.cond
193
194while.cond:                                       ; preds = %while.cond, %entry
195  %n.addr.0 = phi i32 [ %abs_n, %entry ], [ %shr, %while.cond ]
196  %i.0 = phi i32 [ 0, %entry ], [ %inc, %while.cond ]
197  %shr = ashr i32 %n.addr.0, 1
198  %tobool = icmp eq i32 %shr, 0
199  %inc = add nsw i32 %i.0, 1
200  br i1 %tobool, label %while.end, label %while.cond
201
202while.end:                                        ; preds = %while.cond
203  ret i32 %i.0
204}
205
206; Recognize CTLZ builtin pattern.
207; Here it will replace the loop -
208; assume builtin is always profitable.
209;
210; int ctlz_lshr(int n)
211; {
212;   int i = 0;
213;   while(n >>= 1) {
214;     i++;
215;   }
216;   return i;
217; }
218;
219; ALL:  entry
220; ALL:  %0 = lshr i32 %n, 1
221; ALL-NEXT:  %1 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
222; ALL-NEXT:  %2 = sub i32 32, %1
223; ALL-NEXT:  %3 = add i32 %2, 1
224; ALL:  %i.0.lcssa = phi i32 [ %2, %while.cond ]
225; ALL:  ret i32 %i.0.lcssa
226
227; Function Attrs: norecurse nounwind readnone uwtable
228define i32 @ctlz_lshr(i32 %n) {
229entry:
230  br label %while.cond
231
232while.cond:                                       ; preds = %while.cond, %entry
233  %n.addr.0 = phi i32 [ %n, %entry ], [ %shr, %while.cond ]
234  %i.0 = phi i32 [ 0, %entry ], [ %inc, %while.cond ]
235  %shr = lshr i32 %n.addr.0, 1
236  %tobool = icmp eq i32 %shr, 0
237  %inc = add nsw i32 %i.0, 1
238  br i1 %tobool, label %while.end, label %while.cond
239
240while.end:                                        ; preds = %while.cond
241  ret i32 %i.0
242}
243
244; Recognize CTLZ builtin pattern.
245; Here it will replace the loop -
246; assume builtin is always profitable.
247;
248; int ctlz_add(int n, int i0)
249; {
250;   n = n >= 0 ? n : -n;
251;   int i = i0;
252;   while(n >>= 1) {
253;     i++;
254;   }
255;   return i;
256; }
257;
258; ALL:  entry
259; ALL:  %0 = ashr i32 %abs_n, 1
260; ALL-NEXT:  %1 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
261; ALL-NEXT:  %2 = sub i32 32, %1
262; ALL-NEXT:  %3 = add i32 %2, 1
263; ALL-NEXT:  %4 = add i32 %2, %i0
264; ALL:  %i.0.lcssa = phi i32 [ %4, %while.cond ]
265; ALL:  ret i32 %i.0.lcssa
266;
267; Function Attrs: norecurse nounwind readnone uwtable
268define i32 @ctlz_add(i32 %n, i32 %i0) {
269entry:
270  %c = icmp sgt i32 %n, 0
271  %negn = sub nsw i32 0, %n
272  %abs_n = select i1 %c, i32 %n, i32 %negn
273  br label %while.cond
274
275while.cond:                                       ; preds = %while.cond, %entry
276  %n.addr.0 = phi i32 [ %abs_n, %entry ], [ %shr, %while.cond ]
277  %i.0 = phi i32 [ %i0, %entry ], [ %inc, %while.cond ]
278  %shr = ashr i32 %n.addr.0, 1
279  %tobool = icmp eq i32 %shr, 0
280  %inc = add nsw i32 %i.0, 1
281  br i1 %tobool, label %while.end, label %while.cond
282
283while.end:                                        ; preds = %while.cond
284  ret i32 %i.0
285}
286
287; Recognize CTLZ builtin pattern.
288; Here it will replace the loop -
289; assume builtin is always profitable.
290;
291; int ctlz_add_lshr(int n, int i0)
292; {
293;   int i = i0;
294;   while(n >>= 1) {
295;     i++;
296;   }
297;   return i;
298; }
299;
300; ALL:  entry
301; ALL:  %0 = lshr i32 %n, 1
302; ALL-NEXT:  %1 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
303; ALL-NEXT:  %2 = sub i32 32, %1
304; ALL-NEXT:  %3 = add i32 %2, 1
305; ALL-NEXT:  %4 = add i32 %2, %i0
306; ALL:  %i.0.lcssa = phi i32 [ %4, %while.cond ]
307; ALL:  ret i32 %i.0.lcssa
308;
309; Function Attrs: norecurse nounwind readnone uwtable
310define i32 @ctlz_add_lshr(i32 %n, i32 %i0) {
311entry:
312  br label %while.cond
313
314while.cond:                                       ; preds = %while.cond, %entry
315  %n.addr.0 = phi i32 [ %n, %entry ], [ %shr, %while.cond ]
316  %i.0 = phi i32 [ %i0, %entry ], [ %inc, %while.cond ]
317  %shr = lshr i32 %n.addr.0, 1
318  %tobool = icmp eq i32 %shr, 0
319  %inc = add nsw i32 %i.0, 1
320  br i1 %tobool, label %while.end, label %while.cond
321
322while.end:                                        ; preds = %while.cond
323  ret i32 %i.0
324}
325
326; Recognize CTLZ builtin pattern.
327; Here it will replace the loop -
328; assume builtin is always profitable.
329;
330; int ctlz_sext(short in)
331; {
332;   int n = in;
333;   if (in < 0)
334;     n = -n;
335;   int i = 0;
336;   while(n >>= 1) {
337;     i++;
338;   }
339;   return i;
340; }
341;
342; ALL:  entry
343; ALL:  %0 = ashr i32 %abs_n, 1
344; ALL-NEXT:  %1 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
345; ALL-NEXT:  %2 = sub i32 32, %1
346; ALL-NEXT:  %3 = add i32 %2, 1
347; ALL:  %i.0.lcssa = phi i32 [ %2, %while.cond ]
348; ALL:  ret i32 %i.0.lcssa
349
350; Function Attrs: norecurse nounwind readnone uwtable
351define i32 @ctlz_sext(i16 %in) {
352entry:
353  %n = sext i16 %in to i32
354  %c = icmp sgt i16 %in, 0
355  %negn = sub nsw i32 0, %n
356  %abs_n = select i1 %c, i32 %n, i32 %negn
357  br label %while.cond
358
359while.cond:                                       ; preds = %while.cond, %entry
360  %n.addr.0 = phi i32 [ %abs_n, %entry ], [ %shr, %while.cond ]
361  %i.0 = phi i32 [ 0, %entry ], [ %inc, %while.cond ]
362  %shr = ashr i32 %n.addr.0, 1
363  %tobool = icmp eq i32 %shr, 0
364  %inc = add nsw i32 %i.0, 1
365  br i1 %tobool, label %while.end, label %while.cond
366
367while.end:                                        ; preds = %while.cond
368  ret i32 %i.0
369}
370
371; Recognize CTLZ builtin pattern.
372; Here it will replace the loop -
373; assume builtin is always profitable.
374;
375; int ctlz_sext_lshr(short in)
376; {
377;   int i = 0;
378;   while(in >>= 1) {
379;     i++;
380;   }
381;   return i;
382; }
383;
384; ALL:  entry
385; ALL:  %0 = lshr i32 %n, 1
386; ALL-NEXT:  %1 = call i32 @llvm.ctlz.i32(i32 %0, i1 false)
387; ALL-NEXT:  %2 = sub i32 32, %1
388; ALL-NEXT:  %3 = add i32 %2, 1
389; ALL:  %i.0.lcssa = phi i32 [ %2, %while.cond ]
390; ALL:  ret i32 %i.0.lcssa
391
392; Function Attrs: norecurse nounwind readnone uwtable
393define i32 @ctlz_sext_lshr(i16 %in) {
394entry:
395  %n = sext i16 %in to i32
396  br label %while.cond
397
398while.cond:                                       ; preds = %while.cond, %entry
399  %n.addr.0 = phi i32 [ %n, %entry ], [ %shr, %while.cond ]
400  %i.0 = phi i32 [ 0, %entry ], [ %inc, %while.cond ]
401  %shr = lshr i32 %n.addr.0, 1
402  %tobool = icmp eq i32 %shr, 0
403  %inc = add nsw i32 %i.0, 1
404  br i1 %tobool, label %while.end, label %while.cond
405
406while.end:                                        ; preds = %while.cond
407  ret i32 %i.0
408}
409
410; This loop contains a volatile store. If x is initially negative,
411; the code will be an infinite loop because the ashr will eventually produce
412; all ones and continue doing so. This prevents the loop from terminating. If
413; we convert this to a countable loop using ctlz that loop will only run 32
414; times. This is different than the infinite number of times of the original.
415define i32 @foo(i32 %x) {
416; LZCNT-LABEL: @foo(
417; LZCNT-NEXT:  entry:
418; LZCNT-NEXT:    [[V:%.*]] = alloca i8, align 1
419; LZCNT-NEXT:    [[TOBOOL4:%.*]] = icmp eq i32 [[X:%.*]], 0
420; LZCNT-NEXT:    br i1 [[TOBOOL4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_LR_PH:%.*]]
421; LZCNT:       while.body.lr.ph:
422; LZCNT-NEXT:    br label [[WHILE_BODY:%.*]]
423; LZCNT:       while.body:
424; LZCNT-NEXT:    [[CNT_06:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[WHILE_BODY]] ]
425; LZCNT-NEXT:    [[X_ADDR_05:%.*]] = phi i32 [ [[X]], [[WHILE_BODY_LR_PH]] ], [ [[SHR:%.*]], [[WHILE_BODY]] ]
426; LZCNT-NEXT:    [[SHR]] = ashr i32 [[X_ADDR_05]], 1
427; LZCNT-NEXT:    [[INC]] = add i32 [[CNT_06]], 1
428; LZCNT-NEXT:    store volatile i8 42, i8* [[V]], align 1
429; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHR]], 0
430; LZCNT-NEXT:    br i1 [[TOBOOL]], label [[WHILE_COND_WHILE_END_CRIT_EDGE:%.*]], label [[WHILE_BODY]]
431; LZCNT:       while.cond.while.end_crit_edge:
432; LZCNT-NEXT:    [[SPLIT:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
433; LZCNT-NEXT:    br label [[WHILE_END]]
434; LZCNT:       while.end:
435; LZCNT-NEXT:    [[CNT_0_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[WHILE_COND_WHILE_END_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]
436; LZCNT-NEXT:    ret i32 [[CNT_0_LCSSA]]
437;
438; NOLZCNT-LABEL: @foo(
439; NOLZCNT-NEXT:  entry:
440; NOLZCNT-NEXT:    [[V:%.*]] = alloca i8, align 1
441; NOLZCNT-NEXT:    [[TOBOOL4:%.*]] = icmp eq i32 [[X:%.*]], 0
442; NOLZCNT-NEXT:    br i1 [[TOBOOL4]], label [[WHILE_END:%.*]], label [[WHILE_BODY_LR_PH:%.*]]
443; NOLZCNT:       while.body.lr.ph:
444; NOLZCNT-NEXT:    br label [[WHILE_BODY:%.*]]
445; NOLZCNT:       while.body:
446; NOLZCNT-NEXT:    [[CNT_06:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[WHILE_BODY]] ]
447; NOLZCNT-NEXT:    [[X_ADDR_05:%.*]] = phi i32 [ [[X]], [[WHILE_BODY_LR_PH]] ], [ [[SHR:%.*]], [[WHILE_BODY]] ]
448; NOLZCNT-NEXT:    [[SHR]] = ashr i32 [[X_ADDR_05]], 1
449; NOLZCNT-NEXT:    [[INC]] = add i32 [[CNT_06]], 1
450; NOLZCNT-NEXT:    store volatile i8 42, i8* [[V]], align 1
451; NOLZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHR]], 0
452; NOLZCNT-NEXT:    br i1 [[TOBOOL]], label [[WHILE_COND_WHILE_END_CRIT_EDGE:%.*]], label [[WHILE_BODY]]
453; NOLZCNT:       while.cond.while.end_crit_edge:
454; NOLZCNT-NEXT:    [[SPLIT:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
455; NOLZCNT-NEXT:    br label [[WHILE_END]]
456; NOLZCNT:       while.end:
457; NOLZCNT-NEXT:    [[CNT_0_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[WHILE_COND_WHILE_END_CRIT_EDGE]] ], [ 0, [[ENTRY:%.*]] ]
458; NOLZCNT-NEXT:    ret i32 [[CNT_0_LCSSA]]
459;
460entry:
461  %v = alloca i8, align 1
462  %tobool4 = icmp eq i32 %x, 0
463  br i1 %tobool4, label %while.end, label %while.body.lr.ph
464
465while.body.lr.ph:                                 ; preds = %entry
466  br label %while.body
467
468while.body:                                       ; preds = %while.body.lr.ph, %while.body
469  %cnt.06 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %while.body ]
470  %x.addr.05 = phi i32 [ %x, %while.body.lr.ph ], [ %shr, %while.body ]
471  %shr = ashr i32 %x.addr.05, 1
472  %inc = add i32 %cnt.06, 1
473  store volatile i8 42, i8* %v, align 1
474  %tobool = icmp eq i32 %shr, 0
475  br i1 %tobool, label %while.cond.while.end_crit_edge, label %while.body
476
477while.cond.while.end_crit_edge:                   ; preds = %while.body
478  %split = phi i32 [ %inc, %while.body ]
479  br label %while.end
480
481while.end:                                        ; preds = %while.cond.while.end_crit_edge, %entry
482  %cnt.0.lcssa = phi i32 [ %split, %while.cond.while.end_crit_edge ], [ 0, %entry ]
483  ret i32 %cnt.0.lcssa
484}
485
486; We can't easily transform this loop. It returns 1 for an input of both
487; 0 and 1.
488;
489; int ctlz_bad(unsigned n)
490; {
491;   int i = 0;
492;   do {
493;     i++;
494;     n >>= 1;
495;   } while(n != 0) {
496;   return i;
497; }
498;
499; Function Attrs: norecurse nounwind readnone uwtable
500define i32 @ctlz_bad(i32 %n) {
501; ALL-LABEL: @ctlz_bad(
502; ALL-NEXT:  entry:
503; ALL-NEXT:    br label [[WHILE_COND:%.*]]
504; ALL:       while.cond:
505; ALL-NEXT:    [[N_ADDR_0:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[SHR:%.*]], [[WHILE_COND]] ]
506; ALL-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[WHILE_COND]] ]
507; ALL-NEXT:    [[SHR]] = lshr i32 [[N_ADDR_0]], 1
508; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHR]], 0
509; ALL-NEXT:    [[INC]] = add nsw i32 [[I_0]], 1
510; ALL-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_COND]]
511; ALL:       while.end:
512; ALL-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_COND]] ]
513; ALL-NEXT:    ret i32 [[INC_LCSSA]]
514;
515entry:
516  br label %while.cond
517
518while.cond:                                       ; preds = %while.cond, %entry
519  %n.addr.0 = phi i32 [ %n, %entry ], [ %shr, %while.cond ]
520  %i.0 = phi i32 [ 0, %entry ], [ %inc, %while.cond ]
521  %shr = lshr i32 %n.addr.0, 1
522  %tobool = icmp eq i32 %shr, 0
523  %inc = add nsw i32 %i.0, 1
524  br i1 %tobool, label %while.end, label %while.cond
525
526while.end:                                        ; preds = %while.cond
527  ret i32 %inc
528}
529