xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/monotonic-int-phis-multiples.ll (revision f8122518750e3563a79df22d72c26c3c922f63f2)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -S -passes=constraint-elimination < %s | FileCheck %s
3
4define void @multiple_pow2(i64 %count) {
5; CHECK-LABEL: define void @multiple_pow2(
6; CHECK-SAME: i64 [[COUNT:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[END:%.*]] = shl i64 [[COUNT]], 2
9; CHECK-NEXT:    br label [[LOOP:%.*]]
10; CHECK:       loop:
11; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
12; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 4
13; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
14; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
15; CHECK:       loop.latch:
16; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT]]
17; CHECK:       exit:
18; CHECK-NEXT:    ret void
19;
20entry:
21  %end = shl i64 %count, 2
22  br label %loop
23
24loop:
25  %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ]
26  %iv.next = add i64 %iv, 4
27  %cmp.i.not = icmp eq i64 %iv, %end
28  br i1 %cmp.i.not, label %exit, label %loop.latch
29
30loop.latch:
31  %cmp2.i.i = icmp ult i64 %iv, %end
32  br i1 %cmp2.i.i, label %loop, label %exit
33
34exit:
35  ret void
36}
37
38define void @multiple_pow2_larger_than_needed(i64 %count) {
39; CHECK-LABEL: define void @multiple_pow2_larger_than_needed(
40; CHECK-SAME: i64 [[COUNT:%.*]]) {
41; CHECK-NEXT:  entry:
42; CHECK-NEXT:    [[END:%.*]] = shl i64 [[COUNT]], 3
43; CHECK-NEXT:    br label [[LOOP:%.*]]
44; CHECK:       loop:
45; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
46; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 4
47; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
48; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
49; CHECK:       loop.latch:
50; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT]]
51; CHECK:       exit:
52; CHECK-NEXT:    ret void
53;
54entry:
55  %end = shl i64 %count, 3
56  br label %loop
57
58loop:
59  %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ]
60  %iv.next = add i64 %iv, 4
61  %cmp.i.not = icmp eq i64 %iv, %end
62  br i1 %cmp.i.not, label %exit, label %loop.latch
63
64loop.latch:
65  %cmp2.i.i = icmp ult i64 %iv, %end
66  br i1 %cmp2.i.i, label %loop, label %exit
67
68exit:
69  ret void
70}
71
72define void @multiple_pow2_too_small(i64 %count) {
73; CHECK-LABEL: define void @multiple_pow2_too_small(
74; CHECK-SAME: i64 [[COUNT:%.*]]) {
75; CHECK-NEXT:  entry:
76; CHECK-NEXT:    [[END:%.*]] = shl i64 [[COUNT]], 1
77; CHECK-NEXT:    br label [[LOOP:%.*]]
78; CHECK:       loop:
79; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
80; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 4
81; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
82; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
83; CHECK:       loop.latch:
84; CHECK-NEXT:    [[CMP2_I_I:%.*]] = icmp ult i64 [[IV]], [[END]]
85; CHECK-NEXT:    br i1 [[CMP2_I_I]], label [[LOOP]], label [[EXIT]]
86; CHECK:       exit:
87; CHECK-NEXT:    ret void
88;
89entry:
90  %end = shl i64 %count, 1
91  br label %loop
92
93loop:
94  %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ]
95  %iv.next = add i64 %iv, 4
96  %cmp.i.not = icmp eq i64 %iv, %end
97  br i1 %cmp.i.not, label %exit, label %loop.latch
98
99loop.latch:
100  %cmp2.i.i = icmp ult i64 %iv, %end
101  br i1 %cmp2.i.i, label %loop, label %exit
102
103exit:
104  ret void
105}
106
107define void @multiple_pow2_start_offset(i64 %count) {
108; CHECK-LABEL: define void @multiple_pow2_start_offset(
109; CHECK-SAME: i64 [[COUNT:%.*]]) {
110; CHECK-NEXT:  entry:
111; CHECK-NEXT:    [[END:%.*]] = shl i64 [[COUNT]], 2
112; CHECK-NEXT:    [[PRECOND:%.*]] = icmp ugt i64 [[END]], 4
113; CHECK-NEXT:    br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]]
114; CHECK:       loop:
115; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 4, [[ENTRY:%.*]] ]
116; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 4
117; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
118; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
119; CHECK:       loop.latch:
120; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT]]
121; CHECK:       exit:
122; CHECK-NEXT:    ret void
123;
124entry:
125  %end = shl i64 %count, 2
126  %precond = icmp ugt i64 %end, 4
127  br i1 %precond, label %loop, label %exit
128
129loop:
130  %iv = phi i64 [ %iv.next, %loop.latch ], [ 4, %entry ]
131  %iv.next = add i64 %iv, 4
132  %cmp.i.not = icmp eq i64 %iv, %end
133  br i1 %cmp.i.not, label %exit, label %loop.latch
134
135loop.latch:
136  %cmp2.i.i = icmp ult i64 %iv, %end
137  br i1 %cmp2.i.i, label %loop, label %exit
138
139exit:
140  ret void
141}
142
143define void @multiple_pow2_wrong_start_offset(i64 %count) {
144; CHECK-LABEL: define void @multiple_pow2_wrong_start_offset(
145; CHECK-SAME: i64 [[COUNT:%.*]]) {
146; CHECK-NEXT:  entry:
147; CHECK-NEXT:    [[END:%.*]] = shl i64 [[COUNT]], 2
148; CHECK-NEXT:    [[PRECOND:%.*]] = icmp ugt i64 [[END]], 1
149; CHECK-NEXT:    br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]]
150; CHECK:       loop:
151; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 1, [[ENTRY:%.*]] ]
152; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 4
153; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
154; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
155; CHECK:       loop.latch:
156; CHECK-NEXT:    [[CMP2_I_I:%.*]] = icmp ult i64 [[IV]], [[END]]
157; CHECK-NEXT:    br i1 [[CMP2_I_I]], label [[LOOP]], label [[EXIT]]
158; CHECK:       exit:
159; CHECK-NEXT:    ret void
160;
161entry:
162  %end = shl i64 %count, 2
163  %precond = icmp ugt i64 %end, 1
164  br i1 %precond, label %loop, label %exit
165
166loop:
167  %iv = phi i64 [ %iv.next, %loop.latch ], [ 1, %entry ]
168  %iv.next = add i64 %iv, 4
169  %cmp.i.not = icmp eq i64 %iv, %end
170  br i1 %cmp.i.not, label %exit, label %loop.latch
171
172loop.latch:
173  %cmp2.i.i = icmp ult i64 %iv, %end
174  br i1 %cmp2.i.i, label %loop, label %exit
175
176exit:
177  ret void
178}
179
180define void @multiple_pow2_start_offset_dynamic(i64 %count) {
181; CHECK-LABEL: define void @multiple_pow2_start_offset_dynamic(
182; CHECK-SAME: i64 [[COUNT:%.*]]) {
183; CHECK-NEXT:  entry:
184; CHECK-NEXT:    [[SHL:%.*]] = shl i64 [[COUNT]], 2
185; CHECK-NEXT:    [[END:%.*]] = add i64 [[SHL]], 1
186; CHECK-NEXT:    [[PRECOND:%.*]] = icmp ne i64 [[END]], 0
187; CHECK-NEXT:    br i1 [[PRECOND]], label [[LOOP:%.*]], label [[EXIT:%.*]]
188; CHECK:       loop:
189; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 1, [[ENTRY:%.*]] ]
190; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 4
191; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
192; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT]], label [[LOOP_LATCH]]
193; CHECK:       loop.latch:
194; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT]]
195; CHECK:       exit:
196; CHECK-NEXT:    ret void
197;
198entry:
199  %shl = shl i64 %count, 2
200  %end = add i64 %shl, 1
201  %precond = icmp ne i64 %end, 0
202  br i1 %precond, label %loop, label %exit
203
204loop:
205  %iv = phi i64 [ %iv.next, %loop.latch ], [ 1, %entry ]
206  %iv.next = add i64 %iv, 4
207  %cmp.i.not = icmp eq i64 %iv, %end
208  br i1 %cmp.i.not, label %exit, label %loop.latch
209
210loop.latch:
211  %cmp2.i.i = icmp ult i64 %iv, %end
212  br i1 %cmp2.i.i, label %loop, label %exit
213
214exit:
215  ret void
216}
217
218define void @multiple_non_pow2_nuw(i64 %count) {
219; CHECK-LABEL: define void @multiple_non_pow2_nuw(
220; CHECK-SAME: i64 [[COUNT:%.*]]) {
221; CHECK-NEXT:  entry:
222; CHECK-NEXT:    [[END:%.*]] = mul nuw i64 [[COUNT]], 3
223; CHECK-NEXT:    br label [[LOOP:%.*]]
224; CHECK:       loop:
225; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
226; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 3
227; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
228; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
229; CHECK:       loop.latch:
230; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[EXIT]]
231; CHECK:       exit:
232; CHECK-NEXT:    ret void
233;
234entry:
235  %end = mul nuw i64 %count, 3
236  br label %loop
237
238loop:
239  %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ]
240  %iv.next = add i64 %iv, 3
241  %cmp.i.not = icmp eq i64 %iv, %end
242  br i1 %cmp.i.not, label %exit, label %loop.latch
243
244loop.latch:
245  %cmp2.i.i = icmp ult i64 %iv, %end
246  br i1 %cmp2.i.i, label %loop, label %exit
247
248exit:
249  ret void
250}
251
252define void @multiple_non_pow2_missing_nuw(i64 %count) {
253; CHECK-LABEL: define void @multiple_non_pow2_missing_nuw(
254; CHECK-SAME: i64 [[COUNT:%.*]]) {
255; CHECK-NEXT:  entry:
256; CHECK-NEXT:    [[END:%.*]] = mul i64 [[COUNT]], 3
257; CHECK-NEXT:    br label [[LOOP:%.*]]
258; CHECK:       loop:
259; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
260; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 3
261; CHECK-NEXT:    [[CMP_I_NOT:%.*]] = icmp eq i64 [[IV]], [[END]]
262; CHECK-NEXT:    br i1 [[CMP_I_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
263; CHECK:       loop.latch:
264; CHECK-NEXT:    [[CMP2_I_I:%.*]] = icmp ult i64 [[IV]], [[END]]
265; CHECK-NEXT:    br i1 [[CMP2_I_I]], label [[LOOP]], label [[EXIT]]
266; CHECK:       exit:
267; CHECK-NEXT:    ret void
268;
269entry:
270  %end = mul i64 %count, 3
271  br label %loop
272
273loop:
274  %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ]
275  %iv.next = add i64 %iv, 3
276  %cmp.i.not = icmp eq i64 %iv, %end
277  br i1 %cmp.i.not, label %exit, label %loop.latch
278
279loop.latch:
280  %cmp2.i.i = icmp ult i64 %iv, %end
281  br i1 %cmp2.i.i, label %loop, label %exit
282
283exit:
284  ret void
285}
286