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