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
4 declare void @llvm.assume(i1)
6 define i1 @addition_with_extra_facts_and_args_ult_i64(i64 noundef %a, i64 noundef %b, i64 noundef %c) {
7 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_i64(
8 ; CHECK-SAME: i64 noundef [[A:%.*]], i64 noundef [[B:%.*]], i64 noundef [[C:%.*]]) {
10 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i64 [[A]], 2048
11 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
12 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i64 [[B]], 1024
13 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
14 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[B]], [[A]]
15 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i64 [[ADD]], [[C]]
16 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
17 ; CHECK-NEXT: ret i1 true
20 %cmp.a = icmp ule i64 %a, 2048
21 call void @llvm.assume(i1 %cmp.a)
22 %cmp.b = icmp ule i64 %b, 1024
23 call void @llvm.assume(i1 %cmp.b)
24 %add = add nuw nsw i64 %b, %a
25 %cmp.add = icmp ult i64 %add, %c
26 call void @llvm.assume(i1 %cmp.add)
27 %t = icmp ult i64 %a, %c
31 define i1 @addition_with_extra_facts_and_args_ult_1(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
32 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_1(
33 ; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) {
35 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
36 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
37 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
38 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
39 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
40 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
41 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
42 ; CHECK-NEXT: ret i1 true
45 %cmp.a = icmp ule i16 %a, 2048
46 call void @llvm.assume(i1 %cmp.a)
47 %cmp.b = icmp ule i16 %b, 1024
48 call void @llvm.assume(i1 %cmp.b)
49 %add = add nuw nsw i16 %b, %a
50 %cmp.add = icmp ult i16 %add, %c
51 call void @llvm.assume(i1 %cmp.add)
52 %t = icmp ult i16 %a, %c
56 define i1 @addition_with_extra_facts_and_args_ult_2(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
57 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_2(
58 ; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) {
60 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
61 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
62 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
63 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
64 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
65 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
66 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
67 ; CHECK-NEXT: ret i1 true
70 %cmp.a = icmp ule i16 %a, 2048
71 call void @llvm.assume(i1 %cmp.a)
72 %cmp.b = icmp ule i16 %b, 1024
73 call void @llvm.assume(i1 %cmp.b)
74 %add = add nuw nsw i16 %b, %a
75 %cmp.add = icmp ult i16 %add, %c
76 call void @llvm.assume(i1 %cmp.add)
77 %t = icmp ult i16 %b, %c
81 define i1 @addition_with_extra_facts_and_args_ult_3(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
82 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_3(
83 ; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) {
85 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
86 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
87 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
88 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
89 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
90 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
91 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
92 ; CHECK-NEXT: ret i1 false
95 %cmp.a = icmp ule i16 %a, 2048
96 call void @llvm.assume(i1 %cmp.a)
97 %cmp.b = icmp ule i16 %b, 1024
98 call void @llvm.assume(i1 %cmp.b)
99 %add = add nuw nsw i16 %b, %a
100 %cmp.add = icmp ult i16 %add, %c
101 call void @llvm.assume(i1 %cmp.add)
102 %f = icmp uge i16 %a, %c
106 define i1 @addition_with_extra_facts_and_args_ult_4(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
107 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_4(
108 ; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) {
110 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
111 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
112 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
113 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
114 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
115 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
116 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
117 ; CHECK-NEXT: ret i1 false
120 %cmp.a = icmp ule i16 %a, 2048
121 call void @llvm.assume(i1 %cmp.a)
122 %cmp.b = icmp ule i16 %b, 1024
123 call void @llvm.assume(i1 %cmp.b)
124 %add = add nuw nsw i16 %b, %a
125 %cmp.add = icmp ult i16 %add, %c
126 call void @llvm.assume(i1 %cmp.add)
127 %f = icmp uge i16 %b, %c
131 define i1 @addition_with_extra_facts_and_args_ult_5(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
132 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_5(
133 ; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) {
135 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
136 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
137 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
138 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
139 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
140 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
141 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
142 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[A]], 10
143 ; CHECK-NEXT: ret i1 [[CMP]]
146 %cmp.a = icmp ule i16 %a, 2048
147 call void @llvm.assume(i1 %cmp.a)
148 %cmp.b = icmp ule i16 %b, 1024
149 call void @llvm.assume(i1 %cmp.b)
150 %add = add nuw nsw i16 %b, %a
151 %cmp.add = icmp ult i16 %add, %c
152 call void @llvm.assume(i1 %cmp.add)
153 %cmp = icmp uge i16 %a, 10
157 define i1 @addition_with_extra_facts_and_args_ult_6(i16 noundef %a, i16 noundef %b, i16 noundef %c) {
158 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_6(
159 ; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) {
161 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
162 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
163 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
164 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
165 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
166 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
167 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
168 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[A]], [[B]]
169 ; CHECK-NEXT: ret i1 [[CMP]]
172 %cmp.a = icmp ule i16 %a, 2048
173 call void @llvm.assume(i1 %cmp.a)
174 %cmp.b = icmp ule i16 %b, 1024
175 call void @llvm.assume(i1 %cmp.b)
176 %add = add nuw nsw i16 %b, %a
177 %cmp.add = icmp ult i16 %add, %c
178 call void @llvm.assume(i1 %cmp.add)
179 %cmp = icmp ult i16 %a, %b
186 define i1 @addition_with_extra_facts_and_return_value_ult_1() {
187 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_return_value_ult_1() {
189 ; CHECK-NEXT: [[A:%.*]] = call i16 @get()
190 ; CHECK-NEXT: [[B:%.*]] = call i16 @get()
191 ; CHECK-NEXT: [[C:%.*]] = call i16 @get()
192 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
193 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
194 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
195 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
196 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
197 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
198 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
199 ; CHECK-NEXT: ret i1 true
205 %cmp.a = icmp ule i16 %a, 2048
206 call void @llvm.assume(i1 %cmp.a)
207 %cmp.b = icmp ule i16 %b, 1024
208 call void @llvm.assume(i1 %cmp.b)
209 %add = add nuw nsw i16 %b, %a
210 %cmp.add = icmp ult i16 %add, %c
211 call void @llvm.assume(i1 %cmp.add)
212 %t = icmp ult i16 %a, %c
216 define i1 @addition_with_extra_facts_and_return_value_ult_2() {
217 ; CHECK-LABEL: define i1 @addition_with_extra_facts_and_return_value_ult_2() {
219 ; CHECK-NEXT: [[A:%.*]] = call i16 @get()
220 ; CHECK-NEXT: [[B:%.*]] = call i16 @get()
221 ; CHECK-NEXT: [[C:%.*]] = call i16 @get()
222 ; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048
223 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]])
224 ; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024
225 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]])
226 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
227 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
228 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
229 ; CHECK-NEXT: ret i1 false
235 %cmp.a = icmp ule i16 %a, 2048
236 call void @llvm.assume(i1 %cmp.a)
237 %cmp.b = icmp ule i16 %b, 1024
238 call void @llvm.assume(i1 %cmp.b)
239 %add = add nuw nsw i16 %b, %a
240 %cmp.add = icmp ult i16 %add, %c
241 call void @llvm.assume(i1 %cmp.add)
242 %f = icmp uge i16 %a, %c
246 define i1 @addition_no_extra_facts_with_return_value_ult_1() {
247 ; CHECK-LABEL: define i1 @addition_no_extra_facts_with_return_value_ult_1() {
249 ; CHECK-NEXT: [[A:%.*]] = call i16 @get()
250 ; CHECK-NEXT: [[B:%.*]] = call i16 @get()
251 ; CHECK-NEXT: [[C:%.*]] = call i16 @get()
252 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
253 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
254 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
255 ; CHECK-NEXT: ret i1 true
261 %add = add nuw nsw i16 %b, %a
262 %cmp.add = icmp ult i16 %add, %c
263 call void @llvm.assume(i1 %cmp.add)
264 %t = icmp ult i16 %a, %c
268 define i1 @addition_no_extra_facts_with_return_value_ult_2() {
269 ; CHECK-LABEL: define i1 @addition_no_extra_facts_with_return_value_ult_2() {
271 ; CHECK-NEXT: [[A:%.*]] = call i16 @get()
272 ; CHECK-NEXT: [[B:%.*]] = call i16 @get()
273 ; CHECK-NEXT: [[C:%.*]] = call i16 @get()
274 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
275 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
276 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
277 ; CHECK-NEXT: ret i1 false
283 %add = add nuw nsw i16 %b, %a
284 %cmp.add = icmp ult i16 %add, %c
285 call void @llvm.assume(i1 %cmp.add)
286 %f = icmp uge i16 %a, %c
290 define i1 @addition_no_extra_facts_with_return_value_ult_3() {
291 ; CHECK-LABEL: define i1 @addition_no_extra_facts_with_return_value_ult_3() {
293 ; CHECK-NEXT: [[A:%.*]] = call i16 @get()
294 ; CHECK-NEXT: [[B:%.*]] = call i16 @get()
295 ; CHECK-NEXT: [[C:%.*]] = call i16 @get()
296 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]]
297 ; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]]
298 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]])
299 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[A]], 9
300 ; CHECK-NEXT: ret i1 [[CMP]]
306 %add = add nuw nsw i16 %b, %a
307 %cmp.add = icmp ult i16 %add, %c
308 call void @llvm.assume(i1 %cmp.add)
309 %cmp = icmp uge i16 %a, 9
313 ; Test for https://github.com/llvm/llvm-project/issues/63490.
314 define i1 @assume_x_ugt_y_plus_y_via_shl_eq(i8 %x, i8 %y) {
315 ; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_shl_eq(
316 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
317 ; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y]], 1
318 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]]
319 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]])
320 ; CHECK-NEXT: ret i1 false
322 %s = shl nuw i8 %y, 1
323 %c.1 = icmp ugt i8 %x, %s
324 tail call void @llvm.assume(i1 %c.1)
325 %c.2 = icmp eq i8 %x, %y
329 define i1 @assume_x_ugt_y_plus_y_via_shl_eq_no_nuw(i8 %x, i8 %y) {
330 ; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_shl_eq_no_nuw(
331 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
332 ; CHECK-NEXT: [[S:%.*]] = shl i8 [[Y]], 1
333 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]]
334 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]])
335 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X]], [[Y]]
336 ; CHECK-NEXT: ret i1 [[C_2]]
339 %c.1 = icmp ugt i8 %x, %s
340 tail call void @llvm.assume(i1 %c.1)
341 %c.2 = icmp eq i8 %x, %y
345 define i1 @assume_x_ugt_y_plus_y_via_add_eq(i8 %x, i8 %y) {
346 ; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_add_eq(
347 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
348 ; CHECK-NEXT: [[S:%.*]] = add nuw i8 [[Y]], [[Y]]
349 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]]
350 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]])
351 ; CHECK-NEXT: ret i1 false
353 %s = add nuw i8 %y, %y
354 %c.1 = icmp ugt i8 %x, %s
355 tail call void @llvm.assume(i1 %c.1)
356 %c.2 = icmp eq i8 %x, %y
360 define i1 @assume_x_ugt_y_plus_y_via_add_eq_no_nuw(i8 %x, i8 %y) {
361 ; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_add_eq_no_nuw(
362 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
363 ; CHECK-NEXT: [[S:%.*]] = add i8 [[Y]], [[Y]]
364 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]]
365 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]])
366 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X]], [[Y]]
367 ; CHECK-NEXT: ret i1 [[C_2]]
370 %c.1 = icmp ugt i8 %x, %s
371 tail call void @llvm.assume(i1 %c.1)
372 %c.2 = icmp eq i8 %x, %y
376 define i1 @assume_x_ugt_y_plus_y_via_shl_ne(i8 %x, i8 %y) {
377 ; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_shl_ne(
378 ; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
379 ; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y]], 1
380 ; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]]
381 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]])
382 ; CHECK-NEXT: ret i1 true
384 %s = shl nuw i8 %y, 1
385 %c.1 = icmp ugt i8 %x, %s
386 tail call void @llvm.assume(i1 %c.1)
387 %c.2 = icmp ne i8 %x, %y