Skip to content

Commit 41d7350

Browse files
committed
[ConstraintElim] Add set of tests where a loop iv is used in exit.
Test cases inspired by #90417.
1 parent c5c530f commit 41d7350

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -p constraint-elimination -S %s | FileCheck %s
3+
4+
define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_known(ptr %s) {
5+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_known(
6+
; CHECK-SAME: ptr [[S:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*]]:
8+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
9+
; CHECK: [[LOOP_HEADER]]:
10+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
11+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], 1234
12+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
13+
; CHECK: [[LOOP_LATCH]]:
14+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
15+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
16+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
17+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
18+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
19+
; CHECK: [[EXIT]]:
20+
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
21+
; CHECK-NEXT: ret i1 [[T]]
22+
;
23+
entry:
24+
br label %loop.header
25+
26+
loop.header:
27+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
28+
%exitcond.not = icmp eq i32 %iv, 1234
29+
br i1 %exitcond.not, label %exit, label %loop.latch
30+
31+
loop.latch:
32+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
33+
%0 = load i8, ptr %arrayidx, align 1
34+
%latch.c = icmp ult i8 %0, 10
35+
%iv.next = add nuw nsw i32 %iv, 1
36+
br i1 %latch.c, label %loop.header, label %exit
37+
38+
exit:
39+
%t = icmp ult i32 %iv, 1235
40+
ret i1 %t
41+
}
42+
43+
define i1 @multi_exiting_loop_eq_same_exit_with_out_loop_preds_const_compare_not_known(ptr %s, i1 %pre.c, i32 %x) {
44+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_same_exit_with_out_loop_preds_const_compare_not_known(
45+
; CHECK-SAME: ptr [[S:%.*]], i1 [[PRE_C:%.*]], i32 [[X:%.*]]) {
46+
; CHECK-NEXT: [[ENTRY:.*]]:
47+
; CHECK-NEXT: br i1 [[PRE_C]], label %[[LOOP_HEADER:.*]], label %[[EXIT:.*]]
48+
; CHECK: [[LOOP_HEADER]]:
49+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
50+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], 1234
51+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT]], label %[[LOOP_LATCH]]
52+
; CHECK: [[LOOP_LATCH]]:
53+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
54+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
55+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
56+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
57+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
58+
; CHECK: [[EXIT]]:
59+
; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[X]], %[[ENTRY]] ], [ [[IV]], %[[LOOP_HEADER]] ], [ [[IV]], %[[LOOP_LATCH]] ]
60+
; CHECK-NEXT: [[U:%.*]] = icmp ult i32 [[P]], 1235
61+
; CHECK-NEXT: ret i1 [[U]]
62+
;
63+
entry:
64+
br i1 %pre.c, label %loop.header, label %exit
65+
66+
loop.header:
67+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
68+
%exitcond.not = icmp eq i32 %iv, 1234
69+
br i1 %exitcond.not, label %exit, label %loop.latch
70+
71+
loop.latch:
72+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
73+
%0 = load i8, ptr %arrayidx, align 1
74+
%latch.c = icmp ult i8 %0, 10
75+
%iv.next = add nuw nsw i32 %iv, 1
76+
br i1 %latch.c, label %loop.header, label %exit
77+
78+
exit:
79+
%p = phi i32 [ %x, %entry ], [ %iv, %loop.header ], [ %iv, %loop.latch ]
80+
%u = icmp ult i32 %p, 1235
81+
ret i1 %u
82+
}
83+
84+
define i1 @multi_exiting_loop_eq_same_unique_exit_successors_swapped(ptr %s) {
85+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_same_unique_exit_successors_swapped(
86+
; CHECK-SAME: ptr [[S:%.*]]) {
87+
; CHECK-NEXT: [[ENTRY:.*]]:
88+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
89+
; CHECK: [[LOOP_HEADER]]:
90+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
91+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], 1234
92+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[LOOP_LATCH]], label %[[EXIT:.*]]
93+
; CHECK: [[LOOP_LATCH]]:
94+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
95+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
96+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
97+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
98+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
99+
; CHECK: [[EXIT]]:
100+
; CHECK-NEXT: [[U:%.*]] = icmp ult i32 [[IV]], 1235
101+
; CHECK-NEXT: ret i1 [[U]]
102+
;
103+
entry:
104+
br label %loop.header
105+
106+
loop.header:
107+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
108+
%exitcond.not = icmp eq i32 %iv, 1234
109+
br i1 %exitcond.not, label %loop.latch, label %exit
110+
111+
loop.latch:
112+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
113+
%0 = load i8, ptr %arrayidx, align 1
114+
%latch.c = icmp ult i8 %0, 10
115+
%iv.next = add nuw nsw i32 %iv, 1
116+
br i1 %latch.c, label %loop.header, label %exit
117+
118+
exit:
119+
%u = icmp ult i32 %iv, 1235
120+
ret i1 %u
121+
}
122+
123+
define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_not_known(ptr %s) {
124+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_not_known(
125+
; CHECK-SAME: ptr [[S:%.*]]) {
126+
; CHECK-NEXT: [[ENTRY:.*]]:
127+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
128+
; CHECK: [[LOOP_HEADER]]:
129+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
130+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], 1234
131+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
132+
; CHECK: [[LOOP_LATCH]]:
133+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
134+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
135+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
136+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
137+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
138+
; CHECK: [[EXIT]]:
139+
; CHECK-NEXT: [[U:%.*]] = icmp ult i32 [[IV]], 1234
140+
; CHECK-NEXT: ret i1 [[U]]
141+
;
142+
entry:
143+
br label %loop.header
144+
145+
loop.header:
146+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
147+
%exitcond.not = icmp eq i32 %iv, 1234
148+
br i1 %exitcond.not, label %exit, label %loop.latch
149+
150+
loop.latch:
151+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
152+
%0 = load i8, ptr %arrayidx, align 1
153+
%latch.c = icmp ult i8 %0, 10
154+
%iv.next = add nuw nsw i32 %iv, 1
155+
br i1 %latch.c, label %loop.header, label %exit
156+
157+
exit:
158+
%u = icmp ult i32 %iv, 1234
159+
ret i1 %u
160+
}
161+
162+
define i1 @multi_exiting_loop_eq_same_unique_exit_var_compare_known(ptr %s, i32 %N) {
163+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_same_unique_exit_var_compare_known(
164+
; CHECK-SAME: ptr [[S:%.*]], i32 [[N:%.*]]) {
165+
; CHECK-NEXT: [[ENTRY:.*]]:
166+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
167+
; CHECK: [[LOOP_HEADER]]:
168+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
169+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], [[N]]
170+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
171+
; CHECK: [[LOOP_LATCH]]:
172+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
173+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
174+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
175+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
176+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
177+
; CHECK: [[EXIT]]:
178+
; CHECK-NEXT: [[T:%.*]] = icmp ule i32 [[IV]], [[N]]
179+
; CHECK-NEXT: ret i1 [[T]]
180+
;
181+
entry:
182+
br label %loop.header
183+
184+
loop.header:
185+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
186+
%exitcond.not = icmp eq i32 %iv, %N
187+
br i1 %exitcond.not, label %exit, label %loop.latch
188+
189+
loop.latch:
190+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
191+
%0 = load i8, ptr %arrayidx, align 1
192+
%latch.c = icmp ult i8 %0, 10
193+
%iv.next = add nuw nsw i32 %iv, 1
194+
br i1 %latch.c, label %loop.header, label %exit
195+
196+
exit:
197+
%t = icmp ule i32 %iv, %N
198+
ret i1 %t
199+
}
200+
201+
define i1 @multi_exiting_loop_ne_same_unique_exit_const_compare_known(ptr %s) {
202+
; CHECK-LABEL: define i1 @multi_exiting_loop_ne_same_unique_exit_const_compare_known(
203+
; CHECK-SAME: ptr [[S:%.*]]) {
204+
; CHECK-NEXT: [[ENTRY:.*]]:
205+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
206+
; CHECK: [[LOOP_HEADER]]:
207+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
208+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp ne i32 [[IV]], 1234
209+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[LOOP_LATCH]], label %[[EXIT:.*]]
210+
; CHECK: [[LOOP_LATCH]]:
211+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
212+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
213+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
214+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
215+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
216+
; CHECK: [[EXIT]]:
217+
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
218+
; CHECK-NEXT: ret i1 [[T]]
219+
;
220+
entry:
221+
br label %loop.header
222+
223+
loop.header:
224+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
225+
%exitcond.not = icmp ne i32 %iv, 1234
226+
br i1 %exitcond.not, label %loop.latch, label %exit
227+
228+
loop.latch:
229+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
230+
%0 = load i8, ptr %arrayidx, align 1
231+
%latch.c = icmp ult i8 %0, 10
232+
%iv.next = add nuw nsw i32 %iv, 1
233+
br i1 %latch.c, label %loop.header, label %exit
234+
235+
exit:
236+
%t = icmp ult i32 %iv, 1235
237+
ret i1 %t
238+
}
239+
240+
define i1 @multi_exiting_loop_ne_same_unique_exit_successors_swapped(ptr %s) {
241+
; CHECK-LABEL: define i1 @multi_exiting_loop_ne_same_unique_exit_successors_swapped(
242+
; CHECK-SAME: ptr [[S:%.*]]) {
243+
; CHECK-NEXT: [[ENTRY:.*]]:
244+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
245+
; CHECK: [[LOOP_HEADER]]:
246+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
247+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp ne i32 [[IV]], 1234
248+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
249+
; CHECK: [[LOOP_LATCH]]:
250+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
251+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
252+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
253+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
254+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
255+
; CHECK: [[EXIT]]:
256+
; CHECK-NEXT: [[U:%.*]] = icmp ult i32 [[IV]], 1235
257+
; CHECK-NEXT: ret i1 [[U]]
258+
;
259+
entry:
260+
br label %loop.header
261+
262+
loop.header:
263+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
264+
%exitcond.not = icmp ne i32 %iv, 1234
265+
br i1 %exitcond.not, label %exit, label %loop.latch
266+
267+
loop.latch:
268+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
269+
%0 = load i8, ptr %arrayidx, align 1
270+
%latch.c = icmp ult i8 %0, 10
271+
%iv.next = add nuw nsw i32 %iv, 1
272+
br i1 %latch.c, label %loop.header, label %exit
273+
274+
exit:
275+
%u = icmp ult i32 %iv, 1235
276+
ret i1 %u
277+
}

0 commit comments

Comments
 (0)