[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Transforms / CorrelatedValuePropagation / cond-at-use.ll
blob3af4c70a5621c88f92247205abff85548d9c5c70
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
20   ret i16 %sel
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
33   ret i16 %sel
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
46   ret i16 %sel
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
59   ret i16 %sel
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
74   ret i16 %sel
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
89   ret i16 %sel
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
104   ret i16 %sel
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
123   ret i16 %sel
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
136   ret i16 %sel
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
149   ret i16 %sel
152 define i16 @phi_true_cond(i16 %x) {
153 ; CHECK-LABEL: @phi_true_cond(
154 ; CHECK-NEXT:  entry:
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:%.*]]
158 ; CHECK:       split:
159 ; CHECK-NEXT:    br label [[JOIN]]
160 ; CHECK:       join:
161 ; CHECK-NEXT:    [[PHI:%.*]] = phi i16 [ [[SUB1]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
162 ; CHECK-NEXT:    ret i16 [[PHI]]
164 entry:
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
169 split:
170   br label %join
172 join:
173   %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
174   ret i16 %phi
177 define i16 @phi_true_cond_insufficient(i16 %x) {
178 ; CHECK-LABEL: @phi_true_cond_insufficient(
179 ; CHECK-NEXT:  entry:
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:%.*]]
183 ; CHECK:       split:
184 ; CHECK-NEXT:    br label [[JOIN]]
185 ; CHECK:       join:
186 ; CHECK-NEXT:    [[PHI:%.*]] = phi i16 [ [[SUB]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
187 ; CHECK-NEXT:    ret i16 [[PHI]]
189 entry:
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
194 split:
195   br label %join
197 join:
198   %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
199   ret i16 %phi
202 ; TODO: We could handle this by using conditions that are not directly on the
203 ; phi edge.
204 define i16 @phi_true_cond_non_local(i16 %x) {
205 ; CHECK-LABEL: @phi_true_cond_non_local(
206 ; CHECK-NEXT:  entry:
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:%.*]]
210 ; CHECK:       split:
211 ; CHECK-NEXT:    br label [[JOIN]]
212 ; CHECK:       join:
213 ; CHECK-NEXT:    [[PHI:%.*]] = phi i16 [ [[SUB]], [[SPLIT]] ], [ 42, [[ENTRY:%.*]] ]
214 ; CHECK-NEXT:    ret i16 [[PHI]]
216 entry:
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
221 split:
222   br label %join
224 join:
225   %phi = phi i16 [ %sub, %split ], [ 42, %entry ]
226   ret i16 %phi
229 define i16 @phi_false_cond(i16 %x) {
230 ; CHECK-LABEL: @phi_false_cond(
231 ; CHECK-NEXT:  entry:
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:%.*]]
235 ; CHECK:       split:
236 ; CHECK-NEXT:    br label [[JOIN]]
237 ; CHECK:       join:
238 ; CHECK-NEXT:    [[PHI:%.*]] = phi i16 [ [[SUB1]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
239 ; CHECK-NEXT:    ret i16 [[PHI]]
241 entry:
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
246 split:
247   br label %join
249 join:
250   %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
251   ret i16 %phi
254 define i16 @phi_false_cond_insufficient(i16 %x) {
255 ; CHECK-LABEL: @phi_false_cond_insufficient(
256 ; CHECK-NEXT:  entry:
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:%.*]]
260 ; CHECK:       split:
261 ; CHECK-NEXT:    br label [[JOIN]]
262 ; CHECK:       join:
263 ; CHECK-NEXT:    [[PHI:%.*]] = phi i16 [ [[SUB]], [[ENTRY:%.*]] ], [ 42, [[SPLIT]] ]
264 ; CHECK-NEXT:    ret i16 [[PHI]]
266 entry:
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
271 split:
272   br label %join
274 join:
275   %phi = phi i16 [ %sub, %entry ], [ 42, %split ]
276   ret i16 %phi
279 ; TODO: We could handle this by using conditions that are not directly on the
280 ; phi edge.
281 define i16 @phi_false_cond_non_local(i16 %x) {
282 ; CHECK-LABEL: @phi_false_cond_non_local(
283 ; CHECK-NEXT:  entry:
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:%.*]]
287 ; CHECK:       split:
288 ; CHECK-NEXT:    br label [[JOIN]]
289 ; CHECK:       join:
290 ; CHECK-NEXT:    [[PHI:%.*]] = phi i16 [ [[SUB]], [[SPLIT]] ], [ 42, [[ENTRY:%.*]] ]
291 ; CHECK-NEXT:    ret i16 [[PHI]]
293 entry:
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
298 split:
299   br label %join
301 join:
302   %phi = phi i16 [ %sub, %split ], [ 42, %entry ]
303   ret i16 %phi
306 define i16 @loop_cond() {
307 ; CHECK-LABEL: @loop_cond(
308 ; CHECK-NEXT:  entry:
309 ; CHECK-NEXT:    br label [[LOOP:%.*]]
310 ; CHECK:       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]]
317 ; CHECK:       exit:
318 ; CHECK-NEXT:    ret i16 [[COUNT]]
320 entry:
321   br label %loop
323 loop:
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
331 exit:
332   ret i16 %count
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
344   ret i16 %sel
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
359   ret i16 %sel
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
374   ret i16 %sel
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
387   ret i16 %sel
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
403   ret i16 %sel
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
422   ret i16 %sel
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
437   ret i16 %sel
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
452   ret i16 %sel
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
465   ret i16 %sel
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
478   ret i16 %sel
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
491   ret i16 %sel
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
504   ret i16 %sel
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
517   ret i16 %sel
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
530   ret i32 %sel
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
543   ret i16 %sel
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]]
552   %and = and i16 %x, 7
553   %cmp = icmp ult i16 %x, 8
554   %sel = select i1 %cmp, i16 %and, i16 24
555   ret i16 %sel
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]]
565   %and = and i16 %x, 7
566   %cmp = icmp ult i16 %x, 8
567   %sel = select i1 %cmp, i16 %and, i16 24
568   ret i16 %sel
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
579   %and = and i16 %x, 7
580   %cmp = icmp ult i16 %x, 8
581   %sel = select i1 %cmp, i16 %and, i16 24
582   ret i16 %sel
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
594   %and = and i16 %x, 7
595   %cmp = icmp ult i16 %x, 8
596   %sel = select i1 %cmp, i16 %and, i16 24
597   ret i16 %sel
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
614   ret i32 %spec.select
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
631   ret i64 %res