1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=correlated-propagation < %s | FileCheck %s
4 declare void @use.i16(i16)
5 declare i16 @llvm.usub.sat.i16(i16, i16)
6 declare i16 @llvm.uadd.sat.i16(i16, i16)
7 declare i16 @llvm.umin.i16(i16, i16)
8 declare i16 @llvm.abs.i16(i16, i1)
10 define i16 @sel_true_cond(i16 noundef %x) {
11 ; CHECK-LABEL: @sel_true_cond(
12 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i16 [[X:%.*]], 10
13 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 10
14 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SUB1]], i16 42
15 ; CHECK-NEXT: ret i16 [[SEL]]
17 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
18 %cmp = icmp uge i16 %x, 10
19 %sel = select i1 %cmp, i16 %sub, i16 42
23 define i16 @sel_true_cond_insufficient(i16 %x) {
24 ; CHECK-LABEL: @sel_true_cond_insufficient(
25 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
26 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 9
27 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SUB]], i16 42
28 ; CHECK-NEXT: ret i16 [[SEL]]
30 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
31 %cmp = icmp uge i16 %x, 9
32 %sel = select i1 %cmp, i16 %sub, i16 42
36 define i16 @sel_true_cond_wrong_swap(i16 %x) {
37 ; CHECK-LABEL: @sel_true_cond_wrong_swap(
38 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
39 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 10
40 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 42, i16 [[SUB]]
41 ; CHECK-NEXT: ret i16 [[SEL]]
43 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
44 %cmp = icmp uge i16 %x, 10
45 %sel = select i1 %cmp, i16 42, i16 %sub
49 define i16 @sel_true_cond_wrong_op(i16 %x, i16 %y) {
50 ; CHECK-LABEL: @sel_true_cond_wrong_op(
51 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
52 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[Y:%.*]], 10
53 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SUB]], i16 42
54 ; CHECK-NEXT: ret i16 [[SEL]]
56 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
57 %cmp = icmp uge i16 %y, 10
58 %sel = select i1 %cmp, i16 %sub, i16 42
62 define i16 @sel_true_cond_extra_use(i16 %x) {
63 ; CHECK-LABEL: @sel_true_cond_extra_use(
64 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
65 ; CHECK-NEXT: call void @use.i16(i16 [[SUB]])
66 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 10
67 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SUB]], i16 42
68 ; CHECK-NEXT: ret i16 [[SEL]]
70 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
71 call void @use.i16(i16 %sub)
72 %cmp = icmp uge i16 %x, 10
73 %sel = select i1 %cmp, i16 %sub, i16 42
77 define i16 @sel_true_cond_chain_speculatable(i16 noundef %x) {
78 ; CHECK-LABEL: @sel_true_cond_chain_speculatable(
79 ; CHECK-NEXT: [[SUB1:%.*]] = add nuw i16 [[X:%.*]], 1
80 ; CHECK-NEXT: [[EXTRA:%.*]] = mul i16 [[SUB1]], 3
81 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[X]], -1
82 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[EXTRA]], i16 42
83 ; CHECK-NEXT: ret i16 [[SEL]]
85 %sub = call i16 @llvm.uadd.sat.i16(i16 %x, i16 1)
86 %extra = mul i16 %sub, 3
87 %cmp = icmp ne i16 %x, -1
88 %sel = select i1 %cmp, i16 %extra, i16 42
92 define i16 @sel_true_cond_chain_non_speculatable(i16 %x) {
93 ; CHECK-LABEL: @sel_true_cond_chain_non_speculatable(
94 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[X:%.*]], i16 1)
95 ; CHECK-NEXT: [[EXTRA:%.*]] = udiv i16 3, [[SUB]]
96 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[X]], -1
97 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[EXTRA]], i16 42
98 ; CHECK-NEXT: ret i16 [[SEL]]
100 %sub = call i16 @llvm.uadd.sat.i16(i16 %x, i16 1)
101 %extra = udiv i16 3, %sub
102 %cmp = icmp ne i16 %x, -1
103 %sel = select i1 %cmp, i16 %extra, i16 42
107 ; TODO: We could handle this case by raising the limit on the number of
108 ; instructions we look through.
109 define i16 @sel_true_cond_longer_chain(i16 %x) {
110 ; CHECK-LABEL: @sel_true_cond_longer_chain(
111 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[X:%.*]], i16 1)
112 ; CHECK-NEXT: [[EXTRA:%.*]] = mul i16 [[SUB]], 3
113 ; CHECK-NEXT: [[EXTRA2:%.*]] = xor i16 [[SUB]], 7
114 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[X]], -1
115 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[EXTRA2]], i16 42
116 ; CHECK-NEXT: ret i16 [[SEL]]
118 %sub = call i16 @llvm.uadd.sat.i16(i16 %x, i16 1)
119 %extra = mul i16 %sub, 3
120 %extra2 = xor i16 %sub, 7
121 %cmp = icmp ne i16 %x, -1
122 %sel = select i1 %cmp, i16 %extra2, i16 42
126 define i16 @sel_false_cond(i16 noundef %x) {
127 ; CHECK-LABEL: @sel_false_cond(
128 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i16 [[X:%.*]], 10
129 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 10
130 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 42, i16 [[SUB1]]
131 ; CHECK-NEXT: ret i16 [[SEL]]
133 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
134 %cmp = icmp ult i16 %x, 10
135 %sel = select i1 %cmp, i16 42, i16 %sub
139 define i16 @sel_false_cond_insufficient(i16 %x) {
140 ; CHECK-LABEL: @sel_false_cond_insufficient(
141 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
142 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 9
143 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 42, i16 [[SUB]]
144 ; CHECK-NEXT: ret i16 [[SEL]]
146 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
147 %cmp = icmp ult i16 %x, 9
148 %sel = select i1 %cmp, i16 42, i16 %sub
152 define i16 @phi_true_cond(i16 %x) {
153 ; CHECK-LABEL: @phi_true_cond(
155 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i16 [[X:%.*]], 10
156 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 10
157 ; CHECK-NEXT: br i1 [[CMP]], label [[JOIN:%.*]], label [[SPLIT:%.*]]
159 ; CHECK-NEXT: br label [[JOIN]]
161 ; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ [[SUB1]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
162 ; CHECK-NEXT: ret i16 [[PHI]]
165 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
166 %cmp = icmp uge i16 %x, 10
167 br i1 %cmp, label %join, label %split
173 %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
177 define i16 @phi_true_cond_insufficient(i16 %x) {
178 ; CHECK-LABEL: @phi_true_cond_insufficient(
180 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
181 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 9
182 ; CHECK-NEXT: br i1 [[CMP]], label [[JOIN:%.*]], label [[SPLIT:%.*]]
184 ; CHECK-NEXT: br label [[JOIN]]
186 ; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ [[SUB]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
187 ; CHECK-NEXT: ret i16 [[PHI]]
190 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
191 %cmp = icmp uge i16 %x, 9
192 br i1 %cmp, label %join, label %split
198 %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
202 ; TODO: We could handle this by using conditions that are not directly on the
204 define i16 @phi_true_cond_non_local(i16 %x) {
205 ; CHECK-LABEL: @phi_true_cond_non_local(
207 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
208 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[X]], 10
209 ; CHECK-NEXT: br i1 [[CMP]], label [[SPLIT:%.*]], label [[JOIN:%.*]]
211 ; CHECK-NEXT: br label [[JOIN]]
213 ; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ [[SUB]], [[SPLIT]] ], [ 42, [[ENTRY:%.*]] ]
214 ; CHECK-NEXT: ret i16 [[PHI]]
217 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
218 %cmp = icmp uge i16 %x, 10
219 br i1 %cmp, label %split, label %join
225 %phi = phi i16 [ %sub, %split ], [ 42, %entry ]
229 define i16 @phi_false_cond(i16 %x) {
230 ; CHECK-LABEL: @phi_false_cond(
232 ; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i16 [[X:%.*]], 10
233 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 10
234 ; CHECK-NEXT: br i1 [[CMP]], label [[SPLIT:%.*]], label [[JOIN:%.*]]
236 ; CHECK-NEXT: br label [[JOIN]]
238 ; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ [[SUB1]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
239 ; CHECK-NEXT: ret i16 [[PHI]]
242 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
243 %cmp = icmp ult i16 %x, 10
244 br i1 %cmp, label %split, label %join
250 %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
254 define i16 @phi_false_cond_insufficient(i16 %x) {
255 ; CHECK-LABEL: @phi_false_cond_insufficient(
257 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
258 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 9
259 ; CHECK-NEXT: br i1 [[CMP]], label [[SPLIT:%.*]], label [[JOIN:%.*]]
261 ; CHECK-NEXT: br label [[JOIN]]
263 ; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ [[SUB]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
264 ; CHECK-NEXT: ret i16 [[PHI]]
267 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
268 %cmp = icmp ult i16 %x, 9
269 br i1 %cmp, label %split, label %join
275 %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
279 ; TODO: We could handle this by using conditions that are not directly on the
281 define i16 @phi_false_cond_non_local(i16 %x) {
282 ; CHECK-LABEL: @phi_false_cond_non_local(
284 ; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[X:%.*]], i16 10)
285 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 10
286 ; CHECK-NEXT: br i1 [[CMP]], label [[JOIN:%.*]], label [[SPLIT:%.*]]
288 ; CHECK-NEXT: br label [[JOIN]]
290 ; CHECK-NEXT: [[PHI:%.*]] = phi i16 [ [[SUB]], [[SPLIT]] ], [ 42, [[ENTRY:%.*]] ]
291 ; CHECK-NEXT: ret i16 [[PHI]]
294 %sub = call i16 @llvm.usub.sat.i16(i16 %x, i16 10)
295 %cmp = icmp ult i16 %x, 10
296 br i1 %cmp, label %join, label %split
302 %phi = phi i16 [ %sub, %split ], [ 42, %entry ]
306 define i16 @loop_cond() {
307 ; CHECK-LABEL: @loop_cond(
309 ; CHECK-NEXT: br label [[LOOP:%.*]]
311 ; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 1000, [[ENTRY:%.*]] ], [ [[IV_NEXT1:%.*]], [[LOOP]] ]
312 ; CHECK-NEXT: [[COUNT:%.*]] = phi i16 [ 0, [[ENTRY]] ], [ [[COUNT_NEXT:%.*]], [[LOOP]] ]
313 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[IV]], 0
314 ; CHECK-NEXT: [[IV_NEXT1]] = sub nuw i16 [[IV]], 1
315 ; CHECK-NEXT: [[COUNT_NEXT]] = add i16 [[COUNT]], 1
316 ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
318 ; CHECK-NEXT: ret i16 [[COUNT]]
324 %iv = phi i16 [ 1000, %entry ], [ %iv.next, %loop ]
325 %count = phi i16 [ 0, %entry ], [ %count.next, %loop ]
326 %cmp = icmp eq i16 %iv, 0
327 %iv.next = call i16 @llvm.usub.sat.i16(i16 %iv, i16 1)
328 %count.next = add i16 %count, 1
329 br i1 %cmp, label %exit, label %loop
335 define i16 @urem_elide(i16 noundef %x) {
336 ; CHECK-LABEL: @urem_elide(
337 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 42
338 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[X]], i16 24
339 ; CHECK-NEXT: ret i16 [[SEL]]
341 %urem = urem i16 %x, 42
342 %cmp = icmp ult i16 %x, 42
343 %sel = select i1 %cmp, i16 %urem, i16 24
347 define i16 @urem_expand(i16 noundef %x) {
348 ; CHECK-LABEL: @urem_expand(
349 ; CHECK-NEXT: [[UREM_UREM:%.*]] = sub nuw i16 [[X:%.*]], 42
350 ; CHECK-NEXT: [[UREM_CMP:%.*]] = icmp ult i16 [[X]], 42
351 ; CHECK-NEXT: [[UREM:%.*]] = select i1 [[UREM_CMP]], i16 [[X]], i16 [[UREM_UREM]]
352 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 84
353 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[UREM]], i16 24
354 ; CHECK-NEXT: ret i16 [[SEL]]
356 %urem = urem i16 %x, 42
357 %cmp = icmp ult i16 %x, 84
358 %sel = select i1 %cmp, i16 %urem, i16 24
362 define i16 @urem_narrow(i16 noundef %x) {
363 ; CHECK-LABEL: @urem_narrow(
364 ; CHECK-NEXT: [[UREM_LHS_TRUNC:%.*]] = trunc i16 [[X:%.*]] to i8
365 ; CHECK-NEXT: [[UREM1:%.*]] = urem i8 [[UREM_LHS_TRUNC]], 42
366 ; CHECK-NEXT: [[UREM_ZEXT:%.*]] = zext i8 [[UREM1]] to i16
367 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 85
368 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[UREM_ZEXT]], i16 24
369 ; CHECK-NEXT: ret i16 [[SEL]]
371 %urem = urem i16 %x, 42
372 %cmp = icmp ult i16 %x, 85
373 %sel = select i1 %cmp, i16 %urem, i16 24
377 define i16 @urem_insufficient(i16 %x) {
378 ; CHECK-LABEL: @urem_insufficient(
379 ; CHECK-NEXT: [[UREM:%.*]] = urem i16 [[X:%.*]], 42
380 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 257
381 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[UREM]], i16 24
382 ; CHECK-NEXT: ret i16 [[SEL]]
384 %urem = urem i16 %x, 42
385 %cmp = icmp ult i16 %x, 257
386 %sel = select i1 %cmp, i16 %urem, i16 24
390 define i16 @srem_elide(i16 noundef %x) {
391 ; CHECK-LABEL: @srem_elide(
392 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i16 [[X:%.*]], 42
393 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[X]], -42
394 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
395 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i16 [[X]], i16 24
396 ; CHECK-NEXT: ret i16 [[SEL]]
398 %srem = srem i16 %x, 42
399 %cmp1 = icmp slt i16 %x, 42
400 %cmp2 = icmp sgt i16 %x, -42
401 %and = and i1 %cmp1, %cmp2
402 %sel = select i1 %and, i16 %srem, i16 24
406 define i16 @srem_narrow(i16 noundef %x) {
407 ; CHECK-LABEL: @srem_narrow(
408 ; CHECK-NEXT: [[SREM_LHS_TRUNC:%.*]] = trunc i16 [[X:%.*]] to i8
409 ; CHECK-NEXT: [[SREM1:%.*]] = srem i8 [[SREM_LHS_TRUNC]], 42
410 ; CHECK-NEXT: [[SREM_SEXT:%.*]] = sext i8 [[SREM1]] to i16
411 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i16 [[X]], 43
412 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i16 [[X]], -43
413 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
414 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[AND]], i16 [[SREM_SEXT]], i16 24
415 ; CHECK-NEXT: ret i16 [[SEL]]
417 %srem = srem i16 %x, 42
418 %cmp1 = icmp slt i16 %x, 43
419 %cmp2 = icmp sgt i16 %x, -43
420 %and = and i1 %cmp1, %cmp2
421 %sel = select i1 %and, i16 %srem, i16 24
425 define i16 @srem_convert(i16 noundef %x) {
426 ; CHECK-LABEL: @srem_convert(
427 ; CHECK-NEXT: [[X_NONNEG:%.*]] = sub i16 0, [[X:%.*]]
428 ; CHECK-NEXT: [[SREM1:%.*]] = urem i16 [[X_NONNEG]], 42
429 ; CHECK-NEXT: [[SREM1_NEG:%.*]] = sub i16 0, [[SREM1]]
430 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[X]], 0
431 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SREM1_NEG]], i16 24
432 ; CHECK-NEXT: ret i16 [[SEL]]
434 %srem = srem i16 %x, 42
435 %cmp = icmp slt i16 %x, 0
436 %sel = select i1 %cmp, i16 %srem, i16 24
440 define i16 @sdiv_convert(i16 noundef %x) {
441 ; CHECK-LABEL: @sdiv_convert(
442 ; CHECK-NEXT: [[X_NONNEG:%.*]] = sub i16 0, [[X:%.*]]
443 ; CHECK-NEXT: [[SREM1:%.*]] = udiv i16 [[X_NONNEG]], 42
444 ; CHECK-NEXT: [[SREM1_NEG:%.*]] = sub i16 0, [[SREM1]]
445 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[X]], 0
446 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SREM1_NEG]], i16 24
447 ; CHECK-NEXT: ret i16 [[SEL]]
449 %srem = sdiv i16 %x, 42
450 %cmp = icmp slt i16 %x, 0
451 %sel = select i1 %cmp, i16 %srem, i16 24
455 define i16 @abs_elide(i16 %x) {
456 ; CHECK-LABEL: @abs_elide(
457 ; CHECK-NEXT: [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[X:%.*]], i1 false)
458 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i16 [[X]], -32768
459 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[ABS]], i16 42
460 ; CHECK-NEXT: ret i16 [[SEL]]
462 %abs = call i16 @llvm.abs.i16(i16 %x, i1 false)
463 %cmp = icmp ule i16 %x, 32768
464 %sel = select i1 %cmp, i16 %abs, i16 42
468 define i16 @abs_elide2(i16 %x) {
469 ; CHECK-LABEL: @abs_elide2(
470 ; CHECK-NEXT: [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[X:%.*]], i1 false)
471 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i16 [[X]], 0
472 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[ABS]], i16 42
473 ; CHECK-NEXT: ret i16 [[SEL]]
475 %abs = call i16 @llvm.abs.i16(i16 %x, i1 false)
476 %cmp = icmp sle i16 %x, 0
477 %sel = select i1 %cmp, i16 %abs, i16 42
481 define i16 @abs_not_int_min(i16 %x) {
482 ; CHECK-LABEL: @abs_not_int_min(
483 ; CHECK-NEXT: [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[X:%.*]], i1 false)
484 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[X]], -32768
485 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[ABS]], i16 42
486 ; CHECK-NEXT: ret i16 [[SEL]]
488 %abs = call i16 @llvm.abs.i16(i16 %x, i1 false)
489 %cmp = icmp ne i16 %x, 32768
490 %sel = select i1 %cmp, i16 %abs, i16 42
494 define i16 @umin_elide(i16 %x) {
495 ; CHECK-LABEL: @umin_elide(
496 ; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X:%.*]], i16 10)
497 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i16 [[X]], 10
498 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[MIN]], i16 42
499 ; CHECK-NEXT: ret i16 [[SEL]]
501 %min = call i16 @llvm.umin.i16(i16 %x, i16 10)
502 %cmp = icmp ule i16 %x, 10
503 %sel = select i1 %cmp, i16 %min, i16 42
507 define i16 @ashr_convert(i16 noundef %x, i16 %y) {
508 ; CHECK-LABEL: @ashr_convert(
509 ; CHECK-NEXT: [[ASHR:%.*]] = lshr i16 [[X:%.*]], [[Y:%.*]]
510 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i16 [[X]], 0
511 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[ASHR]], i16 24
512 ; CHECK-NEXT: ret i16 [[SEL]]
514 %ashr = ashr i16 %x, %y
515 %cmp = icmp sge i16 %x, 0
516 %sel = select i1 %cmp, i16 %ashr, i16 24
520 define i32 @sext_convert(i16 noundef %x) {
521 ; CHECK-LABEL: @sext_convert(
522 ; CHECK-NEXT: [[EXT:%.*]] = zext nneg i16 [[X:%.*]] to i32
523 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i16 [[X]], 0
524 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[EXT]], i32 24
525 ; CHECK-NEXT: ret i32 [[SEL]]
527 %ext = sext i16 %x to i32
528 %cmp = icmp sge i16 %x, 0
529 %sel = select i1 %cmp, i32 %ext, i32 24
533 define i16 @infer_flags(i16 %x) {
534 ; CHECK-LABEL: @infer_flags(
535 ; CHECK-NEXT: [[ADD:%.*]] = add i16 [[X:%.*]], 42
536 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 100
537 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[ADD]], i16 24
538 ; CHECK-NEXT: ret i16 [[SEL]]
540 %add = add i16 %x, 42
541 %cmp = icmp ult i16 %x, 100
542 %sel = select i1 %cmp, i16 %add, i16 24
546 define i16 @and_elide(i16 noundef %x) {
547 ; CHECK-LABEL: @and_elide(
548 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 8
549 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[X]], i16 24
550 ; CHECK-NEXT: ret i16 [[SEL]]
553 %cmp = icmp ult i16 %x, 8
554 %sel = select i1 %cmp, i16 %and, i16 24
558 define i16 @cond_value_may_not_well_defined(i16 %x) {
559 ; CHECK-LABEL: @cond_value_may_not_well_defined(
560 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[X:%.*]], 7
561 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 8
562 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[AND]], i16 24
563 ; CHECK-NEXT: ret i16 [[SEL]]
566 %cmp = icmp ult i16 %x, 8
567 %sel = select i1 %cmp, i16 %and, i16 24
571 define i16 @and_elide_poison_flags(i16 noundef %a) {
572 ; CHECK-LABEL: @and_elide_poison_flags(
573 ; CHECK-NEXT: [[X:%.*]] = add nuw i16 [[A:%.*]], 1
574 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 8
575 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[X]], i16 24
576 ; CHECK-NEXT: ret i16 [[SEL]]
578 %x = add nuw i16 %a, 1
580 %cmp = icmp ult i16 %x, 8
581 %sel = select i1 %cmp, i16 %and, i16 24
585 define i16 @and_elide_poison_flags_missing_noundef(i16 %a) {
586 ; CHECK-LABEL: @and_elide_poison_flags_missing_noundef(
587 ; CHECK-NEXT: [[X:%.*]] = add nuw i16 [[A:%.*]], 1
588 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[X]], 7
589 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X]], 8
590 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[AND]], i16 24
591 ; CHECK-NEXT: ret i16 [[SEL]]
593 %x = add nuw i16 %a, 1
595 %cmp = icmp ult i16 %x, 8
596 %sel = select i1 %cmp, i16 %and, i16 24
600 define i32 @pr87854(i32 noundef %x.1, i32 noundef %i) {
601 ; CHECK-LABEL: @pr87854(
602 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[X_1:%.*]], -1
603 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]])
604 ; CHECK-NEXT: [[INBOUNDS:%.*]] = icmp ult i32 [[I:%.*]], [[X_1]]
605 ; CHECK-NEXT: [[NEXT:%.*]] = add nuw i32 [[I]], 1
606 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[INBOUNDS]], i32 [[NEXT]], i32 -1
607 ; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
609 %cond = icmp sgt i32 %x.1, -1
610 tail call void @llvm.assume(i1 %cond)
611 %inbounds = icmp ult i32 %i, %x.1
612 %next = add i32 %i, 1
613 %spec.select = select i1 %inbounds, i32 %next, i32 -1
617 define i64 @test_shl_nsw_at_use(i64 noundef %x) {
618 ; CHECK-LABEL: @test_shl_nsw_at_use(
619 ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X:%.*]], 2147483648
620 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[ADD]], 4294967296
621 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i64 [[X]], 32
622 ; CHECK-NEXT: [[SHR:%.*]] = ashr exact i64 [[SHL]], 32
623 ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i64 [[SHR]], i64 0
624 ; CHECK-NEXT: ret i64 [[RES]]
626 %add = add i64 %x, 2147483648
627 %cmp = icmp ult i64 %add, 4294967296
628 %shl = shl i64 %x, 32
629 %shr = ashr exact i64 %shl, 32
630 %res = select i1 %cmp, i64 %shr, i64 0
634 define i1 @test_icmp_mod(i64 noundef %x) {
635 ; CHECK-LABEL: @test_icmp_mod(
637 ; CHECK-NEXT: [[REM:%.*]] = srem i64 [[X:%.*]], 86400
638 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[REM]], 0
639 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i64 86400, i64 0
640 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[COND]], [[REM]]
641 ; CHECK-NEXT: ret i1 false
644 %rem = srem i64 %x, 86400
645 %cmp = icmp slt i64 %rem, 0
646 %cond = select i1 %cmp, i64 86400, i64 0
647 %add = add nsw i64 %cond, %rem
648 %cmp1 = icmp ugt i64 %add, 86399
652 define i1 @test_icmp_mod_commuted1(i64 noundef %x) {
653 ; CHECK-LABEL: @test_icmp_mod_commuted1(
655 ; CHECK-NEXT: [[REM:%.*]] = srem i64 [[X:%.*]], 86400
656 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[REM]], 0
657 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i64 86400, i64 0
658 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[REM]], [[COND]]
659 ; CHECK-NEXT: ret i1 false
662 %rem = srem i64 %x, 86400
663 %cmp = icmp slt i64 %rem, 0
664 %cond = select i1 %cmp, i64 86400, i64 0
665 %add = add nsw i64 %rem, %cond
666 %cmp1 = icmp ugt i64 %add, 86399
670 define i1 @test_icmp_mod_commuted2(i64 noundef %x) {
671 ; CHECK-LABEL: @test_icmp_mod_commuted2(
673 ; CHECK-NEXT: [[REM:%.*]] = srem i64 [[X:%.*]], 86400
674 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[REM]], -1
675 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i64 0, i64 86400
676 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[COND]], [[REM]]
677 ; CHECK-NEXT: ret i1 false
680 %rem = srem i64 %x, 86400
681 %cmp = icmp sgt i64 %rem, -1
682 %cond = select i1 %cmp, i64 0, i64 86400
683 %add = add nsw i64 %cond, %rem
684 %cmp1 = icmp ugt i64 %add, 86399
688 define i1 @test_icmp_mod_undef(i64 %x) {
689 ; CHECK-LABEL: @test_icmp_mod_undef(
691 ; CHECK-NEXT: [[REM:%.*]] = srem i64 [[X:%.*]], 86400
692 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[REM]], 0
693 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i64 86400, i64 0
694 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[COND]], [[REM]]
695 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i64 [[ADD]], 86399
696 ; CHECK-NEXT: ret i1 [[CMP1]]
699 %rem = srem i64 %x, 86400
700 %cmp = icmp slt i64 %rem, 0
701 %cond = select i1 %cmp, i64 86400, i64 0
702 %add = add nsw i64 %cond, %rem
703 %cmp1 = icmp ugt i64 %add, 86399
707 define i1 @test_icmp_mod_wrong_range(i64 noundef %x) {
708 ; CHECK-LABEL: @test_icmp_mod_wrong_range(
710 ; CHECK-NEXT: [[REM:%.*]] = srem i64 [[X:%.*]], 86400
711 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[REM]], 0
712 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i64 86401, i64 0
713 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[COND]], [[REM]]
714 ; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign ugt i64 [[ADD]], 86399
715 ; CHECK-NEXT: ret i1 [[CMP1]]
718 %rem = srem i64 %x, 86400
719 %cmp = icmp slt i64 %rem, 0
720 %cond = select i1 %cmp, i64 86401, i64 0
721 %add = add nsw i64 %cond, %rem
722 %cmp1 = icmp ugt i64 %add, 86399