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