Skip to content

Commit e9b33d0

Browse files
committed
[ConstraintElim] Add extra tests with nested loops and iv decrements.
Add extra test coverage for induction logic to cover nested loops and loops with induction decrements. This adds coverage for upcoming patches.
1 parent 6420d33 commit e9b33d0

File tree

2 files changed

+416
-0
lines changed

2 files changed

+416
-0
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2+
; RUN: opt -p constraint-elimination -S %s | FileCheck %s
3+
4+
declare void @use(i1)
5+
declare void @llvm.assume(i1)
6+
7+
define void @add_rec_decreasing_cond_true_constant(i8 noundef %len) {
8+
; CHECK-LABEL: define void @add_rec_decreasing_cond_true_constant(
9+
; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
10+
; CHECK-NEXT: entry:
11+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
12+
; CHECK: loop.header:
13+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
14+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
15+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
16+
; CHECK: loop.latch:
17+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
18+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
19+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
20+
; CHECK-NEXT: br label [[LOOP_HEADER]]
21+
; CHECK: exit:
22+
; CHECK-NEXT: ret void
23+
;
24+
entry:
25+
br label %loop.header
26+
27+
loop.header:
28+
%k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
29+
%cmp2.not = icmp eq i8 %k.0, 0
30+
br i1 %cmp2.not, label %exit, label %loop.latch
31+
32+
loop.latch:
33+
%cmp.not.i = icmp ult i8 %k.0, 5
34+
call void @use(i1 %cmp.not.i)
35+
%k.dec = add i8 %k.0, -1
36+
br label %loop.header
37+
38+
exit:
39+
ret void
40+
}
41+
42+
define void @add_rec_decreasing_cond_not_true_constant(i8 noundef %len) {
43+
; CHECK-LABEL: define void @add_rec_decreasing_cond_not_true_constant(
44+
; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
45+
; CHECK-NEXT: entry:
46+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
47+
; CHECK: loop.header:
48+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
49+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
50+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
51+
; CHECK: loop.latch:
52+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 4
53+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
54+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
55+
; CHECK-NEXT: br label [[LOOP_HEADER]]
56+
; CHECK: exit:
57+
; CHECK-NEXT: ret void
58+
;
59+
entry:
60+
br label %loop.header
61+
62+
loop.header:
63+
%k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
64+
%cmp2.not = icmp eq i8 %k.0, 0
65+
br i1 %cmp2.not, label %exit, label %loop.latch
66+
67+
loop.latch:
68+
%cmp.not.i = icmp ult i8 %k.0, 4
69+
call void @use(i1 %cmp.not.i)
70+
%k.dec = add i8 %k.0, -1
71+
br label %loop.header
72+
73+
exit:
74+
ret void
75+
}
76+
77+
define void @add_rec_decreasing_cond_true_start_signed_positive(i8 noundef %start) {
78+
; CHECK-LABEL: define void @add_rec_decreasing_cond_true_start_signed_positive(
79+
; CHECK-SAME: i8 noundef [[START:%.*]]) {
80+
; CHECK-NEXT: entry:
81+
; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i8 [[START]], 1
82+
; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
83+
; CHECK-NEXT: [[START_1:%.*]] = add i8 [[START]], -1
84+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
85+
; CHECK: loop.header:
86+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ [[START_1]], [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
87+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
88+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
89+
; CHECK: loop.latch:
90+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], [[START]]
91+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
92+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
93+
; CHECK-NEXT: br label [[LOOP_HEADER]]
94+
; CHECK: exit:
95+
; CHECK-NEXT: ret void
96+
;
97+
entry:
98+
%precond = icmp sge i8 %start, 1
99+
call void @llvm.assume(i1 %precond)
100+
%start.1 = add i8 %start, -1
101+
br label %loop.header
102+
103+
loop.header:
104+
%k.0 = phi i8 [ %start.1, %entry], [ %k.dec, %loop.latch ]
105+
%cmp2.not = icmp eq i8 %k.0, 0
106+
br i1 %cmp2.not, label %exit, label %loop.latch
107+
108+
loop.latch:
109+
%cmp.not.i = icmp ult i8 %k.0, %start
110+
call void @use(i1 %cmp.not.i)
111+
%k.dec = add i8 %k.0, -1
112+
br label %loop.header
113+
114+
exit:
115+
ret void
116+
}
117+
118+
define void @add_rec_decreasing_cond_not_true_start_signed_positive(i8 noundef %start) {
119+
; CHECK-LABEL: define void @add_rec_decreasing_cond_not_true_start_signed_positive(
120+
; CHECK-SAME: i8 noundef [[START:%.*]]) {
121+
; CHECK-NEXT: entry:
122+
; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i8 [[START]], 1
123+
; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
124+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
125+
; CHECK: loop.header:
126+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ [[START]], [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
127+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
128+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
129+
; CHECK: loop.latch:
130+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], [[START]]
131+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
132+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
133+
; CHECK-NEXT: br label [[LOOP_HEADER]]
134+
; CHECK: exit:
135+
; CHECK-NEXT: ret void
136+
;
137+
entry:
138+
%precond = icmp sge i8 %start, 1
139+
call void @llvm.assume(i1 %precond)
140+
br label %loop.header
141+
142+
loop.header:
143+
%k.0 = phi i8 [ %start, %entry], [ %k.dec, %loop.latch ]
144+
%cmp2.not = icmp eq i8 %k.0, 0
145+
br i1 %cmp2.not, label %exit, label %loop.latch
146+
147+
loop.latch:
148+
%cmp.not.i = icmp ult i8 %k.0, %start
149+
call void @use(i1 %cmp.not.i)
150+
%k.dec = add i8 %k.0, -1
151+
br label %loop.header
152+
153+
exit:
154+
ret void
155+
}
156+
157+
define void @add_rec_decreasing_add_rec_positive_to_negative(i8 noundef %len) {
158+
; CHECK-LABEL: define void @add_rec_decreasing_add_rec_positive_to_negative(
159+
; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
160+
; CHECK-NEXT: entry:
161+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
162+
; CHECK: loop.header:
163+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
164+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], -2
165+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
166+
; CHECK: loop.latch:
167+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
168+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
169+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
170+
; CHECK-NEXT: br label [[LOOP_HEADER]]
171+
; CHECK: exit:
172+
; CHECK-NEXT: ret void
173+
;
174+
entry:
175+
br label %loop.header
176+
177+
loop.header:
178+
%k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
179+
%cmp2.not = icmp eq i8 %k.0, -2
180+
br i1 %cmp2.not, label %exit, label %loop.latch
181+
182+
loop.latch:
183+
%cmp.not.i = icmp ult i8 %k.0, 5
184+
call void @use(i1 %cmp.not.i)
185+
%k.dec = add i8 %k.0, -1
186+
br label %loop.header
187+
188+
exit:
189+
ret void
190+
}
191+
192+
define void @add_rec_decreasing_2_cond_true_constant(i8 noundef %len) {
193+
; CHECK-LABEL: define void @add_rec_decreasing_2_cond_true_constant(
194+
; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
195+
; CHECK-NEXT: entry:
196+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
197+
; CHECK: loop.header:
198+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
199+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
200+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
201+
; CHECK: loop.latch:
202+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
203+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
204+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -2
205+
; CHECK-NEXT: br label [[LOOP_HEADER]]
206+
; CHECK: exit:
207+
; CHECK-NEXT: ret void
208+
;
209+
entry:
210+
br label %loop.header
211+
212+
loop.header:
213+
%k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
214+
%cmp2.not = icmp eq i8 %k.0, 0
215+
br i1 %cmp2.not, label %exit, label %loop.latch
216+
217+
loop.latch:
218+
%cmp.not.i = icmp ult i8 %k.0, 5
219+
call void @use(i1 %cmp.not.i)
220+
%k.dec = add i8 %k.0, -2
221+
br label %loop.header
222+
223+
exit:
224+
ret void
225+
}
226+
227+
define void @add_rec_decreasing_2_cond_not_true_constant(i8 noundef %len) {
228+
; CHECK-LABEL: define void @add_rec_decreasing_2_cond_not_true_constant(
229+
; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
230+
; CHECK-NEXT: entry:
231+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
232+
; CHECK: loop.header:
233+
; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
234+
; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
235+
; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
236+
; CHECK: loop.latch:
237+
; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
238+
; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
239+
; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -2
240+
; CHECK-NEXT: br label [[LOOP_HEADER]]
241+
; CHECK: exit:
242+
; CHECK-NEXT: ret void
243+
;
244+
entry:
245+
br label %loop.header
246+
247+
loop.header:
248+
%k.0 = phi i8 [ 5, %entry], [ %k.dec, %loop.latch ]
249+
%cmp2.not = icmp eq i8 %k.0, 0
250+
br i1 %cmp2.not, label %exit, label %loop.latch
251+
252+
loop.latch:
253+
%cmp.not.i = icmp ult i8 %k.0, 5
254+
call void @use(i1 %cmp.not.i)
255+
%k.dec = add i8 %k.0, -2
256+
br label %loop.header
257+
258+
exit:
259+
ret void
260+
}

0 commit comments

Comments
 (0)