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
5 declare void @llvm.assume(i1)
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:%.*]]) {
11 ; CHECK-NEXT: br label [[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]]
17 ; CHECK-NEXT: call void @use(i1 true)
18 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
19 ; CHECK-NEXT: br label [[LOOP_HEADER]]
21 ; CHECK-NEXT: ret void
27 %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
28 %cmp2.not = icmp eq i8 %k.0, 0
29 br i1 %cmp2.not, label %exit, label %loop.latch
32 %cmp.not.i = icmp ult i8 %k.0, 5
33 call void @use(i1 %cmp.not.i)
34 %k.dec = add i8 %k.0, -1
41 define void @add_rec_decreasing_cond_not_true_constant(i8 noundef %len) {
42 ; CHECK-LABEL: define void @add_rec_decreasing_cond_not_true_constant(
43 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
45 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
47 ; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
48 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
49 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
51 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 4
52 ; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
53 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
54 ; CHECK-NEXT: br label [[LOOP_HEADER]]
56 ; CHECK-NEXT: ret void
62 %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
63 %cmp2.not = icmp eq i8 %k.0, 0
64 br i1 %cmp2.not, label %exit, label %loop.latch
67 %cmp.not.i = icmp ult i8 %k.0, 4
68 call void @use(i1 %cmp.not.i)
69 %k.dec = add i8 %k.0, -1
76 define void @add_rec_decreasing_cond_true_start_signed_positive(i8 noundef %start) {
77 ; CHECK-LABEL: define void @add_rec_decreasing_cond_true_start_signed_positive(
78 ; CHECK-SAME: i8 noundef [[START:%.*]]) {
80 ; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i8 [[START]], 1
81 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
82 ; CHECK-NEXT: [[START_1:%.*]] = add i8 [[START]], -1
83 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
85 ; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ [[START_1]], [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
86 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
87 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
89 ; CHECK-NEXT: call void @use(i1 true)
90 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
91 ; CHECK-NEXT: br label [[LOOP_HEADER]]
93 ; CHECK-NEXT: ret void
96 %precond = icmp sge i8 %start, 1
97 call void @llvm.assume(i1 %precond)
98 %start.1 = add i8 %start, -1
102 %k.0 = phi i8 [ %start.1, %entry], [ %k.dec, %loop.latch ]
103 %cmp2.not = icmp eq i8 %k.0, 0
104 br i1 %cmp2.not, label %exit, label %loop.latch
107 %cmp.not.i = icmp ult i8 %k.0, %start
108 call void @use(i1 %cmp.not.i)
109 %k.dec = add i8 %k.0, -1
110 br label %loop.header
116 define void @add_rec_decreasing_cond_not_true_start_signed_positive(i8 noundef %start) {
117 ; CHECK-LABEL: define void @add_rec_decreasing_cond_not_true_start_signed_positive(
118 ; CHECK-SAME: i8 noundef [[START:%.*]]) {
120 ; CHECK-NEXT: [[PRECOND:%.*]] = icmp sge i8 [[START]], 1
121 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
122 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
123 ; CHECK: loop.header:
124 ; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ [[START]], [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
125 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
126 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
128 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], [[START]]
129 ; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
130 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
131 ; CHECK-NEXT: br label [[LOOP_HEADER]]
133 ; CHECK-NEXT: ret void
136 %precond = icmp sge i8 %start, 1
137 call void @llvm.assume(i1 %precond)
138 br label %loop.header
141 %k.0 = phi i8 [ %start, %entry], [ %k.dec, %loop.latch ]
142 %cmp2.not = icmp eq i8 %k.0, 0
143 br i1 %cmp2.not, label %exit, label %loop.latch
146 %cmp.not.i = icmp ult i8 %k.0, %start
147 call void @use(i1 %cmp.not.i)
148 %k.dec = add i8 %k.0, -1
149 br label %loop.header
155 define void @add_rec_decreasing_add_rec_positive_to_negative(i8 noundef %len) {
156 ; CHECK-LABEL: define void @add_rec_decreasing_add_rec_positive_to_negative(
157 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
159 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
160 ; CHECK: loop.header:
161 ; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
162 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], -2
163 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
165 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
166 ; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
167 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -1
168 ; CHECK-NEXT: br label [[LOOP_HEADER]]
170 ; CHECK-NEXT: ret void
173 br label %loop.header
176 %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
177 %cmp2.not = icmp eq i8 %k.0, -2
178 br i1 %cmp2.not, label %exit, label %loop.latch
181 %cmp.not.i = icmp ult i8 %k.0, 5
182 call void @use(i1 %cmp.not.i)
183 %k.dec = add i8 %k.0, -1
184 br label %loop.header
190 define void @add_rec_decreasing_2_cond_true_constant(i8 noundef %len) {
191 ; CHECK-LABEL: define void @add_rec_decreasing_2_cond_true_constant(
192 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
194 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
195 ; CHECK: loop.header:
196 ; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 4, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
197 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
198 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
200 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
201 ; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
202 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -2
203 ; CHECK-NEXT: br label [[LOOP_HEADER]]
205 ; CHECK-NEXT: ret void
208 br label %loop.header
211 %k.0 = phi i8 [ 4, %entry], [ %k.dec, %loop.latch ]
212 %cmp2.not = icmp eq i8 %k.0, 0
213 br i1 %cmp2.not, label %exit, label %loop.latch
216 %cmp.not.i = icmp ult i8 %k.0, 5
217 call void @use(i1 %cmp.not.i)
218 %k.dec = add i8 %k.0, -2
219 br label %loop.header
225 define void @add_rec_decreasing_2_cond_not_true_constant(i8 noundef %len) {
226 ; CHECK-LABEL: define void @add_rec_decreasing_2_cond_not_true_constant(
227 ; CHECK-SAME: i8 noundef [[LEN:%.*]]) {
229 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
230 ; CHECK: loop.header:
231 ; CHECK-NEXT: [[K_0:%.*]] = phi i8 [ 5, [[ENTRY:%.*]] ], [ [[K_DEC:%.*]], [[LOOP_LATCH:%.*]] ]
232 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i8 [[K_0]], 0
233 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
235 ; CHECK-NEXT: [[CMP_NOT_I:%.*]] = icmp ult i8 [[K_0]], 5
236 ; CHECK-NEXT: call void @use(i1 [[CMP_NOT_I]])
237 ; CHECK-NEXT: [[K_DEC]] = add i8 [[K_0]], -2
238 ; CHECK-NEXT: br label [[LOOP_HEADER]]
240 ; CHECK-NEXT: ret void
243 br label %loop.header
246 %k.0 = phi i8 [ 5, %entry], [ %k.dec, %loop.latch ]
247 %cmp2.not = icmp eq i8 %k.0, 0
248 br i1 %cmp2.not, label %exit, label %loop.latch
251 %cmp.not.i = icmp ult i8 %k.0, 5
252 call void @use(i1 %cmp.not.i)
253 %k.dec = add i8 %k.0, -2
254 br label %loop.header