1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
3
4; Test cases that require rewriting zext SCEV expression with infomration from
5; the loop guards.
6
7define void @rewrite_zext(i32 %n) {
8; CHECK-LABEL: 'rewrite_zext'
9; CHECK-NEXT:  Classifying expressions for: @rewrite_zext
10; CHECK-NEXT:    %ext = zext i32 %n to i64
11; CHECK-NEXT:    --> (zext i32 %n to i64) U: [0,4294967296) S: [0,4294967296)
12; CHECK-NEXT:    %n.vec = and i64 %ext, -8
13; CHECK-NEXT:    --> (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> U: [0,4294967289) S: [0,4294967289)
14; CHECK-NEXT:    %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
15; CHECK-NEXT:    --> {0,+,8}<nuw><nsw><%loop> U: [0,17) S: [0,17) Exits: (8 * ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8))<nuw> LoopDispositions: { %loop: Computable }
16; CHECK-NEXT:    %index.next = add nuw nsw i64 %index, 8
17; CHECK-NEXT:    --> {8,+,8}<nuw><nsw><%loop> U: [8,25) S: [8,25) Exits: (8 + (8 * ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8))<nuw>) LoopDispositions: { %loop: Computable }
18; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext
19; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
20; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 2
21; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
22; CHECK-NEXT:  Loop %loop: Trip multiple is 1
23;
24entry:
25  %ext = zext i32 %n to i64
26  %cmp5 = icmp ule i64 %ext, 24
27  br i1 %cmp5, label %check, label %exit
28
29check:                                 ; preds = %entry
30  %min.iters.check = icmp ult i64 %ext, 8
31  %n.vec = and i64 %ext, -8
32  br i1 %min.iters.check, label %exit, label %loop
33
34loop:
35  %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
36  %index.next = add nuw nsw i64 %index, 8
37  %ec = icmp eq i64 %index.next, %n.vec
38  br i1 %ec, label %exit, label %loop
39
40exit:
41  ret void
42}
43
44; Test case from PR40961.
45define i32 @rewrite_zext_min_max(i32 %N, ptr %arr) {
46; CHECK-LABEL: 'rewrite_zext_min_max'
47; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_min_max
48; CHECK-NEXT:    %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
49; CHECK-NEXT:    --> (16 umin %N) U: [0,17) S: [0,17)
50; CHECK-NEXT:    %ext = zext i32 %umin to i64
51; CHECK-NEXT:    --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
52; CHECK-NEXT:    %n.vec = and i64 %ext, 28
53; CHECK-NEXT:    --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
54; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
55; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
56; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
57; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
58; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
59; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
60; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_min_max
61; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
62; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
63; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
64; CHECK-NEXT:  Loop %loop: Trip multiple is 1
65;
66entry:
67  %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
68  %ext = zext i32 %umin to i64
69  %min.iters.check = icmp ult i64 %ext, 4
70  br i1 %min.iters.check, label %exit, label %loop.ph
71
72loop.ph:
73  %n.vec = and i64 %ext, 28
74  br label %loop
75
76; %n.vec is [4, 16) and a multiple of 4.
77loop:
78  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
79  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
80  store i32 0, ptr %gep
81  %index.next = add nuw i64 %index, 4
82  %ec = icmp eq i64 %index.next, %n.vec
83  br i1 %ec, label %exit, label %loop
84
85exit:
86  ret i32 0
87}
88
89; This is same as rewrite_zext_min_max, but zext and umin are swapped.
90; It should be able to prove the same exit count.
91define i32 @rewrite_min_max_zext(i32 %N, ptr %arr) {
92; CHECK-LABEL: 'rewrite_min_max_zext'
93; CHECK-NEXT:  Classifying expressions for: @rewrite_min_max_zext
94; CHECK-NEXT:    %N.wide = zext i32 %N to i64
95; CHECK-NEXT:    --> (zext i32 %N to i64) U: [0,4294967296) S: [0,4294967296)
96; CHECK-NEXT:    %umin = call i64 @llvm.umin.i64(i64 %N.wide, i64 16)
97; CHECK-NEXT:    --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
98; CHECK-NEXT:    %n.vec = and i64 %umin, 28
99; CHECK-NEXT:    --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
100; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
101; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
102; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
103; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
104; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
105; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
106; CHECK-NEXT:  Determining loop execution counts for: @rewrite_min_max_zext
107; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
108; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
109; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
110; CHECK-NEXT:  Loop %loop: Trip multiple is 1
111;
112entry:
113  %N.wide = zext i32 %N to i64
114  %umin = call i64 @llvm.umin.i64(i64 %N.wide, i64 16)
115  %min.iters.check = icmp ult i64 %umin, 4
116  br i1 %min.iters.check, label %exit, label %loop.ph
117
118loop.ph:
119  %n.vec = and i64 %umin, 28
120  br label %loop
121
122; %n.vec is [4, 16) and a multiple of 4.
123loop:
124  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
125  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
126  store i32 0, ptr %gep
127  %index.next = add nuw i64 %index, 4
128  %ec = icmp eq i64 %index.next, %n.vec
129  br i1 %ec, label %exit, label %loop
130
131exit:
132  ret i32 0
133}
134
135; same as rewrite_zext_min_max, but everything is signed.
136; It should be able to prove the same exit count.
137define i32 @rewrite_sext_min_max(i32 %N, ptr %arr) {
138; CHECK-LABEL: 'rewrite_sext_min_max'
139; CHECK-NEXT:  Classifying expressions for: @rewrite_sext_min_max
140; CHECK-NEXT:    %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
141; CHECK-NEXT:    --> (16 smin %N) U: [-2147483648,17) S: [-2147483648,17)
142; CHECK-NEXT:    %ext = sext i32 %smin to i64
143; CHECK-NEXT:    --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
144; CHECK-NEXT:    %n.vec = and i64 %ext, 28
145; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
146; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
147; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
148; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
149; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
150; CHECK-NEXT:    %index.next = add nsw i64 %index, 4
151; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
152; CHECK-NEXT:  Determining loop execution counts for: @rewrite_sext_min_max
153; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
154; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
155; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
156; CHECK-NEXT:  Loop %loop: Trip multiple is 1
157;
158entry:
159  %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
160  %ext = sext i32 %smin to i64
161  %min.iters.check = icmp slt i64 %ext, 4
162  br i1 %min.iters.check, label %exit, label %loop.ph
163
164loop.ph:
165  %n.vec = and i64 %ext, 28
166  br label %loop
167
168; %n.vec is [4, 16) and a multiple of 4.
169loop:
170  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
171  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
172  store i32 0, ptr %gep
173  %index.next = add nsw i64 %index, 4
174  %ec = icmp eq i64 %index.next, %n.vec
175  br i1 %ec, label %exit, label %loop
176
177exit:
178  ret i32 0
179}
180
181; This is a signed version of rewrite_min_max_zext.
182; It should be able to prove the same exit count.
183define i32 @rewrite_min_max_sext(i32 %N, ptr %arr) {
184; CHECK-LABEL: 'rewrite_min_max_sext'
185; CHECK-NEXT:  Classifying expressions for: @rewrite_min_max_sext
186; CHECK-NEXT:    %N.wide = sext i32 %N to i64
187; CHECK-NEXT:    --> (sext i32 %N to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)
188; CHECK-NEXT:    %smin = call i64 @llvm.smin.i64(i64 %N.wide, i64 16)
189; CHECK-NEXT:    --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
190; CHECK-NEXT:    %n.vec = and i64 %smin, 28
191; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
192; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
193; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
194; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
195; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
196; CHECK-NEXT:    %index.next = add nsw i64 %index, 4
197; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
198; CHECK-NEXT:  Determining loop execution counts for: @rewrite_min_max_sext
199; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
200; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
201; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
202; CHECK-NEXT:  Loop %loop: Trip multiple is 1
203;
204entry:
205  %N.wide = sext i32 %N to i64
206  %smin = call i64 @llvm.smin.i64(i64 %N.wide, i64 16)
207  %min.iters.check = icmp slt i64 %smin, 4
208  br i1 %min.iters.check, label %exit, label %loop.ph
209
210loop.ph:
211  %n.vec = and i64 %smin, 28
212  br label %loop
213
214; %n.vec is [4, 16) and a multiple of 4.
215loop:
216  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
217  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
218  store i32 0, ptr %gep
219  %index.next = add nsw i64 %index, 4
220  %ec = icmp eq i64 %index.next, %n.vec
221  br i1 %ec, label %exit, label %loop
222
223exit:
224  ret i32 0
225}
226
227; Test case from PR52464. applyLoopGuards needs to apply information about %and
228; to %ext, which requires rewriting the zext.
229define i32 @rewrite_zext_with_info_from_icmp_ne(i32 %N) {
230; CHECK-LABEL: 'rewrite_zext_with_info_from_icmp_ne'
231; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_with_info_from_icmp_ne
232; CHECK-NEXT:    %and = and i32 %N, 3
233; CHECK-NEXT:    --> (zext i2 (trunc i32 %N to i2) to i32) U: [0,4) S: [0,4)
234; CHECK-NEXT:    %and.sub.1 = add nsw i32 %and, -1
235; CHECK-NEXT:    --> (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> U: [-1,3) S: [-1,3)
236; CHECK-NEXT:    %ext = zext i32 %and.sub.1 to i64
237; CHECK-NEXT:    --> (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64) U: [0,4294967296) S: [0,4294967296)
238; CHECK-NEXT:    %n.rnd.up = add nuw nsw i64 %ext, 4
239; CHECK-NEXT:    --> (4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> U: [4,4294967300) S: [4,4294967300)
240; CHECK-NEXT:    %n.vec = and i64 %n.rnd.up, 8589934588
241; CHECK-NEXT:    --> (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw> U: [4,4294967297) S: [4,4294967297)
242; CHECK-NEXT:    %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
243; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %loop: Computable }
244; CHECK-NEXT:    %iv.next = add i64 %iv, 4
245; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,5) S: [4,5) Exits: 4 LoopDispositions: { %loop: Computable }
246; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_with_info_from_icmp_ne
247; CHECK-NEXT:  Loop %loop: backedge-taken count is i64 0
248; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 0
249; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is i64 0
250; CHECK-NEXT:  Loop %loop: Trip multiple is 1
251;
252entry:
253  %and = and i32 %N, 3
254  %cmp6.not = icmp eq i32 %and, 0
255  br i1 %cmp6.not, label %exit, label %loop.ph
256
257loop.ph:
258  %and.sub.1 = add nsw i32 %and, -1
259  %ext = zext i32 %and.sub.1 to i64
260  %n.rnd.up = add nuw nsw i64 %ext, 4
261  %n.vec = and i64 %n.rnd.up, 8589934588
262  br label %loop
263
264loop:
265  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
266  %iv.next = add i64 %iv, 4
267  call void @use(i64 %iv.next)
268  %ec = icmp eq i64 %iv.next, %n.vec
269  br i1 %ec, label %exit, label %loop
270
271exit:
272  ret i32 0
273}
274
275; Similar to @rewrite_zext_with_info_from_icmp_ne, but the loop is not guarded by %and != 0,
276; hence the subsequent subtraction may yield a negative number.
277define i32 @rewrite_zext_no_icmp_ne(i32 %N) {
278; CHECK-LABEL: 'rewrite_zext_no_icmp_ne'
279; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_no_icmp_ne
280; CHECK-NEXT:    %and = and i32 %N, 3
281; CHECK-NEXT:    --> (zext i2 (trunc i32 %N to i2) to i32) U: [0,4) S: [0,4)
282; CHECK-NEXT:    %and.sub.1 = add nsw i32 %and, -1
283; CHECK-NEXT:    --> (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> U: [-1,3) S: [-1,3)
284; CHECK-NEXT:    %ext = zext i32 %and.sub.1 to i64
285; CHECK-NEXT:    --> (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64) U: [0,4294967296) S: [0,4294967296)
286; CHECK-NEXT:    %n.rnd.up = add nuw nsw i64 %ext, 4
287; CHECK-NEXT:    --> (4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> U: [4,4294967300) S: [4,4294967300)
288; CHECK-NEXT:    %n.vec = and i64 %n.rnd.up, 8589934588
289; CHECK-NEXT:    --> (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw> U: [4,4294967297) S: [4,4294967297)
290; CHECK-NEXT:    %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
291; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,4294967293) S: [0,4294967293) Exits: (4 * ((-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> /u 4))<nuw><nsw> LoopDispositions: { %loop: Computable }
292; CHECK-NEXT:    %iv.next = add i64 %iv, 4
293; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,4294967297) S: [4,4294967297) Exits: (4 + (4 * ((-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> /u 4))<nuw><nsw>)<nuw><nsw> LoopDispositions: { %loop: Computable }
294; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_no_icmp_ne
295; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> /u 4)
296; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 1073741823
297; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((4 + (zext i32 (-1 + (zext i2 (trunc i32 %N to i2) to i32))<nsw> to i64))<nuw><nsw> /u 4))<nuw><nsw>)<nsw> /u 4)
298; CHECK-NEXT:  Loop %loop: Trip multiple is 1
299;
300entry:
301  %and = and i32 %N, 3
302  br label %loop.ph
303
304loop.ph:
305  %and.sub.1 = add nsw i32 %and, -1
306  %ext = zext i32 %and.sub.1 to i64
307  %n.rnd.up = add nuw nsw i64 %ext, 4
308  %n.vec = and i64 %n.rnd.up, 8589934588
309  br label %loop
310
311loop:
312  %iv = phi i64 [ 0, %loop.ph ], [ %iv.next, %loop ]
313  %iv.next = add i64 %iv, 4
314  call void @use(i64 %iv.next)
315  %ec = icmp eq i64 %iv.next, %n.vec
316  br i1 %ec, label %exit, label %loop
317
318exit:
319  ret i32 0
320}
321
322; Make sure no information is lost for conditions on both %n and (zext %n).
323define void @rewrite_zext_and_base_1(i32 %n) {
324; CHECK-LABEL: 'rewrite_zext_and_base_1'
325; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_and_base_1
326; CHECK-NEXT:    %ext = zext i32 %n to i64
327; CHECK-NEXT:    --> (zext i32 %n to i64) U: [0,4294967296) S: [0,4294967296)
328; CHECK-NEXT:    %n.vec = and i64 %ext, -8
329; CHECK-NEXT:    --> (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> U: [0,4294967289) S: [0,4294967289)
330; CHECK-NEXT:    %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
331; CHECK-NEXT:    --> {0,+,8}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (8 * ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8))<nuw> LoopDispositions: { %loop: Computable }
332; CHECK-NEXT:    %index.next = add nuw nsw i64 %index, 8
333; CHECK-NEXT:    --> {8,+,8}<nuw><nsw><%loop> U: [8,33) S: [8,33) Exits: (8 + (8 * ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8))<nuw>) LoopDispositions: { %loop: Computable }
334; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_and_base_1
335; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
336; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
337; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
338; CHECK-NEXT:  Loop %loop: Trip multiple is 1
339;
340entry:
341  %ext = zext i32 %n to i64
342  %cmp5 = icmp ule i64 %ext, 48
343  br i1 %cmp5, label %check.1, label %exit
344
345check.1:
346  %cmp.2 = icmp ule i32 %n, 32
347  br i1 %cmp.2, label %check, label %exit
348
349
350check:                                 ; preds = %entry
351  %min.iters.check = icmp ult i64 %ext, 8
352  %n.vec = and i64 %ext, -8
353  br i1 %min.iters.check, label %exit, label %loop
354
355loop:
356  %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
357  %index.next = add nuw nsw i64 %index, 8
358  %ec = icmp eq i64 %index.next, %n.vec
359  br i1 %ec, label %exit, label %loop
360
361exit:
362  ret void
363}
364
365; Make sure no information is lost for conditions on both %n and (zext %n).
366define void @rewrite_zext_and_base_2(i32 %n) {
367; CHECK-LABEL: 'rewrite_zext_and_base_2'
368; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_and_base_2
369; CHECK-NEXT:    %ext = zext i32 %n to i64
370; CHECK-NEXT:    --> (zext i32 %n to i64) U: [0,4294967296) S: [0,4294967296)
371; CHECK-NEXT:    %n.vec = and i64 %ext, -8
372; CHECK-NEXT:    --> (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw> U: [0,4294967289) S: [0,4294967289)
373; CHECK-NEXT:    %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
374; CHECK-NEXT:    --> {0,+,8}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (8 * ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8))<nuw> LoopDispositions: { %loop: Computable }
375; CHECK-NEXT:    %index.next = add nuw nsw i64 %index, 8
376; CHECK-NEXT:    --> {8,+,8}<nuw><nsw><%loop> U: [8,33) S: [8,33) Exits: (8 + (8 * ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8))<nuw>) LoopDispositions: { %loop: Computable }
377; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_and_base_2
378; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
379; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
380; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * ((zext i32 %n to i64) /u 8))<nuw><nsw>)<nsw> /u 8)
381; CHECK-NEXT:  Loop %loop: Trip multiple is 1
382;
383entry:
384  %ext = zext i32 %n to i64
385  %cmp5 = icmp ule i64 %ext, 32
386  br i1 %cmp5, label %check.1, label %exit
387
388check.1:
389  %cmp.2 = icmp ule i32 %n, 48
390  br i1 %cmp.2, label %check, label %exit
391
392check:                                 ; preds = %entry
393  %min.iters.check = icmp ult i64 %ext, 8
394  %n.vec = and i64 %ext, -8
395  br i1 %min.iters.check, label %exit, label %loop
396
397loop:
398  %index = phi i64 [ 0, %check ], [ %index.next, %loop ]
399  %index.next = add nuw nsw i64 %index, 8
400  %ec = icmp eq i64 %index.next, %n.vec
401  br i1 %ec, label %exit, label %loop
402
403exit:
404  ret void
405}
406
407define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
408; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
409; CHECK-NEXT:  Classifying expressions for: @guard_pessimizes_analysis_step2
410; CHECK-NEXT:    %N.ext = zext i32 %N to i64
411; CHECK-NEXT:    --> (zext i32 %N to i64) U: [0,4294967296) S: [0,4294967296)
412; CHECK-NEXT:    %init = phi i64 [ 2, %entry ], [ 4, %bb1 ]
413; CHECK-NEXT:    --> %init U: [2,5) S: [2,5)
414; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %loop ], [ %init, %loop.ph ]
415; CHECK-NEXT:    --> {%init,+,2}<nuw><nsw><%loop> U: [2,17) S: [2,17) Exits: ((2 * ((14 + (-1 * %init)<nsw>)<nsw> /u 2))<nuw><nsw> + %init) LoopDispositions: { %loop: Computable }
416; CHECK-NEXT:    %iv.next = add i64 %iv, 2
417; CHECK-NEXT:    --> {(2 + %init)<nuw><nsw>,+,2}<nuw><nsw><%loop> U: [4,19) S: [4,19) Exits: (2 + (2 * ((14 + (-1 * %init)<nsw>)<nsw> /u 2))<nuw><nsw> + %init) LoopDispositions: { %loop: Computable }
418; CHECK-NEXT:  Determining loop execution counts for: @guard_pessimizes_analysis_step2
419; CHECK-NEXT:  Loop %loop: backedge-taken count is ((14 + (-1 * %init)<nsw>)<nsw> /u 2)
420; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 6
421; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((14 + (-1 * %init)<nsw>)<nsw> /u 2)
422; CHECK-NEXT:  Loop %loop: Trip multiple is 1
423;
424entry:
425  %N.ext = zext i32 %N to i64
426  br i1 %c, label %bb1, label %guard
427
428bb1:
429  br label %guard
430
431guard:
432  %init = phi i64 [ 2, %entry ], [ 4, %bb1 ]
433  %c.1 = icmp ult i64 %init, %N.ext
434  br i1 %c.1, label %loop.ph, label %exit
435
436loop.ph:
437  br label %loop
438
439loop:
440  %iv = phi i64 [ %iv.next, %loop ], [ %init, %loop.ph ]
441  %iv.next = add i64 %iv, 2
442  %exitcond = icmp eq i64 %iv.next, 16
443  br i1 %exitcond, label %exit, label %loop
444
445exit:
446  ret void
447}
448
449define i32 @rewrite_sext_slt_narrow_check(i32 %N, ptr %arr) {
450; CHECK-LABEL: 'rewrite_sext_slt_narrow_check'
451; CHECK-NEXT:  Classifying expressions for: @rewrite_sext_slt_narrow_check
452; CHECK-NEXT:    %smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
453; CHECK-NEXT:    --> (4 smax %N) U: [4,-2147483648) S: [4,-2147483648)
454; CHECK-NEXT:    %ext = sext i32 %smin to i64
455; CHECK-NEXT:    --> (zext i32 (4 smax %N) to i64) U: [4,2147483648) S: [4,2147483648)
456; CHECK-NEXT:    %n.vec = and i64 %ext, 28
457; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
458; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
459; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
460; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
461; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
462; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
463; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
464; CHECK-NEXT:  Determining loop execution counts for: @rewrite_sext_slt_narrow_check
465; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
466; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
467; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
468; CHECK-NEXT:  Loop %loop: Trip multiple is 1
469;
470entry:
471  %smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
472  %ext = sext i32 %smin to i64
473  %min.iters.check = icmp slt i32 %smin, 17
474  br i1 %min.iters.check, label %loop.ph, label %exit
475
476loop.ph:
477  %n.vec = and i64 %ext, 28
478  br label %loop
479
480; %n.vec is [4, 16] and a multiple of 4.
481loop:
482  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
483  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
484  store i32 0, ptr %gep
485  %index.next = add nuw i64 %index, 4
486  %ec = icmp eq i64 %index.next, %n.vec
487  br i1 %ec, label %exit, label %loop
488
489exit:
490  ret i32 0
491}
492
493define i32 @rewrite_zext_ult_narrow_check(i32 %N, ptr %arr) {
494; CHECK-LABEL: 'rewrite_zext_ult_narrow_check'
495; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_ult_narrow_check
496; CHECK-NEXT:    %umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
497; CHECK-NEXT:    --> (4 umax %N) U: [4,0) S: [4,0)
498; CHECK-NEXT:    %ext = zext i32 %umin to i64
499; CHECK-NEXT:    --> (4 umax (zext i32 %N to i64)) U: [4,4294967296) S: [4,4294967296)
500; CHECK-NEXT:    %n.vec = and i64 %ext, 28
501; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
502; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
503; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
504; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
505; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
506; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
507; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
508; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_ult_narrow_check
509; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
510; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
511; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
512; CHECK-NEXT:  Loop %loop: Trip multiple is 1
513;
514entry:
515  %umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
516  %ext = zext i32 %umin to i64
517  %min.iters.check = icmp ult i32 %umin, 17
518  br i1 %min.iters.check, label %loop.ph, label %exit
519
520loop.ph:
521  %n.vec = and i64 %ext, 28
522  br label %loop
523
524; %n.vec is [4, 16] and a multiple of 4.
525loop:
526  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
527  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
528  store i32 0, ptr %gep
529  %index.next = add nuw i64 %index, 4
530  %ec = icmp eq i64 %index.next, %n.vec
531  br i1 %ec, label %exit, label %loop
532
533exit:
534  ret i32 0
535}
536
537define i32 @rewrite_zext_ule_narrow_check(i32 %N, ptr %arr) {
538; CHECK-LABEL: 'rewrite_zext_ule_narrow_check'
539; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_ule_narrow_check
540; CHECK-NEXT:    %umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
541; CHECK-NEXT:    --> (4 umax %N) U: [4,0) S: [4,0)
542; CHECK-NEXT:    %ext = zext i32 %umin to i64
543; CHECK-NEXT:    --> (4 umax (zext i32 %N to i64)) U: [4,4294967296) S: [4,4294967296)
544; CHECK-NEXT:    %n.vec = and i64 %ext, 28
545; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
546; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
547; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
548; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
549; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
550; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
551; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
552; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_ule_narrow_check
553; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
554; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
555; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((4 umax (zext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
556; CHECK-NEXT:  Loop %loop: Trip multiple is 1
557;
558entry:
559  %umin = call i32 @llvm.umax.i32(i32 %N, i32 4)
560  %ext = zext i32 %umin to i64
561  %min.iters.check = icmp ule i32 %umin, 16
562  br i1 %min.iters.check, label %loop.ph, label %exit
563
564loop.ph:
565  %n.vec = and i64 %ext, 28
566  br label %loop
567
568; %n.vec is [4, 16] and a multiple of 4.
569loop:
570  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
571  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
572  store i32 0, ptr %gep
573  %index.next = add nuw i64 %index, 4
574  %ec = icmp eq i64 %index.next, %n.vec
575  br i1 %ec, label %exit, label %loop
576
577exit:
578  ret i32 0
579}
580
581define i32 @rewrite_zext_sle_narrow_check(i32 %N, ptr %arr) {
582; CHECK-LABEL: 'rewrite_zext_sle_narrow_check'
583; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_sle_narrow_check
584; CHECK-NEXT:    %smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
585; CHECK-NEXT:    --> (4 smax %N) U: [4,-2147483648) S: [4,-2147483648)
586; CHECK-NEXT:    %ext = sext i32 %smin to i64
587; CHECK-NEXT:    --> (zext i32 (4 smax %N) to i64) U: [4,2147483648) S: [4,2147483648)
588; CHECK-NEXT:    %n.vec = and i64 %ext, 28
589; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
590; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
591; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
592; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
593; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
594; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
595; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
596; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_sle_narrow_check
597; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
598; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
599; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((zext i32 (4 smax %N) to i64) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
600; CHECK-NEXT:  Loop %loop: Trip multiple is 1
601;
602entry:
603  %smin = call i32 @llvm.smax.i32(i32 %N, i32 4)
604  %ext = sext i32 %smin to i64
605  %min.iters.check = icmp sle i32 %smin, 17
606  br i1 %min.iters.check, label %loop.ph, label %exit
607
608loop.ph:
609  %n.vec = and i64 %ext, 28
610  br label %loop
611
612; %n.vec is [4, 16] and a multiple of 4.
613loop:
614  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
615  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
616  store i32 0, ptr %gep
617  %index.next = add nuw i64 %index, 4
618  %ec = icmp eq i64 %index.next, %n.vec
619  br i1 %ec, label %exit, label %loop
620
621exit:
622  ret i32 0
623}
624
625define i32 @rewrite_zext_uge_narrow_check(i32 %N, ptr %arr) {
626; CHECK-LABEL: 'rewrite_zext_uge_narrow_check'
627; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_uge_narrow_check
628; CHECK-NEXT:    %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
629; CHECK-NEXT:    --> (16 umin %N) U: [0,17) S: [0,17)
630; CHECK-NEXT:    %ext = zext i32 %umin to i64
631; CHECK-NEXT:    --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
632; CHECK-NEXT:    %n.vec = and i64 %ext, 28
633; CHECK-NEXT:    --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
634; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
635; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
636; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
637; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
638; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
639; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
640; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_uge_narrow_check
641; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
642; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
643; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
644; CHECK-NEXT:  Loop %loop: Trip multiple is 1
645;
646entry:
647  %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
648  %ext = zext i32 %umin to i64
649  %min.iters.check = icmp uge i32 %umin, 4
650  br i1 %min.iters.check, label %loop.ph, label %exit
651
652loop.ph:
653  %n.vec = and i64 %ext, 28
654  br label %loop
655
656; %n.vec is [4, 16] and a multiple of 4.
657loop:
658  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
659  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
660  store i32 0, ptr %gep
661  %index.next = add nuw i64 %index, 4
662  %ec = icmp eq i64 %index.next, %n.vec
663  br i1 %ec, label %exit, label %loop
664
665exit:
666  ret i32 0
667}
668
669define i32 @rewrite_sext_sge_narrow_check(i32 %N, ptr %arr) {
670; CHECK-LABEL: 'rewrite_sext_sge_narrow_check'
671; CHECK-NEXT:  Classifying expressions for: @rewrite_sext_sge_narrow_check
672; CHECK-NEXT:    %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
673; CHECK-NEXT:    --> (16 smin %N) U: [-2147483648,17) S: [-2147483648,17)
674; CHECK-NEXT:    %ext = sext i32 %smin to i64
675; CHECK-NEXT:    --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
676; CHECK-NEXT:    %n.vec = and i64 %ext, 28
677; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
678; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
679; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
680; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
681; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
682; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
683; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
684; CHECK-NEXT:  Determining loop execution counts for: @rewrite_sext_sge_narrow_check
685; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
686; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
687; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
688; CHECK-NEXT:  Loop %loop: Trip multiple is 1
689;
690entry:
691  %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
692  %ext = sext i32 %smin to i64
693  %min.iters.check = icmp sge i32 %smin, 4
694  br i1 %min.iters.check, label %loop.ph, label %exit
695
696loop.ph:
697  %n.vec = and i64 %ext, 28
698  br label %loop
699
700; %n.vec is [4, 16] and a multiple of 4.
701loop:
702  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
703  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
704  store i32 0, ptr %gep
705  %index.next = add nuw i64 %index, 4
706  %ec = icmp eq i64 %index.next, %n.vec
707  br i1 %ec, label %exit, label %loop
708
709exit:
710  ret i32 0
711}
712
713define i32 @rewrite_zext_ugt_narrow_check(i32 %N, ptr %arr) {
714; CHECK-LABEL: 'rewrite_zext_ugt_narrow_check'
715; CHECK-NEXT:  Classifying expressions for: @rewrite_zext_ugt_narrow_check
716; CHECK-NEXT:    %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
717; CHECK-NEXT:    --> (16 umin %N) U: [0,17) S: [0,17)
718; CHECK-NEXT:    %ext = zext i32 %umin to i64
719; CHECK-NEXT:    --> (16 umin (zext i32 %N to i64)) U: [0,17) S: [0,17)
720; CHECK-NEXT:    %n.vec = and i64 %ext, 28
721; CHECK-NEXT:    --> (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw> U: [0,17) S: [0,17)
722; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
723; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
724; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
725; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
726; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
727; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
728; CHECK-NEXT:  Determining loop execution counts for: @rewrite_zext_ugt_narrow_check
729; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
730; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
731; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * ((16 umin (zext i32 %N to i64)) /u 4))<nuw><nsw>)<nsw> /u 4)
732; CHECK-NEXT:  Loop %loop: Trip multiple is 1
733;
734entry:
735  %umin = call i32 @llvm.umin.i32(i32 %N, i32 16)
736  %ext = zext i32 %umin to i64
737  %min.iters.check = icmp ugt i32 %umin, 3
738  br i1 %min.iters.check, label %loop.ph, label %exit
739
740loop.ph:
741  %n.vec = and i64 %ext, 28
742  br label %loop
743
744; %n.vec is [4, 16] and a multiple of 4.
745loop:
746  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
747  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
748  store i32 0, ptr %gep
749  %index.next = add nuw i64 %index, 4
750  %ec = icmp eq i64 %index.next, %n.vec
751  br i1 %ec, label %exit, label %loop
752
753exit:
754  ret i32 0
755}
756
757define i32 @rewrite_sext_sgt_narrow_check(i32 %N, ptr %arr) {
758; CHECK-LABEL: 'rewrite_sext_sgt_narrow_check'
759; CHECK-NEXT:  Classifying expressions for: @rewrite_sext_sgt_narrow_check
760; CHECK-NEXT:    %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
761; CHECK-NEXT:    --> (16 smin %N) U: [-2147483648,17) S: [-2147483648,17)
762; CHECK-NEXT:    %ext = sext i32 %smin to i64
763; CHECK-NEXT:    --> (16 smin (sext i32 %N to i64)) U: [-2147483648,17) S: [-2147483648,17)
764; CHECK-NEXT:    %n.vec = and i64 %ext, 28
765; CHECK-NEXT:    --> (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw> U: [0,29) S: [0,29)
766; CHECK-NEXT:    %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
767; CHECK-NEXT:    --> {0,+,4}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw> LoopDispositions: { %loop: Computable }
768; CHECK-NEXT:    %gep = getelementptr inbounds i32, ptr %arr, i64 %index
769; CHECK-NEXT:    --> {%arr,+,16}<nuw><%loop> U: full-set S: full-set Exits: ((16 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)) + %arr) LoopDispositions: { %loop: Computable }
770; CHECK-NEXT:    %index.next = add nuw i64 %index, 4
771; CHECK-NEXT:    --> {4,+,4}<nuw><nsw><%loop> U: [4,17) S: [4,17) Exits: (4 + (4 * ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4))<nuw>) LoopDispositions: { %loop: Computable }
772; CHECK-NEXT:  Determining loop execution counts for: @rewrite_sext_sgt_narrow_check
773; CHECK-NEXT:  Loop %loop: backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
774; CHECK-NEXT:  Loop %loop: constant max backedge-taken count is i64 3
775; CHECK-NEXT:  Loop %loop: symbolic max backedge-taken count is ((-4 + (4 * (zext i3 (trunc i64 ((16 smin (sext i32 %N to i64)) /u 4) to i3) to i64))<nuw><nsw>)<nsw> /u 4)
776; CHECK-NEXT:  Loop %loop: Trip multiple is 1
777;
778entry:
779  %smin = call i32 @llvm.smin.i32(i32 %N, i32 16)
780  %ext = sext i32 %smin to i64
781  %min.iters.check = icmp sgt i32 %smin, 3
782  br i1 %min.iters.check, label %loop.ph, label %exit
783
784loop.ph:
785  %n.vec = and i64 %ext, 28
786  br label %loop
787
788; %n.vec is [4, 16) and a multiple of 4.
789loop:
790  %index = phi i64 [ 0, %loop.ph ], [ %index.next, %loop ]
791  %gep = getelementptr inbounds i32, ptr %arr, i64 %index
792  store i32 0, ptr %gep
793  %index.next = add nuw i64 %index, 4
794  %ec = icmp eq i64 %index.next, %n.vec
795  br i1 %ec, label %exit, label %loop
796
797exit:
798  ret i32 0
799}
800
801declare void @use(i64)
802
803declare i32 @llvm.umin.i32(i32, i32)
804declare i64 @llvm.umin.i64(i64, i64)
805declare i32 @llvm.smin.i32(i32, i32)
806declare i64 @llvm.smin.i64(i64, i64)
807
808declare i32 @llvm.umax.i32(i32, i32)
809declare i32 @llvm.smax.i32(i32, i32)
810