1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare i8 @llvm.smin.i8(i8, i8)
5 declare i8 @llvm.umin.i8(i8, i8)
6 declare i8 @llvm.smax.i8(i8, i8)
7 declare i8 @llvm.umax.i8(i8, i8)
9 declare void @llvm.assume(i1)
11 declare void @use.i8(i8)
12 declare void @use.i1(i1)
14 define i8 @xor_1(i8 %a, i1 %c, i8 %x, i8 %y) {
15 ; CHECK-LABEL: @xor_1(
16 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
17 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
18 ; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[TMP2]], [[A:%.*]]
19 ; CHECK-NEXT: ret i8 [[NOT_BA]]
23 %b = select i1 %c, i8 %nx, i8 %yy
25 %not_ba = xor i8 %ba, -1
29 define i8 @xor_2(i8 %a, i1 %c, i8 %x, i8 %y) {
30 ; CHECK-LABEL: @xor_2(
31 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
32 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
33 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[TMP2]], [[A:%.*]]
34 ; CHECK-NEXT: ret i8 [[NOT_AB]]
38 %b = select i1 %c, i8 %nx, i8 %yy
40 %not_ab = xor i8 %ab, -1
44 define i8 @xor_fail(i8 %a, i1 %c, i8 %x, i8 %y) {
45 ; CHECK-LABEL: @xor_fail(
46 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
47 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[Y:%.*]]
48 ; CHECK-NEXT: [[AB:%.*]] = xor i8 [[B]], [[A:%.*]]
49 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1
50 ; CHECK-NEXT: ret i8 [[NOT_AB]]
53 %b = select i1 %c, i8 %nx, i8 %y
55 %not_ab = xor i8 %ab, -1
59 define i8 @add_1(i8 %a, i1 %c, i8 %x, i8 %y) {
60 ; CHECK-LABEL: @add_1(
61 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
62 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
63 ; CHECK-NEXT: [[NOT_BA:%.*]] = sub i8 [[TMP2]], [[A:%.*]]
64 ; CHECK-NEXT: ret i8 [[NOT_BA]]
68 %b = select i1 %c, i8 %nx, i8 %yy
70 %not_ba = xor i8 %ba, -1
74 define i8 @add_2(i8 %a, i1 %c, i8 %x, i8 %y) {
75 ; CHECK-LABEL: @add_2(
76 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
77 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
78 ; CHECK-NEXT: [[NOT_AB:%.*]] = sub i8 [[TMP2]], [[A:%.*]]
79 ; CHECK-NEXT: ret i8 [[NOT_AB]]
83 %b = select i1 %c, i8 %nx, i8 %yy
85 %not_ab = xor i8 %ab, -1
89 define i8 @add_fail(i8 %a, i1 %c, i8 %x, i8 %y) {
90 ; CHECK-LABEL: @add_fail(
91 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], [[A:%.*]]
92 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123
93 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]
94 ; CHECK-NEXT: [[AB:%.*]] = add i8 [[B]], [[A]]
95 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1
96 ; CHECK-NEXT: ret i8 [[NOT_AB]]
100 %b = select i1 %c, i8 %nx, i8 %yy
102 %not_ab = xor i8 %ab, -1
106 define i8 @sub_1(i8 %a, i1 %c, i8 %x, i8 %y) {
107 ; CHECK-LABEL: @sub_1(
108 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
109 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
110 ; CHECK-NEXT: [[NOT_BA:%.*]] = add i8 [[TMP2]], [[A:%.*]]
111 ; CHECK-NEXT: ret i8 [[NOT_BA]]
115 %b = select i1 %c, i8 %nx, i8 %yy
117 %not_ba = xor i8 %ba, -1
121 define i8 @sub_2(i8 %a, i1 %c, i8 %x, i8 %y) {
122 ; CHECK-LABEL: @sub_2(
123 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
124 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
125 ; CHECK-NEXT: [[TMP3:%.*]] = add i8 [[TMP2]], [[A:%.*]]
126 ; CHECK-NEXT: [[NOT_AB:%.*]] = sub i8 -2, [[TMP3]]
127 ; CHECK-NEXT: ret i8 [[NOT_AB]]
131 %b = select i1 %c, i8 %nx, i8 %yy
133 %not_ab = xor i8 %ab, -1
137 ; Same as above but with a type larger than i64 to make sure we create -2
139 define i128 @sub_3(i128 %a, i1 %c, i128 %x, i128 %y) {
140 ; CHECK-LABEL: @sub_3(
141 ; CHECK-NEXT: [[TMP1:%.*]] = xor i128 [[Y:%.*]], -124
142 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i128 [[X:%.*]], i128 [[TMP1]]
143 ; CHECK-NEXT: [[TMP3:%.*]] = add i128 [[TMP2]], [[A:%.*]]
144 ; CHECK-NEXT: [[NOT_AB:%.*]] = sub i128 -2, [[TMP3]]
145 ; CHECK-NEXT: ret i128 [[NOT_AB]]
147 %nx = xor i128 %x, -1
148 %yy = xor i128 %y, 123
149 %b = select i1 %c, i128 %nx, i128 %yy
150 %ab = sub i128 %a, %b
151 %not_ab = xor i128 %ab, -1
155 define i8 @sub_fail(i8 %a, i1 %c, i8 %x, i8 %y) {
156 ; CHECK-LABEL: @sub_fail(
157 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
158 ; CHECK-NEXT: call void @use.i8(i8 [[NX]])
159 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
160 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[TMP1]]
161 ; CHECK-NEXT: [[NOT_BA:%.*]] = add i8 [[TMP2]], [[A:%.*]]
162 ; CHECK-NEXT: ret i8 [[NOT_BA]]
166 call void @use.i8(i8 %nx)
167 %b = select i1 %c, i8 %nx, i8 %yy
169 %not_ba = xor i8 %ba, -1
173 define i8 @ashr_1(i8 %a, i1 %c, i8 %x, i8 %y) {
174 ; CHECK-LABEL: @ashr_1(
175 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
176 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
177 ; CHECK-NEXT: [[NOT_BA:%.*]] = ashr i8 [[TMP2]], [[A:%.*]]
178 ; CHECK-NEXT: ret i8 [[NOT_BA]]
182 %b = select i1 %c, i8 %nx, i8 %yy
184 %not_ba = xor i8 %ba, -1
188 define i8 @ashr_2_fail(i8 %a, i1 %c, i8 %x, i8 %y) {
189 ; CHECK-LABEL: @ashr_2_fail(
190 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
191 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123
192 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]
193 ; CHECK-NEXT: [[AB:%.*]] = ashr i8 [[A:%.*]], [[B]]
194 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1
195 ; CHECK-NEXT: ret i8 [[NOT_AB]]
199 %b = select i1 %c, i8 %nx, i8 %yy
201 %not_ab = xor i8 %ab, -1
205 define i8 @select_1(i1 %cc, i8 %na, i8 %aa, i1 %c, i8 %x, i8 %y) {
206 ; CHECK-LABEL: @select_1(
207 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[NA:%.*]], [[AA:%.*]]
208 ; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[TMP1]], -46
209 ; CHECK-NEXT: [[TMP3:%.*]] = xor i8 [[Y:%.*]], -124
210 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP3]]
211 ; CHECK-NEXT: [[NOT_AB:%.*]] = select i1 [[CC:%.*]], i8 [[TMP2]], i8 [[TMP4]]
212 ; CHECK-NEXT: ret i8 [[NOT_AB]]
216 %b = select i1 %c, i8 %nx, i8 %yy
217 %nna = xor i8 %na, 45
218 %a = xor i8 %aa, %nna
219 %ab = select i1 %cc, i8 %a, i8 %b
220 %not_ab = xor i8 %ab, -1
224 define i8 @select_2(i1 %cc, i8 %na, i1 %c, i8 %x, i8 %y) {
225 ; CHECK-LABEL: @select_2(
226 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
227 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
228 ; CHECK-NEXT: [[TMP3:%.*]] = xor i8 [[NA:%.*]], -46
229 ; CHECK-NEXT: [[NOT_BA:%.*]] = select i1 [[CC:%.*]], i8 [[TMP2]], i8 [[TMP3]]
230 ; CHECK-NEXT: ret i8 [[NOT_BA]]
234 %b = select i1 %c, i8 %nx, i8 %yy
236 %ba = select i1 %cc, i8 %b, i8 %a
237 %not_ba = xor i8 %ba, -1
241 define i1 @select_logic_or_fail(i1 %cc, i1 %c, i1 %x, i8 %y) {
242 ; CHECK-LABEL: @select_logic_or_fail(
243 ; CHECK-NEXT: [[NX:%.*]] = xor i1 [[X:%.*]], true
244 ; CHECK-NEXT: [[YY:%.*]] = icmp eq i8 [[Y:%.*]], 123
245 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i1 [[NX]], i1 [[YY]]
246 ; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i1 [[B]], i1 false
247 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i1 [[AB]], true
248 ; CHECK-NEXT: ret i1 [[NOT_AB]]
251 %yy = icmp eq i8 %y, 123
252 %b = select i1 %c, i1 %nx, i1 %yy
253 %ab = select i1 %cc, i1 %b, i1 false
254 %not_ab = xor i1 %ab, -1
258 define i1 @select_logic_and_fail(i1 %cc, i1 %c, i1 %x, i8 %y) {
259 ; CHECK-LABEL: @select_logic_and_fail(
260 ; CHECK-NEXT: [[NX:%.*]] = xor i1 [[X:%.*]], true
261 ; CHECK-NEXT: [[YY:%.*]] = icmp eq i8 [[Y:%.*]], 123
262 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i1 [[NX]], i1 [[YY]]
263 ; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i1 true, i1 [[B]]
264 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i1 [[AB]], true
265 ; CHECK-NEXT: ret i1 [[NOT_AB]]
268 %yy = icmp eq i8 %y, 123
269 %b = select i1 %c, i1 %nx, i1 %yy
270 %ab = select i1 %cc, i1 true, i1 %b
271 %not_ab = xor i1 %ab, -1
275 define i8 @smin_1(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) {
276 ; CHECK-LABEL: @smin_1(
277 ; CHECK-NEXT: [[TMP1:%.*]] = sub i8 [[NA:%.*]], [[AA:%.*]]
278 ; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y:%.*]], -124
279 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP2]]
280 ; CHECK-NEXT: [[NOT_AB:%.*]] = call i8 @llvm.smax.i8(i8 [[TMP1]], i8 [[TMP3]])
281 ; CHECK-NEXT: ret i8 [[NOT_AB]]
285 %b = select i1 %c, i8 %nx, i8 %yy
286 %nna = xor i8 %na, -1
287 %a = add i8 %aa, %nna
288 %ab = call i8 @llvm.smin.i8(i8 %a, i8 %b)
289 %not_ab = xor i8 %ab, -1
293 define i8 @smin_1_fail(i8 %a, i1 %c, i8 %x, i8 %y) {
294 ; CHECK-LABEL: @smin_1_fail(
295 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
296 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123
297 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]
298 ; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smin.i8(i8 [[A:%.*]], i8 [[B]])
299 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1
300 ; CHECK-NEXT: ret i8 [[NOT_AB]]
304 %b = select i1 %c, i8 %nx, i8 %yy
305 %ab = call i8 @llvm.smin.i8(i8 %a, i8 %b)
306 %not_ab = xor i8 %ab, -1
310 define i8 @umin_1_fail(i1 %c, i8 %x, i8 %y) {
311 ; CHECK-LABEL: @umin_1_fail(
312 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
313 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[Y:%.*]]
314 ; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 85)
315 ; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1
316 ; CHECK-NEXT: ret i8 [[NOT_BA]]
319 %b = select i1 %c, i8 %nx, i8 %y
320 %ba = call i8 @llvm.umin.i8(i8 %b, i8 85)
321 %not_ba = xor i8 %ba, -1
325 define i8 @smax_1(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) {
326 ; CHECK-LABEL: @smax_1(
327 ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[NA:%.*]], [[AA:%.*]]
328 ; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[Y:%.*]], -124
329 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP2]]
330 ; CHECK-NEXT: [[NOT_AB:%.*]] = call i8 @llvm.smin.i8(i8 [[TMP1]], i8 [[TMP3]])
331 ; CHECK-NEXT: ret i8 [[NOT_AB]]
335 %b = select i1 %c, i8 %nx, i8 %yy
336 %nna = xor i8 %na, -1
337 %a = sub i8 %nna, %aa
338 %ab = call i8 @llvm.smax.i8(i8 %a, i8 %b)
339 %not_ab = xor i8 %ab, -1
343 define i8 @smax_1_fail(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) {
344 ; CHECK-LABEL: @smax_1_fail(
345 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
346 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123
347 ; CHECK-NEXT: call void @use.i8(i8 [[YY]])
348 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]
349 ; CHECK-NEXT: [[NNA:%.*]] = xor i8 [[NA:%.*]], -1
350 ; CHECK-NEXT: [[A:%.*]] = sub i8 [[NNA]], [[AA:%.*]]
351 ; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]])
352 ; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1
353 ; CHECK-NEXT: ret i8 [[NOT_AB]]
357 call void @use.i8(i8 %yy)
358 %b = select i1 %c, i8 %nx, i8 %yy
359 %nna = xor i8 %na, -1
360 %a = sub i8 %nna, %aa
361 %ab = call i8 @llvm.smax.i8(i8 %a, i8 %b)
362 %not_ab = xor i8 %ab, -1
366 define i8 @umax_1(i8 %na, i1 %c, i8 %x, i8 %y) {
367 ; CHECK-LABEL: @umax_1(
368 ; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124
369 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]]
370 ; CHECK-NEXT: [[NOT_BA:%.*]] = call i8 @llvm.umin.i8(i8 [[TMP2]], i8 -86)
371 ; CHECK-NEXT: ret i8 [[NOT_BA]]
375 %b = select i1 %c, i8 %nx, i8 %yy
376 %ba = call i8 @llvm.umax.i8(i8 %b, i8 85)
377 %not_ba = xor i8 %ba, -1
381 define i8 @umax_1_fail(i8 %na, i1 %c, i8 %x, i8 %y) {
382 ; CHECK-LABEL: @umax_1_fail(
383 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1
384 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123
385 ; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]]
386 ; CHECK-NEXT: call void @use.i8(i8 [[B]])
387 ; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 85)
388 ; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1
389 ; CHECK-NEXT: ret i8 [[NOT_BA]]
393 %b = select i1 %c, i8 %nx, i8 %yy
394 call void @use.i8(i8 %b)
395 %ba = call i8 @llvm.umax.i8(i8 %b, i8 85)
396 %not_ba = xor i8 %ba, -1
400 define i8 @sub_both_freely_invertable_always(i8 %x, i8 %y) {
401 ; CHECK-LABEL: @sub_both_freely_invertable_always(
402 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
403 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
404 ; CHECK-NEXT: [[R:%.*]] = sub i8 [[XX]], [[YY]]
405 ; CHECK-NEXT: ret i8 [[R]]
413 define i8 @add_both_freely_invertable_always(i8 %x, i8 %y) {
414 ; CHECK-LABEL: @add_both_freely_invertable_always(
415 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
416 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
417 ; CHECK-NEXT: [[R:%.*]] = add i8 [[XX]], [[YY]]
418 ; CHECK-NEXT: ret i8 [[R]]
426 define i8 @xor_both_freely_invertable_always(i8 %x, i8 %y) {
427 ; CHECK-LABEL: @xor_both_freely_invertable_always(
428 ; CHECK-NEXT: [[XX:%.*]] = add i8 [[X:%.*]], 123
429 ; CHECK-NEXT: [[YY:%.*]] = add i8 [[Y:%.*]], 45
430 ; CHECK-NEXT: [[R:%.*]] = xor i8 [[XX]], [[YY]]
431 ; CHECK-NEXT: ret i8 [[R]]
439 define i8 @ashr_both_freely_invertable_always(i8 %x, i8 %y) {
440 ; CHECK-LABEL: @ashr_both_freely_invertable_always(
441 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
442 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
443 ; CHECK-NEXT: [[R:%.*]] = ashr i8 [[XX]], [[YY]]
444 ; CHECK-NEXT: ret i8 [[R]]
448 %r = ashr i8 %xx, %yy
452 define i8 @select_both_freely_invertable_always(i1 %cc, i8 %x, i8 %y) {
453 ; CHECK-LABEL: @select_both_freely_invertable_always(
454 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
455 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
456 ; CHECK-NEXT: [[R:%.*]] = select i1 [[CC:%.*]], i8 [[XX]], i8 [[YY]]
457 ; CHECK-NEXT: ret i8 [[R]]
461 %r = select i1 %cc, i8 %xx, i8 %yy
465 define i8 @umin_both_freely_invertable_always(i8 %x, i8 %y) {
466 ; CHECK-LABEL: @umin_both_freely_invertable_always(
467 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
468 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
469 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[XX]], i8 [[YY]])
470 ; CHECK-NEXT: ret i8 [[R]]
474 %r = call i8 @llvm.umin.i8(i8 %xx, i8 %yy)
478 define i8 @umax_both_freely_invertable_always(i8 %x, i8 %y) {
479 ; CHECK-LABEL: @umax_both_freely_invertable_always(
480 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
481 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
482 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[XX]], i8 [[YY]])
483 ; CHECK-NEXT: ret i8 [[R]]
487 %r = call i8 @llvm.umax.i8(i8 %xx, i8 %yy)
491 define i8 @smin_both_freely_invertable_always(i8 %x, i8 %y) {
492 ; CHECK-LABEL: @smin_both_freely_invertable_always(
493 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
494 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
495 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[XX]], i8 [[YY]])
496 ; CHECK-NEXT: ret i8 [[R]]
500 %r = call i8 @llvm.smin.i8(i8 %xx, i8 %yy)
504 define i8 @smax_both_freely_invertable_always(i8 %x, i8 %y) {
505 ; CHECK-LABEL: @smax_both_freely_invertable_always(
506 ; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 123
507 ; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 45
508 ; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[XX]], i8 [[YY]])
509 ; CHECK-NEXT: ret i8 [[R]]
513 %r = call i8 @llvm.smax.i8(i8 %xx, i8 %yy)
517 define i8 @lshr_nneg(i8 %x, i8 %y) {
518 ; CHECK-LABEL: @lshr_nneg(
519 ; CHECK-NEXT: [[NEG:%.*]] = icmp slt i8 [[X:%.*]], 0
520 ; CHECK-NEXT: call void @llvm.assume(i1 [[NEG]])
521 ; CHECK-NEXT: [[SHR_NOT:%.*]] = ashr i8 [[X]], [[Y:%.*]]
522 ; CHECK-NEXT: ret i8 [[SHR_NOT]]
524 %neg = icmp slt i8 %x, 0
525 call void @llvm.assume(i1 %neg)
526 %x.not = xor i8 %x, -1
527 %shr = lshr i8 %x.not, %y
528 %shr.not = xor i8 %shr, -1
532 define i8 @lshr_not_nneg(i8 %x, i8 %y) {
533 ; CHECK-LABEL: @lshr_not_nneg(
534 ; CHECK-NEXT: [[X_NOT:%.*]] = xor i8 [[X:%.*]], -1
535 ; CHECK-NEXT: [[SHR:%.*]] = lshr i8 [[X_NOT]], [[Y:%.*]]
536 ; CHECK-NEXT: [[SHR_NOT:%.*]] = xor i8 [[SHR]], -1
537 ; CHECK-NEXT: ret i8 [[SHR_NOT]]
539 %x.not = xor i8 %x, -1
540 %shr = lshr i8 %x.not, %y
541 %shr.not = xor i8 %shr, -1
545 define i8 @lshr_not_nneg2(i8 %x) {
546 ; CHECK-LABEL: @lshr_not_nneg2(
547 ; CHECK-NEXT: [[SHR:%.*]] = lshr i8 [[X:%.*]], 1
548 ; CHECK-NEXT: [[SHR_NOT:%.*]] = or disjoint i8 [[SHR]], -128
549 ; CHECK-NEXT: ret i8 [[SHR_NOT]]
551 %x.not = xor i8 %x, -1
552 %shr = lshr i8 %x.not, 1
553 %shr.not = xor i8 %shr, -1
557 define i1 @test_inv_free(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
558 ; CHECK-LABEL: @test_inv_free(
560 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
562 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
564 ; CHECK-NEXT: br label [[EXIT]]
566 ; CHECK-NEXT: br label [[EXIT]]
568 ; CHECK-NEXT: [[VAL_NOT:%.*]] = phi i1 [ false, [[B1]] ], [ true, [[B2]] ], [ [[C3:%.*]], [[B3]] ]
569 ; CHECK-NEXT: [[COND_NOT:%.*]] = and i1 [[VAL_NOT]], [[C4:%.*]]
570 ; CHECK-NEXT: br i1 [[COND_NOT]], label [[B5:%.*]], label [[B4:%.*]]
572 ; CHECK-NEXT: ret i1 true
574 ; CHECK-NEXT: ret i1 false
577 br i1 %c1, label %b1, label %b2
579 br i1 %c2, label %exit, label %b3
583 %invc3 = xor i1 %c3, true
586 %val = phi i1 [ true, %b1 ], [ false, %b2 ], [ %invc3, %b3 ]
587 %inv = xor i1 %c4, true
588 %cond = or i1 %val, %inv
589 br i1 %cond, label %b4, label %b5
596 define i32 @test_inv_free_i32(i1 %c1, i1 %c2, i32 %c3, i32 %c4) {
597 ; CHECK-LABEL: @test_inv_free_i32(
599 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
601 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
603 ; CHECK-NEXT: br label [[EXIT]]
605 ; CHECK-NEXT: br label [[EXIT]]
607 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[B1]] ], [ -1, [[B2]] ], [ [[C3:%.*]], [[B3]] ]
608 ; CHECK-NEXT: [[COND:%.*]] = xor i32 [[TMP0]], [[C4:%.*]]
609 ; CHECK-NEXT: ret i32 [[COND]]
612 br i1 %c1, label %b1, label %b2
614 br i1 %c2, label %exit, label %b3
618 %invc3 = xor i32 %c3, -1
621 %val = phi i32 [ -1, %b1 ], [ 0, %b2 ], [ %invc3, %b3 ]
622 %inv = xor i32 %c4, -1
623 %cond = xor i32 %val, %inv
629 define i1 @test_inv_free_multiuse(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
630 ; CHECK-LABEL: @test_inv_free_multiuse(
632 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
634 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
636 ; CHECK-NEXT: br label [[EXIT]]
638 ; CHECK-NEXT: [[INVC3:%.*]] = xor i1 [[C3:%.*]], true
639 ; CHECK-NEXT: br label [[EXIT]]
641 ; CHECK-NEXT: [[VAL:%.*]] = phi i1 [ true, [[B1]] ], [ false, [[B2]] ], [ [[INVC3]], [[B3]] ]
642 ; CHECK-NEXT: call void @use.i1(i1 [[VAL]])
643 ; CHECK-NEXT: [[INV:%.*]] = xor i1 [[C4:%.*]], true
644 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[VAL]], [[INV]]
645 ; CHECK-NEXT: br i1 [[COND]], label [[B4:%.*]], label [[B5:%.*]]
647 ; CHECK-NEXT: ret i1 true
649 ; CHECK-NEXT: ret i1 false
652 br i1 %c1, label %b1, label %b2
654 br i1 %c2, label %exit, label %b3
658 %invc3 = xor i1 %c3, true
661 %val = phi i1 [ true, %b1 ], [ false, %b2 ], [ %invc3, %b3 ]
662 call void @use.i1(i1 %val)
663 %inv = xor i1 %c4, true
664 %cond = or i1 %val, %inv
665 br i1 %cond, label %b4, label %b5
672 define i32 @test_inv_free_i32_newinst(i1 %c1, i1 %c2, i32 %c3, i32 %c4) {
673 ; CHECK-LABEL: @test_inv_free_i32_newinst(
675 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
677 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
679 ; CHECK-NEXT: br label [[EXIT]]
681 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 -8, [[C3:%.*]]
682 ; CHECK-NEXT: br label [[EXIT]]
684 ; CHECK-NEXT: [[VAL:%.*]] = phi i32 [ -1, [[B1]] ], [ 0, [[B2]] ], [ [[ASHR]], [[B3]] ]
685 ; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[VAL]], [[C4:%.*]]
686 ; CHECK-NEXT: [[COND:%.*]] = xor i32 [[TMP0]], -1
687 ; CHECK-NEXT: ret i32 [[COND]]
690 br i1 %c1, label %b1, label %b2
692 br i1 %c2, label %exit, label %b3
696 %ashr = ashr i32 -8, %c3
699 %val = phi i32 [ -1, %b1 ], [ 0, %b2 ], [ %ashr, %b3 ]
700 %inv = xor i32 %c4, -1
701 %cond = xor i32 %val, %inv
705 define i1 @test_inv_free_loop(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
706 ; CHECK-LABEL: @test_inv_free_loop(
708 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
710 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
712 ; CHECK-NEXT: br label [[EXIT]]
714 ; CHECK-NEXT: [[INVC3:%.*]] = xor i1 [[C3:%.*]], true
715 ; CHECK-NEXT: br label [[EXIT]]
717 ; CHECK-NEXT: [[VAL:%.*]] = phi i1 [ true, [[B1]] ], [ false, [[B2]] ], [ [[INVC3]], [[B3]] ], [ [[NOT:%.*]], [[EXIT]] ]
718 ; CHECK-NEXT: [[INV:%.*]] = xor i1 [[C4:%.*]], true
719 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[VAL]], [[INV]]
720 ; CHECK-NEXT: [[NOT]] = xor i1 [[VAL]], true
721 ; CHECK-NEXT: br i1 [[COND]], label [[EXIT]], label [[B4:%.*]]
723 ; CHECK-NEXT: ret i1 true
726 br i1 %c1, label %b1, label %b2
728 br i1 %c2, label %exit, label %b3
732 %invc3 = xor i1 %c3, true
735 %val = phi i1 [ true, %b1 ], [ false, %b2 ], [ %invc3, %b3 ], [ %not, %exit ]
736 %inv = xor i1 %c4, true
737 %cond = or i1 %val, %inv
738 %not = xor i1 %val, true
739 br i1 %cond, label %exit, label %b4