xref: /llvm-project/llvm/test/Analysis/ScalarEvolution/trip-multiple.ll (revision 8b5b294ec2cf876bc5eb5bd5fcb56ef487e36d60)
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2; RUN: opt -passes='print<scalar-evolution>,verify<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
3
4; Test trip multiples with functions that look like:
5
6; void foo();
7; void square(unsigned num) {
8;     if (num % 5 == 0)
9;     for (unsigned i = 0; i < num; ++i)
10;         foo();
11; }
12
13declare void @foo(...)
14
15define void @trip_multiple_3(i32 noundef %num) {
16; CHECK-LABEL: 'trip_multiple_3'
17; CHECK-NEXT:  Classifying expressions for: @trip_multiple_3
18; CHECK-NEXT:    %rem = urem i32 %num, 3
19; CHECK-NEXT:    --> ((-3 * (%num /u 3)) + %num) U: full-set S: full-set
20; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
21; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
22; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
23; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-1) S: [0,-1) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
24; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
25; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: %num LoopDispositions: { %for.body: Computable }
26; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_3
27; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
28; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -2
29; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
30; CHECK-NEXT:  Loop %for.body: Trip multiple is 3
31;
32entry:
33  %rem = urem i32 %num, 3
34  %cmp = icmp eq i32 %rem, 0
35  %cmp14 = icmp ne i32 %num, 0
36  %or.cond = and i1 %cmp, %cmp14
37  br i1 %or.cond, label %for.body, label %if.end
38
39for.body:                                         ; preds = %entry, %for.body
40  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
41  tail call void (...) @foo() #2
42  %inc = add nuw i32 %i.05, 1
43  %exitcond.not = icmp eq i32 %inc, %num
44  br i1 %exitcond.not, label %if.end, label %for.body
45
46if.end:                                           ; preds = %for.body, %entry
47  ret void
48}
49define void @trip_multiple_4(i32 noundef %num) {
50; CHECK-LABEL: 'trip_multiple_4'
51; CHECK-NEXT:  Classifying expressions for: @trip_multiple_4
52; CHECK-NEXT:    %rem = urem i32 %num, 4
53; CHECK-NEXT:    --> (zext i2 (trunc i32 %num to i2) to i32) U: [0,4) S: [0,4)
54; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
55; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
56; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
57; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-4) S: [0,-4) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
58; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
59; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,-3) S: [1,-3) Exits: %num LoopDispositions: { %for.body: Computable }
60; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_4
61; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
62; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -5
63; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
64; CHECK-NEXT:  Loop %for.body: Trip multiple is 4
65;
66entry:
67  %rem = urem i32 %num, 4
68  %cmp = icmp eq i32 %rem, 0
69  %cmp14 = icmp ne i32 %num, 0
70  %or.cond = and i1 %cmp, %cmp14
71  br i1 %or.cond, label %for.body, label %if.end
72
73for.body:                                         ; preds = %entry, %for.body
74  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
75  tail call void (...) @foo() #2
76  %inc = add nuw i32 %i.05, 1
77  %exitcond.not = icmp eq i32 %inc, %num
78  br i1 %exitcond.not, label %if.end, label %for.body
79
80if.end:                                           ; preds = %for.body, %entry
81  ret void
82}
83
84define void @trip_multiple_5(i32 noundef %num) {
85; CHECK-LABEL: 'trip_multiple_5'
86; CHECK-NEXT:  Classifying expressions for: @trip_multiple_5
87; CHECK-NEXT:    %rem = urem i32 %num, 5
88; CHECK-NEXT:    --> ((-5 * (%num /u 5)) + %num) U: full-set S: full-set
89; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
90; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
91; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
92; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-1) S: [0,-1) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
93; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
94; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,0) S: [1,0) Exits: %num LoopDispositions: { %for.body: Computable }
95; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_5
96; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
97; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -2
98; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
99; CHECK-NEXT:  Loop %for.body: Trip multiple is 5
100;
101entry:
102  %rem = urem i32 %num, 5
103  %cmp = icmp eq i32 %rem, 0
104  %cmp14 = icmp ne i32 %num, 0
105  %or.cond = and i1 %cmp, %cmp14
106  br i1 %or.cond, label %for.body, label %if.end
107
108for.body:                                         ; preds = %entry, %for.body
109  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
110  tail call void (...) @foo() #2
111  %inc = add nuw i32 %i.05, 1
112  %exitcond.not = icmp eq i32 %inc, %num
113  br i1 %exitcond.not, label %if.end, label %for.body
114
115if.end:                                           ; preds = %for.body, %entry
116  ret void
117}
118
119define void @trip_multiple_6(i32 noundef %num) {
120; CHECK-LABEL: 'trip_multiple_6'
121; CHECK-NEXT:  Classifying expressions for: @trip_multiple_6
122; CHECK-NEXT:    %rem = urem i32 %num, 6
123; CHECK-NEXT:    --> ((-6 * (%num /u 6)) + %num) U: full-set S: full-set
124; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
125; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
126; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
127; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-4) S: [0,-4) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
128; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
129; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,-3) S: [1,-3) Exits: %num LoopDispositions: { %for.body: Computable }
130; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_6
131; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
132; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -5
133; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
134; CHECK-NEXT:  Loop %for.body: Trip multiple is 6
135;
136entry:
137  %rem = urem i32 %num, 6
138  %cmp = icmp eq i32 %rem, 0
139  %cmp14 = icmp ne i32 %num, 0
140  %or.cond = and i1 %cmp, %cmp14
141  br i1 %or.cond, label %for.body, label %if.end
142
143for.body:                                         ; preds = %entry, %for.body
144  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
145  tail call void (...) @foo() #2
146  %inc = add nuw i32 %i.05, 1
147  %exitcond.not = icmp eq i32 %inc, %num
148  br i1 %exitcond.not, label %if.end, label %for.body
149
150if.end:                                           ; preds = %for.body, %entry
151  ret void
152}
153
154define void @trip_multiple_7(i32 noundef %num) {
155; CHECK-LABEL: 'trip_multiple_7'
156; CHECK-NEXT:  Classifying expressions for: @trip_multiple_7
157; CHECK-NEXT:    %rem = urem i32 %num, 7
158; CHECK-NEXT:    --> ((-7 * (%num /u 7)) + %num) U: full-set S: full-set
159; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
160; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
161; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
162; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-4) S: [0,-4) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
163; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
164; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,-3) S: [1,-3) Exits: %num LoopDispositions: { %for.body: Computable }
165; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_7
166; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
167; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -5
168; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
169; CHECK-NEXT:  Loop %for.body: Trip multiple is 7
170;
171entry:
172  %rem = urem i32 %num, 7
173  %cmp = icmp eq i32 %rem, 0
174  %cmp14 = icmp ne i32 %num, 0
175  %or.cond = and i1 %cmp, %cmp14
176  br i1 %or.cond, label %for.body, label %if.end
177
178for.body:                                         ; preds = %entry, %for.body
179  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
180  tail call void (...) @foo() #2
181  %inc = add nuw i32 %i.05, 1
182  %exitcond.not = icmp eq i32 %inc, %num
183  br i1 %exitcond.not, label %if.end, label %for.body
184
185if.end:                                           ; preds = %for.body, %entry
186  ret void
187}
188
189define void @trip_multiple_8(i32 noundef %num) {
190; CHECK-LABEL: 'trip_multiple_8'
191; CHECK-NEXT:  Classifying expressions for: @trip_multiple_8
192; CHECK-NEXT:    %rem = urem i32 %num, 8
193; CHECK-NEXT:    --> (zext i3 (trunc i32 %num to i3) to i32) U: [0,8) S: [0,8)
194; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
195; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
196; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
197; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-8) S: [0,-8) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
198; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
199; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,-7) S: [1,-7) Exits: %num LoopDispositions: { %for.body: Computable }
200; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_8
201; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
202; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -9
203; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
204; CHECK-NEXT:  Loop %for.body: Trip multiple is 8
205;
206entry:
207  %rem = urem i32 %num, 8
208  %cmp = icmp eq i32 %rem, 0
209  %cmp14 = icmp ne i32 %num, 0
210  %or.cond = and i1 %cmp, %cmp14
211  br i1 %or.cond, label %for.body, label %if.end
212
213for.body:                                         ; preds = %entry, %for.body
214  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
215  tail call void (...) @foo() #2
216  %inc = add nuw i32 %i.05, 1
217  %exitcond.not = icmp eq i32 %inc, %num
218  br i1 %exitcond.not, label %if.end, label %for.body
219
220if.end:                                           ; preds = %for.body, %entry
221  ret void
222}
223define void @trip_multiple_9(i32 noundef %num) {
224; CHECK-LABEL: 'trip_multiple_9'
225; CHECK-NEXT:  Classifying expressions for: @trip_multiple_9
226; CHECK-NEXT:    %rem = urem i32 %num, 9
227; CHECK-NEXT:    --> ((-9 * (%num /u 9)) + %num) U: full-set S: full-set
228; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
229; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
230; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
231; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-4) S: [0,-4) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
232; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
233; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,-3) S: [1,-3) Exits: %num LoopDispositions: { %for.body: Computable }
234; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_9
235; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
236; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -5
237; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
238; CHECK-NEXT:  Loop %for.body: Trip multiple is 9
239;
240entry:
241  %rem = urem i32 %num, 9
242  %cmp = icmp eq i32 %rem, 0
243  %cmp14 = icmp ne i32 %num, 0
244  %or.cond = and i1 %cmp, %cmp14
245  br i1 %or.cond, label %for.body, label %if.end
246
247for.body:                                         ; preds = %entry, %for.body
248  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
249  tail call void (...) @foo() #2
250  %inc = add nuw i32 %i.05, 1
251  %exitcond.not = icmp eq i32 %inc, %num
252  br i1 %exitcond.not, label %if.end, label %for.body
253
254if.end:                                           ; preds = %for.body, %entry
255  ret void
256}
257define void @trip_multiple_10(i32 noundef %num) {
258; CHECK-LABEL: 'trip_multiple_10'
259; CHECK-NEXT:  Classifying expressions for: @trip_multiple_10
260; CHECK-NEXT:    %rem = urem i32 %num, 10
261; CHECK-NEXT:    --> ((-10 * (%num /u 10)) + %num) U: full-set S: full-set
262; CHECK-NEXT:    %or.cond = and i1 %cmp, %cmp14
263; CHECK-NEXT:    --> (%cmp14 umin %cmp) U: full-set S: full-set
264; CHECK-NEXT:    %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
265; CHECK-NEXT:    --> {0,+,1}<nuw><%for.body> U: [0,-6) S: [0,-6) Exits: (-1 + %num) LoopDispositions: { %for.body: Computable }
266; CHECK-NEXT:    %inc = add nuw i32 %i.05, 1
267; CHECK-NEXT:    --> {1,+,1}<nuw><%for.body> U: [1,-5) S: [1,-5) Exits: %num LoopDispositions: { %for.body: Computable }
268; CHECK-NEXT:  Determining loop execution counts for: @trip_multiple_10
269; CHECK-NEXT:  Loop %for.body: backedge-taken count is (-1 + %num)
270; CHECK-NEXT:  Loop %for.body: constant max backedge-taken count is i32 -7
271; CHECK-NEXT:  Loop %for.body: symbolic max backedge-taken count is (-1 + %num)
272; CHECK-NEXT:  Loop %for.body: Trip multiple is 10
273;
274entry:
275  %rem = urem i32 %num, 10
276  %cmp = icmp eq i32 %rem, 0
277  %cmp14 = icmp ne i32 %num, 0
278  %or.cond = and i1 %cmp, %cmp14
279  br i1 %or.cond, label %for.body, label %if.end
280
281for.body:                                         ; preds = %entry, %for.body
282  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
283  tail call void (...) @foo() #2
284  %inc = add nuw i32 %i.05, 1
285  %exitcond.not = icmp eq i32 %inc, %num
286  br i1 %exitcond.not, label %if.end, label %for.body
287
288if.end:                                           ; preds = %for.body, %entry
289  ret void
290}
291