xref: /llvm-project/llvm/test/Transforms/LoopIdiom/X86/logical-right-shift-until-zero.ll (revision 48c6b2729e2111bec08799c65b8b459e12413546)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mcpu=corei7 < %s -S | FileCheck %s --check-prefixes=CHECK,NOLZCNT
3; RUN: opt -passes=loop-idiom -mtriple=x86_64 -mcpu=core-avx2 < %s -S | FileCheck %s --check-prefixes=CHECK,LZCNT
4
5declare void @escape_inner(i8, i8, i8, i1, i8)
6declare void @escape_outer(i8, i8, i8, i1, i8)
7
8declare i8 @gen.i8()
9
10; Most basic pattern; Note that iff the shift amount is offset, said offsetting
11; must not cause an overflow, but `add nsw` is fine.
12define i8 @p0(i8 %val, i8 %start, i8 %extraoffset) {
13; NOLZCNT-LABEL: @p0(
14; NOLZCNT-NEXT:  entry:
15; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
16; NOLZCNT:       loop:
17; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
18; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
19; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
20; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
21; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
22; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
23; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
24; NOLZCNT:       end:
25; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
26; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
27; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
28; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
29; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
30; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
31; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
32;
33; LZCNT-LABEL: @p0(
34; LZCNT-NEXT:  entry:
35; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
36; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
37; LZCNT-NEXT:    [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]
38; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]
39; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
40; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]
41; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
42; LZCNT-NEXT:    br label [[LOOP:%.*]]
43; LZCNT:       loop:
44; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
45; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
46; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
47; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
48; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]
49; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
50; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
51; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])
52; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
53; LZCNT:       end:
54; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
55; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
56; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
57; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
58; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
59; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
60; LZCNT-NEXT:    ret i8 [[IV_RES]]
61;
62entry:
63  br label %loop
64
65loop:
66  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
67  %nbits = add nsw i8 %iv, %extraoffset
68  %val.shifted = lshr i8 %val, %nbits
69  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
70  %iv.next = add i8 %iv, 1
71
72  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
73
74  br i1 %val.shifted.iszero, label %end, label %loop
75
76end:
77  %iv.res = phi i8 [ %iv, %loop ]
78  %nbits.res = phi i8 [ %nbits, %loop ]
79  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
80  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
81  %iv.next.res = phi i8 [ %iv.next, %loop ]
82
83  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
84
85  ret i8 %iv.res
86}
87
88; `add nuw` is also fine.
89define i8 @p1(i8 %val, i8 %start, i8 %extraoffset) {
90; NOLZCNT-LABEL: @p1(
91; NOLZCNT-NEXT:  entry:
92; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
93; NOLZCNT:       loop:
94; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
95; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nuw i8 [[IV]], [[EXTRAOFFSET:%.*]]
96; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
97; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
98; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
99; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
100; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
101; NOLZCNT:       end:
102; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
103; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
104; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
105; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
106; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
107; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
108; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
109;
110; LZCNT-LABEL: @p1(
111; LZCNT-NEXT:  entry:
112; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
113; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
114; LZCNT-NEXT:    [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]
115; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]
116; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
117; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]
118; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
119; LZCNT-NEXT:    br label [[LOOP:%.*]]
120; LZCNT:       loop:
121; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
122; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
123; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
124; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
125; LZCNT-NEXT:    [[NBITS:%.*]] = add nuw i8 [[IV]], [[EXTRAOFFSET]]
126; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
127; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
128; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])
129; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
130; LZCNT:       end:
131; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
132; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
133; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
134; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
135; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
136; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
137; LZCNT-NEXT:    ret i8 [[IV_RES]]
138;
139entry:
140  br label %loop
141
142loop:
143  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
144  %nbits = add nuw i8 %iv, %extraoffset
145  %val.shifted = lshr i8 %val, %nbits
146  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
147  %iv.next = add i8 %iv, 1
148
149  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
150
151  br i1 %val.shifted.iszero, label %end, label %loop
152
153end:
154  %iv.res = phi i8 [ %iv, %loop ]
155  %nbits.res = phi i8 [ %nbits, %loop ]
156  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
157  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
158  %iv.next.res = phi i8 [ %iv.next, %loop ]
159
160  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
161
162  ret i8 %iv.res
163}
164
165; `sub nsw` is also fine.
166define i8 @p2(i8 %val, i8 %start, i8 %extraoffset) {
167; NOLZCNT-LABEL: @p2(
168; NOLZCNT-NEXT:  entry:
169; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
170; NOLZCNT:       loop:
171; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
172; NOLZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
173; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
174; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
175; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
176; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
177; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
178; NOLZCNT:       end:
179; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
180; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
181; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
182; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
183; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
184; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
185; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
186;
187; LZCNT-LABEL: @p2(
188; LZCNT-NEXT:  entry:
189; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
190; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
191; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]
192; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
193; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]
194; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
195; LZCNT-NEXT:    br label [[LOOP:%.*]]
196; LZCNT:       loop:
197; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
198; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
199; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
200; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
201; LZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i8 [[IV]], [[EXTRAOFFSET]]
202; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
203; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
204; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])
205; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
206; LZCNT:       end:
207; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
208; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
209; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
210; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
211; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
212; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
213; LZCNT-NEXT:    ret i8 [[IV_RES]]
214;
215entry:
216  br label %loop
217
218loop:
219  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
220  %nbits = sub nsw i8 %iv, %extraoffset
221  %val.shifted = lshr i8 %val, %nbits
222  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
223  %iv.next = add i8 %iv, 1
224
225  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
226
227  br i1 %val.shifted.iszero, label %end, label %loop
228
229end:
230  %iv.res = phi i8 [ %iv, %loop ]
231  %nbits.res = phi i8 [ %nbits, %loop ]
232  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
233  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
234  %iv.next.res = phi i8 [ %iv.next, %loop ]
235
236  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
237
238  ret i8 %iv.res
239}
240
241; But `sub nuw` is not fine..
242define i8 @n3(i8 %val, i8 %start, i8 %extraoffset) {
243; CHECK-LABEL: @n3(
244; CHECK-NEXT:  entry:
245; CHECK-NEXT:    br label [[LOOP:%.*]]
246; CHECK:       loop:
247; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
248; CHECK-NEXT:    [[NBITS:%.*]] = sub nuw i8 [[IV]], [[EXTRAOFFSET:%.*]]
249; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
250; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
251; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
252; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
253; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
254; CHECK:       end:
255; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
256; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
257; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
258; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
259; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
260; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
261; CHECK-NEXT:    ret i8 [[IV_RES]]
262;
263entry:
264  br label %loop
265
266loop:
267  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
268  %nbits = sub nuw i8 %iv, %extraoffset
269  %val.shifted = lshr i8 %val, %nbits
270  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
271  %iv.next = add i8 %iv, 1
272
273  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
274
275  br i1 %val.shifted.iszero, label %end, label %loop
276
277end:
278  %iv.res = phi i8 [ %iv, %loop ]
279  %nbits.res = phi i8 [ %nbits, %loop ]
280  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
281  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
282  %iv.next.res = phi i8 [ %iv.next, %loop ]
283
284  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
285
286  ret i8 %iv.res
287}
288
289; Likewise, plain `sub` is not fine.
290define i8 @n4(i8 %val, i8 %start, i8 %extraoffset) {
291; CHECK-LABEL: @n4(
292; CHECK-NEXT:  entry:
293; CHECK-NEXT:    br label [[LOOP:%.*]]
294; CHECK:       loop:
295; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
296; CHECK-NEXT:    [[NBITS:%.*]] = sub i8 [[IV]], [[EXTRAOFFSET:%.*]]
297; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
298; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
299; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
300; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
301; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
302; CHECK:       end:
303; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
304; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
305; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
306; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
307; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
308; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
309; CHECK-NEXT:    ret i8 [[IV_RES]]
310;
311entry:
312  br label %loop
313
314loop:
315  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
316  %nbits = sub i8 %iv, %extraoffset
317  %val.shifted = lshr i8 %val, %nbits
318  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
319  %iv.next = add i8 %iv, 1
320
321  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
322
323  br i1 %val.shifted.iszero, label %end, label %loop
324
325end:
326  %iv.res = phi i8 [ %iv, %loop ]
327  %nbits.res = phi i8 [ %nbits, %loop ]
328  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
329  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
330  %iv.next.res = phi i8 [ %iv.next, %loop ]
331
332  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
333
334  ret i8 %iv.res
335}
336
337; Likewise, plain `add` is not fine.
338define i8 @n5(i8 %val, i8 %start, i8 %extraoffset) {
339; CHECK-LABEL: @n5(
340; CHECK-NEXT:  entry:
341; CHECK-NEXT:    br label [[LOOP:%.*]]
342; CHECK:       loop:
343; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
344; CHECK-NEXT:    [[NBITS:%.*]] = add i8 [[IV]], [[EXTRAOFFSET:%.*]]
345; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
346; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
347; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
348; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
349; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
350; CHECK:       end:
351; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
352; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
353; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
354; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
355; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
356; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
357; CHECK-NEXT:    ret i8 [[IV_RES]]
358;
359entry:
360  br label %loop
361
362loop:
363  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
364  %nbits = add i8 %iv, %extraoffset
365  %val.shifted = lshr i8 %val, %nbits
366  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
367  %iv.next = add i8 %iv, 1
368
369  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
370
371  br i1 %val.shifted.iszero, label %end, label %loop
372
373end:
374  %iv.res = phi i8 [ %iv, %loop ]
375  %nbits.res = phi i8 [ %nbits, %loop ]
376  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
377  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
378  %iv.next.res = phi i8 [ %iv.next, %loop ]
379
380  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
381
382  ret i8 %iv.res
383}
384
385; Of course, we don't have to have an offset
386define i8 @p6(i8 %val, i8 %start) {
387; NOLZCNT-LABEL: @p6(
388; NOLZCNT-NEXT:  entry:
389; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
390; NOLZCNT:       loop:
391; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
392; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[IV]]
393; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
394; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
395; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[IV]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
396; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
397; NOLZCNT:       end:
398; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
399; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
400; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
401; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
402; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[IV_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
403; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
404;
405; LZCNT-LABEL: @p6(
406; LZCNT-NEXT:  entry:
407; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
408; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
409; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i8 [[VAL_NUMACTIVEBITS]], 0
410; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
411; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i8 [[IV_FINAL]], [[START]]
412; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
413; LZCNT-NEXT:    br label [[LOOP:%.*]]
414; LZCNT:       loop:
415; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
416; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
417; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
418; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
419; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[IV]]
420; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
421; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[IV]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])
422; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
423; LZCNT:       end:
424; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
425; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
426; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
427; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
428; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[IV_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
429; LZCNT-NEXT:    ret i8 [[IV_RES]]
430;
431entry:
432  br label %loop
433
434loop:
435  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
436  %val.shifted = lshr i8 %val, %iv
437  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
438  %iv.next = add i8 %iv, 1
439
440  call void @escape_inner(i8 %iv, i8 %iv, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
441
442  br i1 %val.shifted.iszero, label %end, label %loop
443
444end:
445  %iv.res = phi i8 [ %iv, %loop ]
446  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
447  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
448  %iv.next.res = phi i8 [ %iv.next, %loop ]
449
450  call void @escape_outer(i8 %iv.res, i8 %iv.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
451
452  ret i8 %iv.res
453}
454
455declare void @escape_inner.i7(i7, i7, i7, i1, i7)
456declare void @escape_outer.i7(i7, i7, i7, i1, i7)
457
458; Other bitwidths are fine also
459define i7 @p7(i7 %val, i7 %start, i7 %extraoffset) {
460; NOLZCNT-LABEL: @p7(
461; NOLZCNT-NEXT:  entry:
462; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
463; NOLZCNT:       loop:
464; NOLZCNT-NEXT:    [[IV:%.*]] = phi i7 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
465; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i7 [[IV]], [[EXTRAOFFSET:%.*]]
466; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i7 [[VAL:%.*]], [[NBITS]]
467; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i7 [[VAL_SHIFTED]], 0
468; NOLZCNT-NEXT:    [[IV_NEXT]] = add i7 [[IV]], 1
469; NOLZCNT-NEXT:    call void @escape_inner.i7(i7 [[IV]], i7 [[NBITS]], i7 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i7 [[IV_NEXT]])
470; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
471; NOLZCNT:       end:
472; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i7 [ [[IV]], [[LOOP]] ]
473; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i7 [ [[NBITS]], [[LOOP]] ]
474; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i7 [ [[VAL_SHIFTED]], [[LOOP]] ]
475; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
476; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i7 [ [[IV_NEXT]], [[LOOP]] ]
477; NOLZCNT-NEXT:    call void @escape_outer.i7(i7 [[IV_RES]], i7 [[NBITS_RES]], i7 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i7 [[IV_NEXT_RES]])
478; NOLZCNT-NEXT:    ret i7 [[IV_RES]]
479;
480; LZCNT-LABEL: @p7(
481; LZCNT-NEXT:  entry:
482; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i7 @llvm.ctlz.i7(i7 [[VAL:%.*]], i1 false)
483; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i7 7, [[VAL_NUMLEADINGZEROS]]
484; LZCNT-NEXT:    [[TMP0:%.*]] = sub i7 0, [[EXTRAOFFSET:%.*]]
485; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i7 [[VAL_NUMACTIVEBITS]], [[TMP0]]
486; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i7 @llvm.smax.i7(i7 [[VAL_NUMACTIVEBITS_OFFSET]], i7 [[START:%.*]])
487; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i7 [[IV_FINAL]], [[START]]
488; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i7 [[LOOP_BACKEDGETAKENCOUNT]], 1
489; LZCNT-NEXT:    br label [[LOOP:%.*]]
490; LZCNT:       loop:
491; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i7 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
492; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i7 [[LOOP_IV]], 1
493; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i7 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
494; LZCNT-NEXT:    [[IV:%.*]] = add nsw i7 [[LOOP_IV]], [[START]]
495; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i7 [[IV]], [[EXTRAOFFSET]]
496; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i7 [[VAL]], [[NBITS]]
497; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i7 [[IV]], 1
498; LZCNT-NEXT:    call void @escape_inner.i7(i7 [[IV]], i7 [[NBITS]], i7 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i7 [[IV_NEXT]])
499; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
500; LZCNT:       end:
501; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i7 [ [[IV_FINAL]], [[LOOP]] ]
502; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i7 [ [[NBITS]], [[LOOP]] ]
503; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i7 [ [[VAL_SHIFTED]], [[LOOP]] ]
504; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
505; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i7 [ [[IV_NEXT]], [[LOOP]] ]
506; LZCNT-NEXT:    call void @escape_outer.i7(i7 [[IV_RES]], i7 [[NBITS_RES]], i7 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i7 [[IV_NEXT_RES]])
507; LZCNT-NEXT:    ret i7 [[IV_RES]]
508;
509entry:
510  br label %loop
511
512loop:
513  %iv = phi i7 [ %start, %entry ], [ %iv.next, %loop ]
514  %nbits = add nsw i7 %iv, %extraoffset
515  %val.shifted = lshr i7 %val, %nbits
516  %val.shifted.iszero = icmp eq i7 %val.shifted, 0
517  %iv.next = add i7 %iv, 1
518
519  call void @escape_inner.i7(i7 %iv, i7 %nbits, i7 %val.shifted, i1 %val.shifted.iszero, i7 %iv.next)
520
521  br i1 %val.shifted.iszero, label %end, label %loop
522
523end:
524  %iv.res = phi i7 [ %iv, %loop ]
525  %nbits.res = phi i7 [ %nbits, %loop ]
526  %val.shifted.res = phi i7 [ %val.shifted, %loop ]
527  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
528  %iv.next.res = phi i7 [ %iv.next, %loop ]
529
530  call void @escape_outer.i7(i7 %iv.res, i7 %nbits.res, i7 %val.shifted.res, i1 %val.shifted.iszero.res, i7 %iv.next.res)
531
532  ret i7 %iv.res
533}
534
535; Step must be 1
536define i8 @n8(i8 %val, i8 %start, i8 %extraoffset) {
537; CHECK-LABEL: @n8(
538; CHECK-NEXT:  entry:
539; CHECK-NEXT:    br label [[LOOP:%.*]]
540; CHECK:       loop:
541; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
542; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
543; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
544; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
545; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 2
546; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
547; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
548; CHECK:       end:
549; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
550; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
551; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
552; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
553; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
554; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
555; CHECK-NEXT:    ret i8 [[IV_RES]]
556;
557entry:
558  br label %loop
559
560loop:
561  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
562  %nbits = add nsw i8 %iv, %extraoffset
563  %val.shifted = lshr i8 %val, %nbits
564  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
565  %iv.next = add i8 %iv, 2 ; not 1
566
567  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
568
569  br i1 %val.shifted.iszero, label %end, label %loop
570
571end:
572  %iv.res = phi i8 [ %iv, %loop ]
573  %nbits.res = phi i8 [ %nbits, %loop ]
574  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
575  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
576  %iv.next.res = phi i8 [ %iv.next, %loop ]
577
578  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
579
580  ret i8 %iv.res
581}
582
583; Cmp-br are commutable
584define i8 @t9(i8 %val, i8 %start, i8 %extraoffset) {
585; NOLZCNT-LABEL: @t9(
586; NOLZCNT-NEXT:  entry:
587; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
588; NOLZCNT:       loop:
589; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
590; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
591; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
592; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISNOTZERO:%.*]] = icmp ne i8 [[VAL_SHIFTED]], 0
593; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
594; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISNOTZERO]], i8 [[IV_NEXT]])
595; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISNOTZERO]], label [[LOOP]], label [[END:%.*]]
596; NOLZCNT:       end:
597; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
598; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
599; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
600; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISNOTZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISNOTZERO]], [[LOOP]] ]
601; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
602; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISNOTZERO_RES]], i8 [[IV_NEXT_RES]])
603; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
604;
605; LZCNT-LABEL: @t9(
606; LZCNT-NEXT:  entry:
607; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
608; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
609; LZCNT-NEXT:    [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]
610; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]
611; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
612; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]
613; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
614; LZCNT-NEXT:    br label [[LOOP:%.*]]
615; LZCNT:       loop:
616; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
617; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
618; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
619; LZCNT-NEXT:    [[VAL_SHIFTED_ISNOTZERO:%.*]] = xor i1 [[LOOP_IVCHECK]], true
620; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
621; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]
622; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
623; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
624; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISNOTZERO]], i8 [[IV_NEXT]])
625; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
626; LZCNT:       end:
627; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
628; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
629; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
630; LZCNT-NEXT:    [[VAL_SHIFTED_ISNOTZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISNOTZERO]], [[LOOP]] ]
631; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
632; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISNOTZERO_RES]], i8 [[IV_NEXT_RES]])
633; LZCNT-NEXT:    ret i8 [[IV_RES]]
634;
635entry:
636  br label %loop
637
638loop:
639  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
640  %nbits = add nsw i8 %iv, %extraoffset
641  %val.shifted = lshr i8 %val, %nbits
642  %val.shifted.isnotzero = icmp ne i8 %val.shifted, 0
643  %iv.next = add i8 %iv, 1
644
645  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.isnotzero, i8 %iv.next)
646
647  br i1 %val.shifted.isnotzero, label %loop, label %end
648
649end:
650  %iv.res = phi i8 [ %iv, %loop ]
651  %nbits.res = phi i8 [ %nbits, %loop ]
652  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
653  %val.shifted.isnotzero.res = phi i1 [ %val.shifted.isnotzero, %loop ]
654  %iv.next.res = phi i8 [ %iv.next, %loop ]
655
656  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.isnotzero.res, i8 %iv.next.res)
657
658  ret i8 %iv.res
659}
660
661; We want to exit once it becomes zero
662define i8 @n10(i8 %val, i8 %start, i8 %extraoffset) {
663; CHECK-LABEL: @n10(
664; CHECK-NEXT:  entry:
665; CHECK-NEXT:    br label [[LOOP:%.*]]
666; CHECK:       loop:
667; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
668; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
669; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
670; CHECK-NEXT:    [[VAL_SHIFTED_ISNOTZERO:%.*]] = icmp ne i8 [[VAL_SHIFTED]], 0
671; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
672; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISNOTZERO]], i8 [[IV_NEXT]])
673; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISNOTZERO]], label [[END:%.*]], label [[LOOP]]
674; CHECK:       end:
675; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
676; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
677; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
678; CHECK-NEXT:    [[VAL_SHIFTED_ISNOTZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISNOTZERO]], [[LOOP]] ]
679; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
680; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISNOTZERO_RES]], i8 [[IV_NEXT_RES]])
681; CHECK-NEXT:    ret i8 [[IV_RES]]
682;
683entry:
684  br label %loop
685
686loop:
687  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
688  %nbits = add nsw i8 %iv, %extraoffset
689  %val.shifted = lshr i8 %val, %nbits
690  %val.shifted.isnotzero = icmp ne i8 %val.shifted, 0 ; not eq
691  %iv.next = add i8 %iv, 1
692
693  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.isnotzero, i8 %iv.next)
694
695  br i1 %val.shifted.isnotzero, label %end, label %loop
696
697end:
698  %iv.res = phi i8 [ %iv, %loop ]
699  %nbits.res = phi i8 [ %nbits, %loop ]
700  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
701  %val.shifted.isnotzero.res = phi i1 [ %val.shifted.isnotzero, %loop ]
702  %iv.next.res = phi i8 [ %iv.next, %loop ]
703
704  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.isnotzero.res, i8 %iv.next.res)
705
706  ret i8 %iv.res
707}
708
709; Once it compares zero, we want to exit, not exit when it compares non-zero
710define i8 @n11(i8 %val, i8 %start, i8 %extraoffset) {
711; CHECK-LABEL: @n11(
712; CHECK-NEXT:  entry:
713; CHECK-NEXT:    br label [[LOOP:%.*]]
714; CHECK:       loop:
715; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
716; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
717; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
718; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
719; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
720; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
721; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[LOOP]], label [[END:%.*]]
722; CHECK:       end:
723; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
724; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
725; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
726; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
727; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
728; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
729; CHECK-NEXT:    ret i8 [[IV_RES]]
730;
731entry:
732  br label %loop
733
734loop:
735  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
736  %nbits = add nsw i8 %iv, %extraoffset
737  %val.shifted = lshr i8 %val, %nbits
738  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
739  %iv.next = add i8 %iv, 1
740
741  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
742
743  br i1 %val.shifted.iszero, label %loop, label %end ; wrong destinations
744
745end:
746  %iv.res = phi i8 [ %iv, %loop ]
747  %nbits.res = phi i8 [ %nbits, %loop ]
748  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
749  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
750  %iv.next.res = phi i8 [ %iv.next, %loop ]
751
752  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
753
754  ret i8 %iv.res
755}
756
757; We must be comparing with 0
758define i8 @n12(i8 %val, i8 %start, i8 %extraoffset) {
759; CHECK-LABEL: @n12(
760; CHECK-NEXT:  entry:
761; CHECK-NEXT:    br label [[LOOP:%.*]]
762; CHECK:       loop:
763; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
764; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
765; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
766; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 1
767; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
768; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
769; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
770; CHECK:       end:
771; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
772; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
773; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
774; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
775; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
776; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
777; CHECK-NEXT:    ret i8 [[IV_RES]]
778;
779entry:
780  br label %loop
781
782loop:
783  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
784  %nbits = add nsw i8 %iv, %extraoffset
785  %val.shifted = lshr i8 %val, %nbits
786  %val.shifted.iszero = icmp eq i8 %val.shifted, 1 ; not 0
787  %iv.next = add i8 %iv, 1
788
789  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
790
791  br i1 %val.shifted.iszero, label %end, label %loop
792
793end:
794  %iv.res = phi i8 [ %iv, %loop ]
795  %nbits.res = phi i8 [ %nbits, %loop ]
796  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
797  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
798  %iv.next.res = phi i8 [ %iv.next, %loop ]
799
800  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
801
802  ret i8 %iv.res
803}
804
805; Loop must have a single block.
806define i8 @n13(i8 %val, i8 %start, i8 %extraoffset) {
807; CHECK-LABEL: @n13(
808; CHECK-NEXT:  entry:
809; CHECK-NEXT:    br label [[LOOP:%.*]]
810; CHECK:       loop:
811; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_END:%.*]] ]
812; CHECK-NEXT:    br label [[LOOP_END]]
813; CHECK:       loop.end:
814; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
815; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
816; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
817; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
818; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
819; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
820; CHECK:       end:
821; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP_END]] ]
822; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP_END]] ]
823; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP_END]] ]
824; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP_END]] ]
825; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP_END]] ]
826; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
827; CHECK-NEXT:    ret i8 [[IV_RES]]
828;
829entry:
830  br label %loop
831
832loop:
833  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop.end ]
834  br label %loop.end
835
836loop.end:
837  %nbits = add nsw i8 %iv, %extraoffset
838  %val.shifted = lshr i8 %val, %nbits
839  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
840  %iv.next = add i8 %iv, 1
841
842  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
843
844  br i1 %val.shifted.iszero, label %end, label %loop
845
846end:
847  %iv.res = phi i8 [ %iv, %loop.end ]
848  %nbits.res = phi i8 [ %nbits, %loop.end ]
849  %val.shifted.res = phi i8 [ %val.shifted, %loop.end ]
850  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop.end ]
851  %iv.next.res = phi i8 [ %iv.next, %loop.end ]
852
853  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
854
855  ret i8 %iv.res
856}
857
858; The comparison must have an equality predicate
859define i8 @n14(i8 %val, i8 %start, i8 %extraoffset) {
860; CHECK-LABEL: @n14(
861; CHECK-NEXT:  entry:
862; CHECK-NEXT:    br label [[LOOP:%.*]]
863; CHECK:       loop:
864; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
865; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
866; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
867; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp ult i8 [[VAL_SHIFTED]], 1
868; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
869; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
870; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
871; CHECK:       end:
872; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
873; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
874; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
875; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
876; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
877; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
878; CHECK-NEXT:    ret i8 [[IV_RES]]
879;
880entry:
881  br label %loop
882
883loop:
884  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
885  %nbits = add nsw i8 %iv, %extraoffset
886  %val.shifted = lshr i8 %val, %nbits
887  %val.shifted.iszero = icmp ult i8 %val.shifted, 1 ; not `==0`
888  %iv.next = add i8 %iv, 1
889
890  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
891
892  br i1 %val.shifted.iszero, label %end, label %loop
893
894end:
895  %iv.res = phi i8 [ %iv, %loop ]
896  %nbits.res = phi i8 [ %nbits, %loop ]
897  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
898  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
899  %iv.next.res = phi i8 [ %iv.next, %loop ]
900
901  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
902
903  ret i8 %iv.res
904}
905
906; offset computation can be commuted
907define i8 @t15(i8 %val, i8 %start, i8 %extraoffset) {
908; NOLZCNT-LABEL: @t15(
909; NOLZCNT-NEXT:  entry:
910; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
911; NOLZCNT:       loop:
912; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
913; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[EXTRAOFFSET:%.*]], [[IV]]
914; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
915; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
916; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
917; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
918; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
919; NOLZCNT:       end:
920; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
921; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
922; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
923; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
924; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
925; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
926; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
927;
928; LZCNT-LABEL: @t15(
929; LZCNT-NEXT:  entry:
930; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
931; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
932; LZCNT-NEXT:    [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]
933; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]
934; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
935; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]
936; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
937; LZCNT-NEXT:    br label [[LOOP:%.*]]
938; LZCNT:       loop:
939; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
940; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
941; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
942; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
943; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[EXTRAOFFSET]], [[IV]]
944; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
945; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
946; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])
947; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
948; LZCNT:       end:
949; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
950; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
951; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
952; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
953; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
954; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
955; LZCNT-NEXT:    ret i8 [[IV_RES]]
956;
957entry:
958  br label %loop
959
960loop:
961  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
962  %nbits = add nsw i8 %extraoffset, %iv ; swapped order
963  %val.shifted = lshr i8 %val, %nbits
964  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
965  %iv.next = add i8 %iv, 1
966
967  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
968
969  br i1 %val.shifted.iszero, label %end, label %loop
970
971end:
972  %iv.res = phi i8 [ %iv, %loop ]
973  %nbits.res = phi i8 [ %nbits, %loop ]
974  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
975  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
976  %iv.next.res = phi i8 [ %iv.next, %loop ]
977
978  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
979
980  ret i8 %iv.res
981}
982
983; But for `sub nsw`, it is not commutable.
984define i8 @n16(i8 %val, i8 %start, i8 %extraoffset) {
985; CHECK-LABEL: @n16(
986; CHECK-NEXT:  entry:
987; CHECK-NEXT:    br label [[LOOP:%.*]]
988; CHECK:       loop:
989; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
990; CHECK-NEXT:    [[NBITS:%.*]] = sub nsw i8 [[EXTRAOFFSET:%.*]], [[IV]]
991; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
992; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
993; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
994; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
995; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
996; CHECK:       end:
997; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
998; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
999; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1000; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1001; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1002; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1003; CHECK-NEXT:    ret i8 [[IV_RES]]
1004;
1005entry:
1006  br label %loop
1007
1008loop:
1009  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
1010  %nbits = sub nsw i8 %extraoffset, %iv
1011  %val.shifted = lshr i8 %val, %nbits
1012  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1013  %iv.next = add i8 %iv, 1
1014
1015  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1016
1017  br i1 %val.shifted.iszero, label %end, label %loop
1018
1019end:
1020  %iv.res = phi i8 [ %iv, %loop ]
1021  %nbits.res = phi i8 [ %nbits, %loop ]
1022  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1023  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1024  %iv.next.res = phi i8 [ %iv.next, %loop ]
1025
1026  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1027
1028  ret i8 %iv.res
1029}
1030
1031; The offset must be loop-invariant
1032define i8 @n17(i8 %val, i8 %start) {
1033; CHECK-LABEL: @n17(
1034; CHECK-NEXT:  entry:
1035; CHECK-NEXT:    br label [[LOOP:%.*]]
1036; CHECK:       loop:
1037; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1038; CHECK-NEXT:    [[EXTRAOFFSET:%.*]] = call i8 @gen.i8()
1039; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]
1040; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
1041; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1042; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
1043; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1044; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1045; CHECK:       end:
1046; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1047; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1048; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1049; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1050; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1051; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1052; CHECK-NEXT:    ret i8 [[IV_RES]]
1053;
1054entry:
1055  br label %loop
1056
1057loop:
1058  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
1059  %extraoffset = call i8 @gen.i8()
1060  %nbits = add nsw i8 %iv, %extraoffset
1061  %val.shifted = lshr i8 %val, %nbits
1062  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1063  %iv.next = add i8 %iv, 1
1064
1065  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1066
1067  br i1 %val.shifted.iszero, label %end, label %loop
1068
1069end:
1070  %iv.res = phi i8 [ %iv, %loop ]
1071  %nbits.res = phi i8 [ %nbits, %loop ]
1072  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1073  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1074  %iv.next.res = phi i8 [ %iv.next, %loop ]
1075
1076  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1077
1078  ret i8 %iv.res
1079}
1080
1081; Likewise for `sub nsw`.
1082define i8 @n18(i8 %val, i8 %start) {
1083; CHECK-LABEL: @n18(
1084; CHECK-NEXT:  entry:
1085; CHECK-NEXT:    br label [[LOOP:%.*]]
1086; CHECK:       loop:
1087; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1088; CHECK-NEXT:    [[EXTRAOFFSET:%.*]] = call i8 @gen.i8()
1089; CHECK-NEXT:    [[NBITS:%.*]] = sub nsw i8 [[IV]], [[EXTRAOFFSET]]
1090; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
1091; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1092; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
1093; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1094; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1095; CHECK:       end:
1096; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1097; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1098; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1099; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1100; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1101; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1102; CHECK-NEXT:    ret i8 [[IV_RES]]
1103;
1104entry:
1105  br label %loop
1106
1107loop:
1108  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
1109  %extraoffset = call i8 @gen.i8()
1110  %nbits = sub nsw i8 %iv, %extraoffset
1111  %val.shifted = lshr i8 %val, %nbits
1112  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1113  %iv.next = add i8 %iv, 1
1114
1115  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1116
1117  br i1 %val.shifted.iszero, label %end, label %loop
1118
1119end:
1120  %iv.res = phi i8 [ %iv, %loop ]
1121  %nbits.res = phi i8 [ %nbits, %loop ]
1122  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1123  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1124  %iv.next.res = phi i8 [ %iv.next, %loop ]
1125
1126  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1127
1128  ret i8 %iv.res
1129}
1130
1131; The "induction variable" must be in the loop header.
1132define i8 @n19(i8 %val, i8 %start, i8 %extraoffset) {
1133; CHECK-LABEL: @n19(
1134; CHECK-NEXT:  entry:
1135; CHECK-NEXT:    br label [[LOOP_PREHEADER:%.*]]
1136; CHECK:       loop.preheader:
1137; CHECK-NEXT:    [[NOTIV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ]
1138; CHECK-NEXT:    br label [[LOOP:%.*]]
1139; CHECK:       loop:
1140; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[LOOP_PREHEADER]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1141; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[NOTIV]], [[EXTRAOFFSET:%.*]]
1142; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
1143; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1144; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
1145; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1146; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1147; CHECK:       end:
1148; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1149; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1150; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1151; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1152; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1153; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1154; CHECK-NEXT:    ret i8 [[IV_RES]]
1155;
1156entry:
1157  br label %loop.preheader
1158
1159loop.preheader:
1160  %notiv = phi i8 [ 0, %entry ]
1161  br label %loop
1162
1163loop:
1164  %iv = phi i8 [ %start, %loop.preheader ], [ %iv.next, %loop ]
1165  %nbits = add nsw i8 %notiv, %extraoffset ; uses %notiv instead of %iv
1166  %val.shifted = lshr i8 %val, %nbits
1167  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1168  %iv.next = add i8 %iv, 1
1169
1170  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1171
1172  br i1 %val.shifted.iszero, label %end, label %loop
1173
1174end:
1175  %iv.res = phi i8 [ %iv, %loop ]
1176  %nbits.res = phi i8 [ %nbits, %loop ]
1177  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1178  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1179  %iv.next.res = phi i8 [ %iv.next, %loop ]
1180
1181  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1182
1183  ret i8 %iv.res
1184}
1185
1186; IV must really be a PHI
1187define i8 @n20(i8 %val, i8 %start, i8 %extraoffset) {
1188; CHECK-LABEL: @n20(
1189; CHECK-NEXT:  entry:
1190; CHECK-NEXT:    br label [[LOOP:%.*]]
1191; CHECK:       loop:
1192; CHECK-NEXT:    [[IV:%.*]] = add i8 0, 0
1193; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
1194; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
1195; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1196; CHECK-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
1197; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1198; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1199; CHECK:       end:
1200; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1201; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1202; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1203; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1204; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1205; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1206; CHECK-NEXT:    ret i8 [[IV_RES]]
1207;
1208entry:
1209  br label %loop
1210
1211loop:
1212  %iv = add i8 0, 0 ; again not IV
1213  %nbits = add nsw i8 %iv, %extraoffset
1214  %val.shifted = lshr i8 %val, %nbits
1215  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1216  %iv.next = add i8 %iv, 1
1217
1218  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1219
1220  br i1 %val.shifted.iszero, label %end, label %loop
1221
1222end:
1223  %iv.res = phi i8 [ %iv, %loop ]
1224  %nbits.res = phi i8 [ %nbits, %loop ]
1225  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1226  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1227  %iv.next.res = phi i8 [ %iv.next, %loop ]
1228
1229  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1230
1231  ret i8 %iv.res
1232}
1233
1234; The induction should be actually increasing IV
1235define i8 @n21(i8 %val, i8 %start, i8 %extraoffset) {
1236; CHECK-LABEL: @n21(
1237; CHECK-NEXT:  entry:
1238; CHECK-NEXT:    br label [[LOOP:%.*]]
1239; CHECK:       loop:
1240; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1241; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
1242; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
1243; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1244; CHECK-NEXT:    [[IV_NEXT]] = add i8 0, 1
1245; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1246; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1247; CHECK:       end:
1248; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1249; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1250; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1251; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1252; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1253; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1254; CHECK-NEXT:    ret i8 [[IV_RES]]
1255;
1256entry:
1257  br label %loop
1258
1259loop:
1260  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
1261  %nbits = add nsw i8 %iv, %extraoffset
1262  %val.shifted = lshr i8 %val, %nbits
1263  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1264  %iv.next = add i8 0, 1 ; should be adding to IV
1265
1266  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1267
1268  br i1 %val.shifted.iszero, label %end, label %loop
1269
1270end:
1271  %iv.res = phi i8 [ %iv, %loop ]
1272  %nbits.res = phi i8 [ %nbits, %loop ]
1273  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1274  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1275  %iv.next.res = phi i8 [ %iv.next, %loop ]
1276
1277  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1278
1279  ret i8 %iv.res
1280}
1281
1282; We should not just blindly look for add, we should look what IV actually uses.
1283define i8 @n22(i8 %val, i8 %start, i8 %extraoffset) {
1284; NOLZCNT-LABEL: @n22(
1285; NOLZCNT-NEXT:  entry:
1286; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1287; NOLZCNT:       loop:
1288; NOLZCNT-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1289; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
1290; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL:%.*]], [[NBITS]]
1291; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1292; NOLZCNT-NEXT:    [[NOT_IV_NEXT:%.*]] = add i8 [[IV]], 1
1293; NOLZCNT-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
1294; NOLZCNT-NEXT:    [[ALSO_IV_NEXT:%.*]] = add i8 [[IV]], 1
1295; NOLZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1296; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1297; NOLZCNT:       end:
1298; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1299; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1300; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1301; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1302; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1303; NOLZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1304; NOLZCNT-NEXT:    ret i8 [[IV_RES]]
1305;
1306; LZCNT-LABEL: @n22(
1307; LZCNT-NEXT:  entry:
1308; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i8 @llvm.ctlz.i8(i8 [[VAL:%.*]], i1 false)
1309; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i8 8, [[VAL_NUMLEADINGZEROS]]
1310; LZCNT-NEXT:    [[TMP0:%.*]] = sub i8 0, [[EXTRAOFFSET:%.*]]
1311; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i8 [[VAL_NUMACTIVEBITS]], [[TMP0]]
1312; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i8 @llvm.smax.i8(i8 [[VAL_NUMACTIVEBITS_OFFSET]], i8 [[START:%.*]])
1313; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i8 [[IV_FINAL]], [[START]]
1314; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i8 [[LOOP_BACKEDGETAKENCOUNT]], 1
1315; LZCNT-NEXT:    br label [[LOOP:%.*]]
1316; LZCNT:       loop:
1317; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1318; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i8 [[LOOP_IV]], 1
1319; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i8 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1320; LZCNT-NEXT:    [[IV:%.*]] = add nsw i8 [[LOOP_IV]], [[START]]
1321; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET]]
1322; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
1323; LZCNT-NEXT:    [[NOT_IV_NEXT:%.*]] = add i8 [[IV]], 1
1324; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i8 [[IV]], 1
1325; LZCNT-NEXT:    [[ALSO_IV_NEXT:%.*]] = add i8 [[IV]], 1
1326; LZCNT-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i8 [[IV_NEXT]])
1327; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1328; LZCNT:       end:
1329; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV_FINAL]], [[LOOP]] ]
1330; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1331; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1332; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1333; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1334; LZCNT-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1335; LZCNT-NEXT:    ret i8 [[IV_RES]]
1336;
1337entry:
1338  br label %loop
1339
1340loop:
1341  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
1342  %nbits = add nsw i8 %iv, %extraoffset
1343  %val.shifted = lshr i8 %val, %nbits
1344  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1345  %not.iv.next = add i8 %iv, 1 ; not used by %iv
1346  %iv.next = add i8 %iv, 1
1347  %also.iv.next = add i8 %iv, 1 ; not used by %iv
1348
1349  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1350
1351  br i1 %val.shifted.iszero, label %end, label %loop
1352
1353end:
1354  %iv.res = phi i8 [ %iv, %loop ]
1355  %nbits.res = phi i8 [ %nbits, %loop ]
1356  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1357  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1358  %iv.next.res = phi i8 [ %iv.next, %loop ]
1359
1360  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1361
1362  ret i8 %iv.res
1363}
1364
1365define i8 @n23(i8 %start, i8 %extraoffset) {
1366; CHECK-LABEL: @n23(
1367; CHECK-NEXT:  entry:
1368; CHECK-NEXT:    br label [[LOOP:%.*]]
1369; CHECK:       loop:
1370; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1371; CHECK-NEXT:    [[NBITS:%.*]] = add nsw i8 [[IV]], [[EXTRAOFFSET:%.*]]
1372; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen.i8()
1373; CHECK-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i8 [[VAL]], [[NBITS]]
1374; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i8 [[VAL_SHIFTED]], 0
1375; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], 1
1376; CHECK-NEXT:    call void @escape_inner(i8 [[IV]], i8 [[NBITS]], i8 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i8 [[IV_NEXT]])
1377; CHECK-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1378; CHECK:       end:
1379; CHECK-NEXT:    [[IV_RES:%.*]] = phi i8 [ [[IV]], [[LOOP]] ]
1380; CHECK-NEXT:    [[NBITS_RES:%.*]] = phi i8 [ [[NBITS]], [[LOOP]] ]
1381; CHECK-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i8 [ [[VAL_SHIFTED]], [[LOOP]] ]
1382; CHECK-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1383; CHECK-NEXT:    [[IV_NEXT_RES:%.*]] = phi i8 [ [[IV_NEXT]], [[LOOP]] ]
1384; CHECK-NEXT:    call void @escape_outer(i8 [[IV_RES]], i8 [[NBITS_RES]], i8 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i8 [[IV_NEXT_RES]])
1385; CHECK-NEXT:    ret i8 [[IV_RES]]
1386;
1387entry:
1388  br label %loop
1389
1390loop:
1391  %iv = phi i8 [ %start, %entry ], [ %iv.next, %loop ]
1392  %nbits = add nsw i8 %iv, %extraoffset
1393  %val = call i8 @gen.i8()
1394  %val.shifted = lshr i8 %val, %nbits
1395  %val.shifted.iszero = icmp eq i8 %val.shifted, 0
1396  %iv.next = add i8 %iv, 1
1397
1398  call void @escape_inner(i8 %iv, i8 %nbits, i8 %val.shifted, i1 %val.shifted.iszero, i8 %iv.next)
1399
1400  br i1 %val.shifted.iszero, label %end, label %loop
1401
1402end:
1403  %iv.res = phi i8 [ %iv, %loop ]
1404  %nbits.res = phi i8 [ %nbits, %loop ]
1405  %val.shifted.res = phi i8 [ %val.shifted, %loop ]
1406  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1407  %iv.next.res = phi i8 [ %iv.next, %loop ]
1408
1409  call void @escape_outer(i8 %iv.res, i8 %nbits.res, i8 %val.shifted.res, i1 %val.shifted.iszero.res, i8 %iv.next.res)
1410
1411  ret i8 %iv.res
1412}
1413
1414; Tests with some small bit widths
1415declare void @escape_inner.i1(i1, i1, i1, i1, i1)
1416declare void @escape_outer.i1(i1, i1, i1, i1, i1)
1417declare void @escape_inner.i2(i2, i2, i2, i1, i2)
1418declare void @escape_outer.i2(i2, i2, i2, i1, i2)
1419declare void @escape_inner.i3(i3, i3, i3, i1, i3)
1420declare void @escape_outer.i3(i3, i3, i3, i1, i3)
1421
1422define i1 @t24_nooffset_i1(i1 %val, i1 %start) {
1423; NOLZCNT-LABEL: @t24_nooffset_i1(
1424; NOLZCNT-NEXT:  entry:
1425; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1426; NOLZCNT:       loop:
1427; NOLZCNT-NEXT:    [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1428; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL:%.*]], [[IV]]
1429; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false
1430; NOLZCNT-NEXT:    [[IV_NEXT]] = add i1 [[IV]], true
1431; NOLZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[IV]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])
1432; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1433; NOLZCNT:       end:
1434; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]
1435; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
1436; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1437; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
1438; NOLZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[IV_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
1439; NOLZCNT-NEXT:    ret i1 [[IV_RES]]
1440;
1441; LZCNT-LABEL: @t24_nooffset_i1(
1442; LZCNT-NEXT:  entry:
1443; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.ctlz.i1(i1 [[VAL:%.*]], i1 false)
1444; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]
1445; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i1 [[VAL_NUMACTIVEBITS]], false
1446; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])
1447; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i1 [[IV_FINAL]], [[START]]
1448; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true
1449; LZCNT-NEXT:    br label [[LOOP:%.*]]
1450; LZCNT:       loop:
1451; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1452; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true
1453; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1454; LZCNT-NEXT:    [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]
1455; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL]], [[IV]]
1456; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i1 [[IV]], true
1457; LZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[IV]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])
1458; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1459; LZCNT:       end:
1460; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]
1461; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
1462; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1463; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
1464; LZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[IV_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
1465; LZCNT-NEXT:    ret i1 [[IV_RES]]
1466;
1467entry:
1468  br label %loop
1469
1470loop:
1471  %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]
1472  %val.shifted = lshr i1 %val, %iv
1473  %val.shifted.iszero = icmp eq i1 %val.shifted, 0
1474  %iv.next = add i1 %iv, 1
1475
1476  call void @escape_inner.i1(i1 %iv, i1 %iv, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)
1477
1478  br i1 %val.shifted.iszero, label %end, label %loop
1479
1480end:
1481  %iv.res = phi i1 [ %iv, %loop ]
1482  %val.shifted.res = phi i1 [ %val.shifted, %loop ]
1483  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1484  %iv.next.res = phi i1 [ %iv.next, %loop ]
1485
1486  call void @escape_outer.i1(i1 %iv.res, i1 %iv.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)
1487
1488  ret i1 %iv.res
1489}
1490define i2 @t25_nooffset_i2(i2 %val, i2 %start) {
1491; NOLZCNT-LABEL: @t25_nooffset_i2(
1492; NOLZCNT-NEXT:  entry:
1493; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1494; NOLZCNT:       loop:
1495; NOLZCNT-NEXT:    [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1496; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL:%.*]], [[IV]]
1497; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0
1498; NOLZCNT-NEXT:    [[IV_NEXT]] = add i2 [[IV]], 1
1499; NOLZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[IV]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])
1500; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1501; NOLZCNT:       end:
1502; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]
1503; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
1504; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1505; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
1506; NOLZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[IV_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
1507; NOLZCNT-NEXT:    ret i2 [[IV_RES]]
1508;
1509; LZCNT-LABEL: @t25_nooffset_i2(
1510; LZCNT-NEXT:  entry:
1511; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.ctlz.i2(i2 [[VAL:%.*]], i1 false)
1512; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]
1513; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i2 [[VAL_NUMACTIVEBITS]], 0
1514; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])
1515; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i2 [[IV_FINAL]], [[START]]
1516; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 1
1517; LZCNT-NEXT:    br label [[LOOP:%.*]]
1518; LZCNT:       loop:
1519; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1520; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 1
1521; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1522; LZCNT-NEXT:    [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]
1523; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL]], [[IV]]
1524; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i2 [[IV]], 1
1525; LZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[IV]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])
1526; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1527; LZCNT:       end:
1528; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]
1529; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
1530; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1531; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
1532; LZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[IV_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
1533; LZCNT-NEXT:    ret i2 [[IV_RES]]
1534;
1535entry:
1536  br label %loop
1537
1538loop:
1539  %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]
1540  %val.shifted = lshr i2 %val, %iv
1541  %val.shifted.iszero = icmp eq i2 %val.shifted, 0
1542  %iv.next = add i2 %iv, 1
1543
1544  call void @escape_inner.i2(i2 %iv, i2 %iv, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)
1545
1546  br i1 %val.shifted.iszero, label %end, label %loop
1547
1548end:
1549  %iv.res = phi i2 [ %iv, %loop ]
1550  %val.shifted.res = phi i2 [ %val.shifted, %loop ]
1551  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1552  %iv.next.res = phi i2 [ %iv.next, %loop ]
1553
1554  call void @escape_outer.i2(i2 %iv.res, i2 %iv.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)
1555
1556  ret i2 %iv.res
1557}
1558define i3 @t26_nooffset_i3(i3 %val, i3 %start) {
1559; NOLZCNT-LABEL: @t26_nooffset_i3(
1560; NOLZCNT-NEXT:  entry:
1561; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1562; NOLZCNT:       loop:
1563; NOLZCNT-NEXT:    [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1564; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL:%.*]], [[IV]]
1565; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0
1566; NOLZCNT-NEXT:    [[IV_NEXT]] = add i3 [[IV]], 1
1567; NOLZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[IV]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])
1568; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1569; NOLZCNT:       end:
1570; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]
1571; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
1572; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1573; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
1574; NOLZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[IV_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
1575; NOLZCNT-NEXT:    ret i3 [[IV_RES]]
1576;
1577; LZCNT-LABEL: @t26_nooffset_i3(
1578; LZCNT-NEXT:  entry:
1579; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.ctlz.i3(i3 [[VAL:%.*]], i1 false)
1580; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]
1581; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nuw nsw i3 [[VAL_NUMACTIVEBITS]], 0
1582; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])
1583; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nuw nsw i3 [[IV_FINAL]], [[START]]
1584; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 1
1585; LZCNT-NEXT:    br label [[LOOP:%.*]]
1586; LZCNT:       loop:
1587; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1588; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 1
1589; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1590; LZCNT-NEXT:    [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]
1591; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL]], [[IV]]
1592; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i3 [[IV]], 1
1593; LZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[IV]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])
1594; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1595; LZCNT:       end:
1596; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]
1597; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
1598; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1599; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
1600; LZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[IV_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
1601; LZCNT-NEXT:    ret i3 [[IV_RES]]
1602;
1603entry:
1604  br label %loop
1605
1606loop:
1607  %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]
1608  %val.shifted = lshr i3 %val, %iv
1609  %val.shifted.iszero = icmp eq i3 %val.shifted, 0
1610  %iv.next = add i3 %iv, 1
1611
1612  call void @escape_inner.i3(i3 %iv, i3 %iv, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)
1613
1614  br i1 %val.shifted.iszero, label %end, label %loop
1615
1616end:
1617  %iv.res = phi i3 [ %iv, %loop ]
1618  %val.shifted.res = phi i3 [ %val.shifted, %loop ]
1619  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1620  %iv.next.res = phi i3 [ %iv.next, %loop ]
1621
1622  call void @escape_outer.i3(i3 %iv.res, i3 %iv.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)
1623
1624  ret i3 %iv.res
1625}
1626
1627define i1 @t27_addnsw_i1(i1 %val, i1 %start, i1 %extraoffset) {
1628; NOLZCNT-LABEL: @t27_addnsw_i1(
1629; NOLZCNT-NEXT:  entry:
1630; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1631; NOLZCNT:       loop:
1632; NOLZCNT-NEXT:    [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1633; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i1 [[IV]], [[EXTRAOFFSET:%.*]]
1634; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL:%.*]], [[NBITS]]
1635; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false
1636; NOLZCNT-NEXT:    [[IV_NEXT]] = add i1 [[IV]], true
1637; NOLZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])
1638; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1639; NOLZCNT:       end:
1640; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]
1641; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]
1642; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
1643; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1644; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
1645; NOLZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
1646; NOLZCNT-NEXT:    ret i1 [[IV_RES]]
1647;
1648; LZCNT-LABEL: @t27_addnsw_i1(
1649; LZCNT-NEXT:  entry:
1650; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.ctlz.i1(i1 [[VAL:%.*]], i1 false)
1651; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]
1652; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i1 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]
1653; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])
1654; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i1 [[IV_FINAL]], [[START]]
1655; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true
1656; LZCNT-NEXT:    br label [[LOOP:%.*]]
1657; LZCNT:       loop:
1658; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1659; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true
1660; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1661; LZCNT-NEXT:    [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]
1662; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i1 [[IV]], [[EXTRAOFFSET]]
1663; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL]], [[NBITS]]
1664; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i1 [[IV]], true
1665; LZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])
1666; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1667; LZCNT:       end:
1668; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]
1669; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]
1670; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
1671; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1672; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
1673; LZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
1674; LZCNT-NEXT:    ret i1 [[IV_RES]]
1675;
1676entry:
1677  br label %loop
1678
1679loop:
1680  %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]
1681  %nbits = add nsw i1 %iv, %extraoffset
1682  %val.shifted = lshr i1 %val, %nbits
1683  %val.shifted.iszero = icmp eq i1 %val.shifted, 0
1684  %iv.next = add i1 %iv, 1
1685
1686  call void @escape_inner.i1(i1 %iv, i1 %nbits, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)
1687
1688  br i1 %val.shifted.iszero, label %end, label %loop
1689
1690end:
1691  %iv.res = phi i1 [ %iv, %loop ]
1692  %nbits.res = phi i1 [ %nbits, %loop ]
1693  %val.shifted.res = phi i1 [ %val.shifted, %loop ]
1694  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1695  %iv.next.res = phi i1 [ %iv.next, %loop ]
1696
1697  call void @escape_outer.i1(i1 %iv.res, i1 %nbits.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)
1698
1699  ret i1 %iv.res
1700}
1701define i2 @t28_addnsw_i2(i2 %val, i2 %start, i2 %extraoffset) {
1702; NOLZCNT-LABEL: @t28_addnsw_i2(
1703; NOLZCNT-NEXT:  entry:
1704; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1705; NOLZCNT:       loop:
1706; NOLZCNT-NEXT:    [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1707; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i2 [[IV]], [[EXTRAOFFSET:%.*]]
1708; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL:%.*]], [[NBITS]]
1709; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0
1710; NOLZCNT-NEXT:    [[IV_NEXT]] = add i2 [[IV]], 1
1711; NOLZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])
1712; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1713; NOLZCNT:       end:
1714; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]
1715; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]
1716; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
1717; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1718; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
1719; NOLZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
1720; NOLZCNT-NEXT:    ret i2 [[IV_RES]]
1721;
1722; LZCNT-LABEL: @t28_addnsw_i2(
1723; LZCNT-NEXT:  entry:
1724; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.ctlz.i2(i2 [[VAL:%.*]], i1 false)
1725; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]
1726; LZCNT-NEXT:    [[TMP0:%.*]] = sub i2 0, [[EXTRAOFFSET:%.*]]
1727; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i2 [[VAL_NUMACTIVEBITS]], [[TMP0]]
1728; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])
1729; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i2 [[IV_FINAL]], [[START]]
1730; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 1
1731; LZCNT-NEXT:    br label [[LOOP:%.*]]
1732; LZCNT:       loop:
1733; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1734; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 1
1735; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1736; LZCNT-NEXT:    [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]
1737; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i2 [[IV]], [[EXTRAOFFSET]]
1738; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL]], [[NBITS]]
1739; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i2 [[IV]], 1
1740; LZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])
1741; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1742; LZCNT:       end:
1743; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]
1744; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]
1745; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
1746; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1747; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
1748; LZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
1749; LZCNT-NEXT:    ret i2 [[IV_RES]]
1750;
1751entry:
1752  br label %loop
1753
1754loop:
1755  %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]
1756  %nbits = add nsw i2 %iv, %extraoffset
1757  %val.shifted = lshr i2 %val, %nbits
1758  %val.shifted.iszero = icmp eq i2 %val.shifted, 0
1759  %iv.next = add i2 %iv, 1
1760
1761  call void @escape_inner.i2(i2 %iv, i2 %nbits, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)
1762
1763  br i1 %val.shifted.iszero, label %end, label %loop
1764
1765end:
1766  %iv.res = phi i2 [ %iv, %loop ]
1767  %nbits.res = phi i2 [ %nbits, %loop ]
1768  %val.shifted.res = phi i2 [ %val.shifted, %loop ]
1769  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1770  %iv.next.res = phi i2 [ %iv.next, %loop ]
1771
1772  call void @escape_outer.i2(i2 %iv.res, i2 %nbits.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)
1773
1774  ret i2 %iv.res
1775}
1776define i3 @t29_addnsw_i3(i3 %val, i3 %start, i3 %extraoffset) {
1777; NOLZCNT-LABEL: @t29_addnsw_i3(
1778; NOLZCNT-NEXT:  entry:
1779; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1780; NOLZCNT:       loop:
1781; NOLZCNT-NEXT:    [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1782; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nsw i3 [[IV]], [[EXTRAOFFSET:%.*]]
1783; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL:%.*]], [[NBITS]]
1784; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0
1785; NOLZCNT-NEXT:    [[IV_NEXT]] = add i3 [[IV]], 1
1786; NOLZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])
1787; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1788; NOLZCNT:       end:
1789; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]
1790; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]
1791; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
1792; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1793; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
1794; NOLZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
1795; NOLZCNT-NEXT:    ret i3 [[IV_RES]]
1796;
1797; LZCNT-LABEL: @t29_addnsw_i3(
1798; LZCNT-NEXT:  entry:
1799; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.ctlz.i3(i3 [[VAL:%.*]], i1 false)
1800; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]
1801; LZCNT-NEXT:    [[TMP0:%.*]] = sub i3 0, [[EXTRAOFFSET:%.*]]
1802; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i3 [[VAL_NUMACTIVEBITS]], [[TMP0]]
1803; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])
1804; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i3 [[IV_FINAL]], [[START]]
1805; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 1
1806; LZCNT-NEXT:    br label [[LOOP:%.*]]
1807; LZCNT:       loop:
1808; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1809; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 1
1810; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1811; LZCNT-NEXT:    [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]
1812; LZCNT-NEXT:    [[NBITS:%.*]] = add nsw i3 [[IV]], [[EXTRAOFFSET]]
1813; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL]], [[NBITS]]
1814; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i3 [[IV]], 1
1815; LZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])
1816; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1817; LZCNT:       end:
1818; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]
1819; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]
1820; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
1821; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1822; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
1823; LZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
1824; LZCNT-NEXT:    ret i3 [[IV_RES]]
1825;
1826entry:
1827  br label %loop
1828
1829loop:
1830  %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]
1831  %nbits = add nsw i3 %iv, %extraoffset
1832  %val.shifted = lshr i3 %val, %nbits
1833  %val.shifted.iszero = icmp eq i3 %val.shifted, 0
1834  %iv.next = add i3 %iv, 1
1835
1836  call void @escape_inner.i3(i3 %iv, i3 %nbits, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)
1837
1838  br i1 %val.shifted.iszero, label %end, label %loop
1839
1840end:
1841  %iv.res = phi i3 [ %iv, %loop ]
1842  %nbits.res = phi i3 [ %nbits, %loop ]
1843  %val.shifted.res = phi i3 [ %val.shifted, %loop ]
1844  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1845  %iv.next.res = phi i3 [ %iv.next, %loop ]
1846
1847  call void @escape_outer.i3(i3 %iv.res, i3 %nbits.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)
1848
1849  ret i3 %iv.res
1850}
1851
1852define i1 @t30_addnuw_i1(i1 %val, i1 %start, i1 %extraoffset) {
1853; NOLZCNT-LABEL: @t30_addnuw_i1(
1854; NOLZCNT-NEXT:  entry:
1855; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1856; NOLZCNT:       loop:
1857; NOLZCNT-NEXT:    [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1858; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nuw i1 [[IV]], [[EXTRAOFFSET:%.*]]
1859; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL:%.*]], [[NBITS]]
1860; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false
1861; NOLZCNT-NEXT:    [[IV_NEXT]] = add i1 [[IV]], true
1862; NOLZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])
1863; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1864; NOLZCNT:       end:
1865; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]
1866; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]
1867; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
1868; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1869; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
1870; NOLZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
1871; NOLZCNT-NEXT:    ret i1 [[IV_RES]]
1872;
1873; LZCNT-LABEL: @t30_addnuw_i1(
1874; LZCNT-NEXT:  entry:
1875; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.ctlz.i1(i1 [[VAL:%.*]], i1 false)
1876; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]
1877; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i1 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]
1878; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])
1879; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i1 [[IV_FINAL]], [[START]]
1880; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true
1881; LZCNT-NEXT:    br label [[LOOP:%.*]]
1882; LZCNT:       loop:
1883; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1884; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true
1885; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1886; LZCNT-NEXT:    [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]
1887; LZCNT-NEXT:    [[NBITS:%.*]] = add nuw i1 [[IV]], [[EXTRAOFFSET]]
1888; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL]], [[NBITS]]
1889; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i1 [[IV]], true
1890; LZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])
1891; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1892; LZCNT:       end:
1893; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]
1894; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]
1895; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
1896; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1897; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
1898; LZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
1899; LZCNT-NEXT:    ret i1 [[IV_RES]]
1900;
1901entry:
1902  br label %loop
1903
1904loop:
1905  %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]
1906  %nbits = add nuw i1 %iv, %extraoffset
1907  %val.shifted = lshr i1 %val, %nbits
1908  %val.shifted.iszero = icmp eq i1 %val.shifted, 0
1909  %iv.next = add i1 %iv, 1
1910
1911  call void @escape_inner.i1(i1 %iv, i1 %nbits, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)
1912
1913  br i1 %val.shifted.iszero, label %end, label %loop
1914
1915end:
1916  %iv.res = phi i1 [ %iv, %loop ]
1917  %nbits.res = phi i1 [ %nbits, %loop ]
1918  %val.shifted.res = phi i1 [ %val.shifted, %loop ]
1919  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1920  %iv.next.res = phi i1 [ %iv.next, %loop ]
1921
1922  call void @escape_outer.i1(i1 %iv.res, i1 %nbits.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)
1923
1924  ret i1 %iv.res
1925}
1926define i2 @t31_addnuw_i2(i2 %val, i2 %start, i2 %extraoffset) {
1927; NOLZCNT-LABEL: @t31_addnuw_i2(
1928; NOLZCNT-NEXT:  entry:
1929; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
1930; NOLZCNT:       loop:
1931; NOLZCNT-NEXT:    [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1932; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nuw i2 [[IV]], [[EXTRAOFFSET:%.*]]
1933; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL:%.*]], [[NBITS]]
1934; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0
1935; NOLZCNT-NEXT:    [[IV_NEXT]] = add i2 [[IV]], 1
1936; NOLZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])
1937; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
1938; NOLZCNT:       end:
1939; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]
1940; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]
1941; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
1942; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
1943; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
1944; NOLZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
1945; NOLZCNT-NEXT:    ret i2 [[IV_RES]]
1946;
1947; LZCNT-LABEL: @t31_addnuw_i2(
1948; LZCNT-NEXT:  entry:
1949; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.ctlz.i2(i2 [[VAL:%.*]], i1 false)
1950; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]
1951; LZCNT-NEXT:    [[TMP0:%.*]] = sub i2 0, [[EXTRAOFFSET:%.*]]
1952; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i2 [[VAL_NUMACTIVEBITS]], [[TMP0]]
1953; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])
1954; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i2 [[IV_FINAL]], [[START]]
1955; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 1
1956; LZCNT-NEXT:    br label [[LOOP:%.*]]
1957; LZCNT:       loop:
1958; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
1959; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 1
1960; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
1961; LZCNT-NEXT:    [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]
1962; LZCNT-NEXT:    [[NBITS:%.*]] = add nuw i2 [[IV]], [[EXTRAOFFSET]]
1963; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL]], [[NBITS]]
1964; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i2 [[IV]], 1
1965; LZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])
1966; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
1967; LZCNT:       end:
1968; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]
1969; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]
1970; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
1971; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
1972; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
1973; LZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
1974; LZCNT-NEXT:    ret i2 [[IV_RES]]
1975;
1976entry:
1977  br label %loop
1978
1979loop:
1980  %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]
1981  %nbits = add nuw i2 %iv, %extraoffset
1982  %val.shifted = lshr i2 %val, %nbits
1983  %val.shifted.iszero = icmp eq i2 %val.shifted, 0
1984  %iv.next = add i2 %iv, 1
1985
1986  call void @escape_inner.i2(i2 %iv, i2 %nbits, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)
1987
1988  br i1 %val.shifted.iszero, label %end, label %loop
1989
1990end:
1991  %iv.res = phi i2 [ %iv, %loop ]
1992  %nbits.res = phi i2 [ %nbits, %loop ]
1993  %val.shifted.res = phi i2 [ %val.shifted, %loop ]
1994  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
1995  %iv.next.res = phi i2 [ %iv.next, %loop ]
1996
1997  call void @escape_outer.i2(i2 %iv.res, i2 %nbits.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)
1998
1999  ret i2 %iv.res
2000}
2001define i3 @t32_addnuw_i3(i3 %val, i3 %start, i3 %extraoffset) {
2002; NOLZCNT-LABEL: @t32_addnuw_i3(
2003; NOLZCNT-NEXT:  entry:
2004; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
2005; NOLZCNT:       loop:
2006; NOLZCNT-NEXT:    [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
2007; NOLZCNT-NEXT:    [[NBITS:%.*]] = add nuw i3 [[IV]], [[EXTRAOFFSET:%.*]]
2008; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL:%.*]], [[NBITS]]
2009; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0
2010; NOLZCNT-NEXT:    [[IV_NEXT]] = add i3 [[IV]], 1
2011; NOLZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])
2012; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
2013; NOLZCNT:       end:
2014; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]
2015; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]
2016; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
2017; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
2018; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
2019; NOLZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
2020; NOLZCNT-NEXT:    ret i3 [[IV_RES]]
2021;
2022; LZCNT-LABEL: @t32_addnuw_i3(
2023; LZCNT-NEXT:  entry:
2024; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.ctlz.i3(i3 [[VAL:%.*]], i1 false)
2025; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]
2026; LZCNT-NEXT:    [[TMP0:%.*]] = sub i3 0, [[EXTRAOFFSET:%.*]]
2027; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i3 [[VAL_NUMACTIVEBITS]], [[TMP0]]
2028; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])
2029; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i3 [[IV_FINAL]], [[START]]
2030; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 1
2031; LZCNT-NEXT:    br label [[LOOP:%.*]]
2032; LZCNT:       loop:
2033; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
2034; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 1
2035; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
2036; LZCNT-NEXT:    [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]
2037; LZCNT-NEXT:    [[NBITS:%.*]] = add nuw i3 [[IV]], [[EXTRAOFFSET]]
2038; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL]], [[NBITS]]
2039; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i3 [[IV]], 1
2040; LZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])
2041; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
2042; LZCNT:       end:
2043; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]
2044; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]
2045; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
2046; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
2047; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
2048; LZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
2049; LZCNT-NEXT:    ret i3 [[IV_RES]]
2050;
2051entry:
2052  br label %loop
2053
2054loop:
2055  %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]
2056  %nbits = add nuw i3 %iv, %extraoffset
2057  %val.shifted = lshr i3 %val, %nbits
2058  %val.shifted.iszero = icmp eq i3 %val.shifted, 0
2059  %iv.next = add i3 %iv, 1
2060
2061  call void @escape_inner.i3(i3 %iv, i3 %nbits, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)
2062
2063  br i1 %val.shifted.iszero, label %end, label %loop
2064
2065end:
2066  %iv.res = phi i3 [ %iv, %loop ]
2067  %nbits.res = phi i3 [ %nbits, %loop ]
2068  %val.shifted.res = phi i3 [ %val.shifted, %loop ]
2069  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
2070  %iv.next.res = phi i3 [ %iv.next, %loop ]
2071
2072  call void @escape_outer.i3(i3 %iv.res, i3 %nbits.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)
2073
2074  ret i3 %iv.res
2075}
2076
2077
2078define i1 @t33_subnsw_i1(i1 %val, i1 %start, i1 %extraoffset) {
2079; NOLZCNT-LABEL: @t33_subnsw_i1(
2080; NOLZCNT-NEXT:  entry:
2081; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
2082; NOLZCNT:       loop:
2083; NOLZCNT-NEXT:    [[IV:%.*]] = phi i1 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
2084; NOLZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i1 [[IV]], [[EXTRAOFFSET:%.*]]
2085; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL:%.*]], [[NBITS]]
2086; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i1 [[VAL_SHIFTED]], false
2087; NOLZCNT-NEXT:    [[IV_NEXT]] = add i1 [[IV]], true
2088; NOLZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i1 [[IV_NEXT]])
2089; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
2090; NOLZCNT:       end:
2091; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV]], [[LOOP]] ]
2092; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]
2093; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
2094; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
2095; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
2096; NOLZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
2097; NOLZCNT-NEXT:    ret i1 [[IV_RES]]
2098;
2099; LZCNT-LABEL: @t33_subnsw_i1(
2100; LZCNT-NEXT:  entry:
2101; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i1 @llvm.ctlz.i1(i1 [[VAL:%.*]], i1 false)
2102; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i1 true, [[VAL_NUMLEADINGZEROS]]
2103; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i1 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]
2104; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_NUMACTIVEBITS_OFFSET]], i1 [[START:%.*]])
2105; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i1 [[IV_FINAL]], [[START]]
2106; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i1 [[LOOP_BACKEDGETAKENCOUNT]], true
2107; LZCNT-NEXT:    br label [[LOOP:%.*]]
2108; LZCNT:       loop:
2109; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
2110; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i1 [[LOOP_IV]], true
2111; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i1 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
2112; LZCNT-NEXT:    [[IV:%.*]] = add nsw i1 [[LOOP_IV]], [[START]]
2113; LZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i1 [[IV]], [[EXTRAOFFSET]]
2114; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i1 [[VAL]], [[NBITS]]
2115; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i1 [[IV]], true
2116; LZCNT-NEXT:    call void @escape_inner.i1(i1 [[IV]], i1 [[NBITS]], i1 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i1 [[IV_NEXT]])
2117; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
2118; LZCNT:       end:
2119; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i1 [ [[IV_FINAL]], [[LOOP]] ]
2120; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i1 [ [[NBITS]], [[LOOP]] ]
2121; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i1 [ [[VAL_SHIFTED]], [[LOOP]] ]
2122; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
2123; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i1 [ [[IV_NEXT]], [[LOOP]] ]
2124; LZCNT-NEXT:    call void @escape_outer.i1(i1 [[IV_RES]], i1 [[NBITS_RES]], i1 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i1 [[IV_NEXT_RES]])
2125; LZCNT-NEXT:    ret i1 [[IV_RES]]
2126;
2127entry:
2128  br label %loop
2129
2130loop:
2131  %iv = phi i1 [ %start, %entry ], [ %iv.next, %loop ]
2132  %nbits = sub nsw i1 %iv, %extraoffset
2133  %val.shifted = lshr i1 %val, %nbits
2134  %val.shifted.iszero = icmp eq i1 %val.shifted, 0
2135  %iv.next = add i1 %iv, 1
2136
2137  call void @escape_inner.i1(i1 %iv, i1 %nbits, i1 %val.shifted, i1 %val.shifted.iszero, i1 %iv.next)
2138
2139  br i1 %val.shifted.iszero, label %end, label %loop
2140
2141end:
2142  %iv.res = phi i1 [ %iv, %loop ]
2143  %nbits.res = phi i1 [ %nbits, %loop ]
2144  %val.shifted.res = phi i1 [ %val.shifted, %loop ]
2145  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
2146  %iv.next.res = phi i1 [ %iv.next, %loop ]
2147
2148  call void @escape_outer.i1(i1 %iv.res, i1 %nbits.res, i1 %val.shifted.res, i1 %val.shifted.iszero.res, i1 %iv.next.res)
2149
2150  ret i1 %iv.res
2151}
2152define i2 @t34_addnuw_i2(i2 %val, i2 %start, i2 %extraoffset) {
2153; NOLZCNT-LABEL: @t34_addnuw_i2(
2154; NOLZCNT-NEXT:  entry:
2155; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
2156; NOLZCNT:       loop:
2157; NOLZCNT-NEXT:    [[IV:%.*]] = phi i2 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
2158; NOLZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i2 [[IV]], [[EXTRAOFFSET:%.*]]
2159; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL:%.*]], [[NBITS]]
2160; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i2 [[VAL_SHIFTED]], 0
2161; NOLZCNT-NEXT:    [[IV_NEXT]] = add i2 [[IV]], 1
2162; NOLZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i2 [[IV_NEXT]])
2163; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
2164; NOLZCNT:       end:
2165; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV]], [[LOOP]] ]
2166; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]
2167; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
2168; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
2169; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
2170; NOLZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
2171; NOLZCNT-NEXT:    ret i2 [[IV_RES]]
2172;
2173; LZCNT-LABEL: @t34_addnuw_i2(
2174; LZCNT-NEXT:  entry:
2175; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i2 @llvm.ctlz.i2(i2 [[VAL:%.*]], i1 false)
2176; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw i2 -2, [[VAL_NUMLEADINGZEROS]]
2177; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i2 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]
2178; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i2 @llvm.smax.i2(i2 [[VAL_NUMACTIVEBITS_OFFSET]], i2 [[START:%.*]])
2179; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i2 [[IV_FINAL]], [[START]]
2180; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw i2 [[LOOP_BACKEDGETAKENCOUNT]], 1
2181; LZCNT-NEXT:    br label [[LOOP:%.*]]
2182; LZCNT:       loop:
2183; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i2 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
2184; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw i2 [[LOOP_IV]], 1
2185; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i2 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
2186; LZCNT-NEXT:    [[IV:%.*]] = add nsw i2 [[LOOP_IV]], [[START]]
2187; LZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i2 [[IV]], [[EXTRAOFFSET]]
2188; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i2 [[VAL]], [[NBITS]]
2189; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i2 [[IV]], 1
2190; LZCNT-NEXT:    call void @escape_inner.i2(i2 [[IV]], i2 [[NBITS]], i2 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i2 [[IV_NEXT]])
2191; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
2192; LZCNT:       end:
2193; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i2 [ [[IV_FINAL]], [[LOOP]] ]
2194; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i2 [ [[NBITS]], [[LOOP]] ]
2195; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i2 [ [[VAL_SHIFTED]], [[LOOP]] ]
2196; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
2197; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i2 [ [[IV_NEXT]], [[LOOP]] ]
2198; LZCNT-NEXT:    call void @escape_outer.i2(i2 [[IV_RES]], i2 [[NBITS_RES]], i2 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i2 [[IV_NEXT_RES]])
2199; LZCNT-NEXT:    ret i2 [[IV_RES]]
2200;
2201entry:
2202  br label %loop
2203
2204loop:
2205  %iv = phi i2 [ %start, %entry ], [ %iv.next, %loop ]
2206  %nbits = sub nsw i2 %iv, %extraoffset
2207  %val.shifted = lshr i2 %val, %nbits
2208  %val.shifted.iszero = icmp eq i2 %val.shifted, 0
2209  %iv.next = add i2 %iv, 1
2210
2211  call void @escape_inner.i2(i2 %iv, i2 %nbits, i2 %val.shifted, i1 %val.shifted.iszero, i2 %iv.next)
2212
2213  br i1 %val.shifted.iszero, label %end, label %loop
2214
2215end:
2216  %iv.res = phi i2 [ %iv, %loop ]
2217  %nbits.res = phi i2 [ %nbits, %loop ]
2218  %val.shifted.res = phi i2 [ %val.shifted, %loop ]
2219  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
2220  %iv.next.res = phi i2 [ %iv.next, %loop ]
2221
2222  call void @escape_outer.i2(i2 %iv.res, i2 %nbits.res, i2 %val.shifted.res, i1 %val.shifted.iszero.res, i2 %iv.next.res)
2223
2224  ret i2 %iv.res
2225}
2226define i3 @t35_addnuw_i3(i3 %val, i3 %start, i3 %extraoffset) {
2227; NOLZCNT-LABEL: @t35_addnuw_i3(
2228; NOLZCNT-NEXT:  entry:
2229; NOLZCNT-NEXT:    br label [[LOOP:%.*]]
2230; NOLZCNT:       loop:
2231; NOLZCNT-NEXT:    [[IV:%.*]] = phi i3 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
2232; NOLZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i3 [[IV]], [[EXTRAOFFSET:%.*]]
2233; NOLZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL:%.*]], [[NBITS]]
2234; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO:%.*]] = icmp eq i3 [[VAL_SHIFTED]], 0
2235; NOLZCNT-NEXT:    [[IV_NEXT]] = add i3 [[IV]], 1
2236; NOLZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[VAL_SHIFTED_ISZERO]], i3 [[IV_NEXT]])
2237; NOLZCNT-NEXT:    br i1 [[VAL_SHIFTED_ISZERO]], label [[END:%.*]], label [[LOOP]]
2238; NOLZCNT:       end:
2239; NOLZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV]], [[LOOP]] ]
2240; NOLZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]
2241; NOLZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
2242; NOLZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[VAL_SHIFTED_ISZERO]], [[LOOP]] ]
2243; NOLZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
2244; NOLZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
2245; NOLZCNT-NEXT:    ret i3 [[IV_RES]]
2246;
2247; LZCNT-LABEL: @t35_addnuw_i3(
2248; LZCNT-NEXT:  entry:
2249; LZCNT-NEXT:    [[VAL_NUMLEADINGZEROS:%.*]] = call i3 @llvm.ctlz.i3(i3 [[VAL:%.*]], i1 false)
2250; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS:%.*]] = sub nuw nsw i3 3, [[VAL_NUMLEADINGZEROS]]
2251; LZCNT-NEXT:    [[VAL_NUMACTIVEBITS_OFFSET:%.*]] = add nsw i3 [[VAL_NUMACTIVEBITS]], [[EXTRAOFFSET:%.*]]
2252; LZCNT-NEXT:    [[IV_FINAL:%.*]] = call i3 @llvm.smax.i3(i3 [[VAL_NUMACTIVEBITS_OFFSET]], i3 [[START:%.*]])
2253; LZCNT-NEXT:    [[LOOP_BACKEDGETAKENCOUNT:%.*]] = sub nsw i3 [[IV_FINAL]], [[START]]
2254; LZCNT-NEXT:    [[LOOP_TRIPCOUNT:%.*]] = add nuw nsw i3 [[LOOP_BACKEDGETAKENCOUNT]], 1
2255; LZCNT-NEXT:    br label [[LOOP:%.*]]
2256; LZCNT:       loop:
2257; LZCNT-NEXT:    [[LOOP_IV:%.*]] = phi i3 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_IV_NEXT:%.*]], [[LOOP]] ]
2258; LZCNT-NEXT:    [[LOOP_IV_NEXT]] = add nuw nsw i3 [[LOOP_IV]], 1
2259; LZCNT-NEXT:    [[LOOP_IVCHECK:%.*]] = icmp eq i3 [[LOOP_IV_NEXT]], [[LOOP_TRIPCOUNT]]
2260; LZCNT-NEXT:    [[IV:%.*]] = add nsw i3 [[LOOP_IV]], [[START]]
2261; LZCNT-NEXT:    [[NBITS:%.*]] = sub nsw i3 [[IV]], [[EXTRAOFFSET]]
2262; LZCNT-NEXT:    [[VAL_SHIFTED:%.*]] = lshr i3 [[VAL]], [[NBITS]]
2263; LZCNT-NEXT:    [[IV_NEXT:%.*]] = add i3 [[IV]], 1
2264; LZCNT-NEXT:    call void @escape_inner.i3(i3 [[IV]], i3 [[NBITS]], i3 [[VAL_SHIFTED]], i1 [[LOOP_IVCHECK]], i3 [[IV_NEXT]])
2265; LZCNT-NEXT:    br i1 [[LOOP_IVCHECK]], label [[END:%.*]], label [[LOOP]]
2266; LZCNT:       end:
2267; LZCNT-NEXT:    [[IV_RES:%.*]] = phi i3 [ [[IV_FINAL]], [[LOOP]] ]
2268; LZCNT-NEXT:    [[NBITS_RES:%.*]] = phi i3 [ [[NBITS]], [[LOOP]] ]
2269; LZCNT-NEXT:    [[VAL_SHIFTED_RES:%.*]] = phi i3 [ [[VAL_SHIFTED]], [[LOOP]] ]
2270; LZCNT-NEXT:    [[VAL_SHIFTED_ISZERO_RES:%.*]] = phi i1 [ [[LOOP_IVCHECK]], [[LOOP]] ]
2271; LZCNT-NEXT:    [[IV_NEXT_RES:%.*]] = phi i3 [ [[IV_NEXT]], [[LOOP]] ]
2272; LZCNT-NEXT:    call void @escape_outer.i3(i3 [[IV_RES]], i3 [[NBITS_RES]], i3 [[VAL_SHIFTED_RES]], i1 [[VAL_SHIFTED_ISZERO_RES]], i3 [[IV_NEXT_RES]])
2273; LZCNT-NEXT:    ret i3 [[IV_RES]]
2274;
2275entry:
2276  br label %loop
2277
2278loop:
2279  %iv = phi i3 [ %start, %entry ], [ %iv.next, %loop ]
2280  %nbits = sub nsw i3 %iv, %extraoffset
2281  %val.shifted = lshr i3 %val, %nbits
2282  %val.shifted.iszero = icmp eq i3 %val.shifted, 0
2283  %iv.next = add i3 %iv, 1
2284
2285  call void @escape_inner.i3(i3 %iv, i3 %nbits, i3 %val.shifted, i1 %val.shifted.iszero, i3 %iv.next)
2286
2287  br i1 %val.shifted.iszero, label %end, label %loop
2288
2289end:
2290  %iv.res = phi i3 [ %iv, %loop ]
2291  %nbits.res = phi i3 [ %nbits, %loop ]
2292  %val.shifted.res = phi i3 [ %val.shifted, %loop ]
2293  %val.shifted.iszero.res = phi i1 [ %val.shifted.iszero, %loop ]
2294  %iv.next.res = phi i3 [ %iv.next, %loop ]
2295
2296  call void @escape_outer.i3(i3 %iv.res, i3 %nbits.res, i3 %val.shifted.res, i1 %val.shifted.iszero.res, i3 %iv.next.res)
2297
2298  ret i3 %iv.res
2299}
2300