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
4 define void @multiple_pow2(i64 %count) {
5 ; CHECK-LABEL: define void @multiple_pow2(
6 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
8 ; CHECK-NEXT: [[END:%.*]] = shl i64 [[COUNT]], 2
9 ; CHECK-NEXT: br label [[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]]
16 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]]
18 ; CHECK-NEXT: ret void
21 %end = shl i64 %count, 2
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
31 %cmp2.i.i = icmp ult i64 %iv, %end
32 br i1 %cmp2.i.i, label %loop, label %exit
38 define void @multiple_pow2_larger_than_needed(i64 %count) {
39 ; CHECK-LABEL: define void @multiple_pow2_larger_than_needed(
40 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
42 ; CHECK-NEXT: [[END:%.*]] = shl i64 [[COUNT]], 3
43 ; CHECK-NEXT: br label [[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]]
50 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]]
52 ; CHECK-NEXT: ret void
55 %end = shl i64 %count, 3
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
65 %cmp2.i.i = icmp ult i64 %iv, %end
66 br i1 %cmp2.i.i, label %loop, label %exit
72 define void @multiple_pow2_too_small(i64 %count) {
73 ; CHECK-LABEL: define void @multiple_pow2_too_small(
74 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
76 ; CHECK-NEXT: [[END:%.*]] = shl i64 [[COUNT]], 1
77 ; CHECK-NEXT: br label [[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]]
84 ; CHECK-NEXT: [[CMP2_I_I:%.*]] = icmp ult i64 [[IV]], [[END]]
85 ; CHECK-NEXT: br i1 [[CMP2_I_I]], label [[LOOP]], label [[EXIT]]
87 ; CHECK-NEXT: ret void
90 %end = shl i64 %count, 1
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
100 %cmp2.i.i = icmp ult i64 %iv, %end
101 br i1 %cmp2.i.i, label %loop, label %exit
107 define void @multiple_pow2_start_offset(i64 %count) {
108 ; CHECK-LABEL: define void @multiple_pow2_start_offset(
109 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
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:%.*]]
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]]
120 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]]
122 ; CHECK-NEXT: ret void
125 %end = shl i64 %count, 2
126 %precond = icmp ugt i64 %end, 4
127 br i1 %precond, label %loop, label %exit
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
136 %cmp2.i.i = icmp ult i64 %iv, %end
137 br i1 %cmp2.i.i, label %loop, label %exit
143 define void @multiple_pow2_wrong_start_offset(i64 %count) {
144 ; CHECK-LABEL: define void @multiple_pow2_wrong_start_offset(
145 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
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:%.*]]
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]]
156 ; CHECK-NEXT: [[CMP2_I_I:%.*]] = icmp ult i64 [[IV]], [[END]]
157 ; CHECK-NEXT: br i1 [[CMP2_I_I]], label [[LOOP]], label [[EXIT]]
159 ; CHECK-NEXT: ret void
162 %end = shl i64 %count, 2
163 %precond = icmp ugt i64 %end, 1
164 br i1 %precond, label %loop, label %exit
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
173 %cmp2.i.i = icmp ult i64 %iv, %end
174 br i1 %cmp2.i.i, label %loop, label %exit
180 define void @multiple_pow2_start_offset_dynamic(i64 %count) {
181 ; CHECK-LABEL: define void @multiple_pow2_start_offset_dynamic(
182 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
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:%.*]]
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]]
194 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]]
196 ; CHECK-NEXT: ret void
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
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
211 %cmp2.i.i = icmp ult i64 %iv, %end
212 br i1 %cmp2.i.i, label %loop, label %exit
218 define void @multiple_non_pow2_nuw(i64 %count) {
219 ; CHECK-LABEL: define void @multiple_non_pow2_nuw(
220 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
222 ; CHECK-NEXT: [[END:%.*]] = mul nuw i64 [[COUNT]], 3
223 ; CHECK-NEXT: br label [[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]]
230 ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]]
232 ; CHECK-NEXT: ret void
235 %end = mul nuw i64 %count, 3
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
245 %cmp2.i.i = icmp ult i64 %iv, %end
246 br i1 %cmp2.i.i, label %loop, label %exit
252 define void @multiple_non_pow2_missing_nuw(i64 %count) {
253 ; CHECK-LABEL: define void @multiple_non_pow2_missing_nuw(
254 ; CHECK-SAME: i64 [[COUNT:%.*]]) {
256 ; CHECK-NEXT: [[END:%.*]] = mul i64 [[COUNT]], 3
257 ; CHECK-NEXT: br label [[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]]
264 ; CHECK-NEXT: [[CMP2_I_I:%.*]] = icmp ult i64 [[IV]], [[END]]
265 ; CHECK-NEXT: br i1 [[CMP2_I_I]], label [[LOOP]], label [[EXIT]]
267 ; CHECK-NEXT: ret void
270 %end = mul i64 %count, 3
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
280 %cmp2.i.i = icmp ult i64 %iv, %end
281 br i1 %cmp2.i.i, label %loop, label %exit