Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / free-inversion.ll
bloba89887a586b5829919587f39bfe9f343ebf64cdb
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]]
21   %nx = xor i8 %x, -1
22   %yy = xor i8 %y, 123
23   %b = select i1 %c, i8 %nx, i8 %yy
24   %ba = xor i8 %b, %a
25   %not_ba = xor i8 %ba, -1
26   ret i8 %not_ba
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]]
36   %nx = xor i8 %x, -1
37   %yy = xor i8 %y, 123
38   %b = select i1 %c, i8 %nx, i8 %yy
39   %ab = xor i8 %a, %b
40   %not_ab = xor i8 %ab, -1
41   ret i8 %not_ab
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]]
52   %nx = xor i8 %x, -1
53   %b = select i1 %c, i8 %nx, i8 %y
54   %ab = xor i8 %a, %b
55   %not_ab = xor i8 %ab, -1
56   ret i8 %not_ab
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]]
66   %nx = xor i8 %x, -1
67   %yy = xor i8 %y, 123
68   %b = select i1 %c, i8 %nx, i8 %yy
69   %ba = add i8 %b, %a
70   %not_ba = xor i8 %ba, -1
71   ret i8 %not_ba
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]]
81   %nx = xor i8 %x, -1
82   %yy = xor i8 %y, 123
83   %b = select i1 %c, i8 %nx, i8 %yy
84   %ab = add i8 %a, %b
85   %not_ab = xor i8 %ab, -1
86   ret i8 %not_ab
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]]
98   %nx = xor i8 %x, %a
99   %yy = xor i8 %y, 123
100   %b = select i1 %c, i8 %nx, i8 %yy
101   %ab = add i8 %a, %b
102   %not_ab = xor i8 %ab, -1
103   ret i8 %not_ab
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]]
113   %nx = xor i8 %x, -1
114   %yy = xor i8 %y, 123
115   %b = select i1 %c, i8 %nx, i8 %yy
116   %ba = sub i8 %b, %a
117   %not_ba = xor i8 %ba, -1
118   ret i8 %not_ba
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]]
129   %nx = xor i8 %x, -1
130   %yy = xor i8 %y, 123
131   %b = select i1 %c, i8 %nx, i8 %yy
132   %ab = sub i8 %a, %b
133   %not_ab = xor i8 %ab, -1
134   ret i8 %not_ab
137 ; Same as above but with a type larger than i64 to make sure we create -2
138 ; correctly.
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
152   ret i128 %not_ab
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]]
164   %nx = xor i8 %x, -1
165   %yy = xor i8 %y, 123
166   call void @use.i8(i8 %nx)
167   %b = select i1 %c, i8 %nx, i8 %yy
168   %ba = sub i8 %b, %a
169   %not_ba = xor i8 %ba, -1
170   ret i8 %not_ba
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]]
180   %nx = xor i8 %x, -1
181   %yy = xor i8 %y, 123
182   %b = select i1 %c, i8 %nx, i8 %yy
183   %ba = ashr i8 %b, %a
184   %not_ba = xor i8 %ba, -1
185   ret i8 %not_ba
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]]
197   %nx = xor i8 %x, -1
198   %yy = xor i8 %y, 123
199   %b = select i1 %c, i8 %nx, i8 %yy
200   %ab = ashr i8 %a, %b
201   %not_ab = xor i8 %ab, -1
202   ret i8 %not_ab
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]]
214   %nx = xor i8 %x, -1
215   %yy = xor i8 %y, 123
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
221   ret i8 %not_ab
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]]
232   %nx = xor i8 %x, -1
233   %yy = xor i8 %y, 123
234   %b = select i1 %c, i8 %nx, i8 %yy
235   %a = xor i8 %na, 45
236   %ba = select i1 %cc, i8 %b, i8 %a
237   %not_ba = xor i8 %ba, -1
238   ret i8 %not_ba
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]]
250   %nx = xor i1 %x, -1
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
255   ret i1 %not_ab
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]]
267   %nx = xor i1 %x, -1
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
272   ret i1 %not_ab
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]]
283   %nx = xor i8 %x, -1
284   %yy = xor i8 %y, 123
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
290   ret i8 %not_ab
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]]
302   %nx = xor i8 %x, -1
303   %yy = xor i8 %y, 123
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
307   ret i8 %not_ab
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]]
318   %nx = xor i8 %x, -1
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
322   ret i8 %not_ba
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]]
333   %nx = xor i8 %x, -1
334   %yy = xor i8 %y, 123
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
340   ret i8 %not_ab
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]]
355   %nx = xor i8 %x, -1
356   %yy = xor i8 %y, 123
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
363   ret i8 %not_ab
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]]
373   %nx = xor i8 %x, -1
374   %yy = xor i8 %y, 123
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
378   ret i8 %not_ba
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]]
391   %nx = xor i8 %x, -1
392   %yy = xor i8 %y, 123
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
397   ret i8 %not_ba
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]]
407   %xx = xor i8 %x, 123
408   %yy = xor i8 %y, 45
409   %r = sub i8 %xx, %yy
410   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]]
420   %xx = xor i8 %x, 123
421   %yy = xor i8 %y, 45
422   %r = add i8 %xx, %yy
423   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]]
433   %xx = add i8 %x, 123
434   %yy = add i8 %y, 45
435   %r = xor i8 %xx, %yy
436   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]]
446   %xx = xor i8 %x, 123
447   %yy = xor i8 %y, 45
448   %r = ashr i8 %xx, %yy
449   ret i8 %r
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]]
459   %xx = xor i8 %x, 123
460   %yy = xor i8 %y, 45
461   %r = select i1 %cc, i8 %xx, i8 %yy
462   ret i8 %r
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]]
472   %xx = xor i8 %x, 123
473   %yy = xor i8 %y, 45
474   %r = call i8 @llvm.umin.i8(i8 %xx, i8 %yy)
475   ret i8 %r
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]]
485   %xx = xor i8 %x, 123
486   %yy = xor i8 %y, 45
487   %r = call i8 @llvm.umax.i8(i8 %xx, i8 %yy)
488   ret i8 %r
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]]
498   %xx = xor i8 %x, 123
499   %yy = xor i8 %y, 45
500   %r = call i8 @llvm.smin.i8(i8 %xx, i8 %yy)
501   ret i8 %r
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]]
511   %xx = xor i8 %x, 123
512   %yy = xor i8 %y, 45
513   %r = call i8 @llvm.smax.i8(i8 %xx, i8 %yy)
514   ret i8 %r
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
529   ret i8 %shr.not
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
542   ret i8 %shr.not
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
554   ret i8 %shr.not
557 define i1 @test_inv_free(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
558 ; CHECK-LABEL: @test_inv_free(
559 ; CHECK-NEXT:  entry:
560 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
561 ; CHECK:       b1:
562 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
563 ; CHECK:       b2:
564 ; CHECK-NEXT:    br label [[EXIT]]
565 ; CHECK:       b3:
566 ; CHECK-NEXT:    br label [[EXIT]]
567 ; CHECK:       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:%.*]]
571 ; CHECK:       b4:
572 ; CHECK-NEXT:    ret i1 true
573 ; CHECK:       b5:
574 ; CHECK-NEXT:    ret i1 false
576 entry:
577   br i1 %c1, label %b1, label %b2
579   br i1 %c2, label %exit, label %b3
581   br label %exit
583   %invc3 = xor i1 %c3, true
584   br label %exit
585 exit:
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
591   ret i1 true
593   ret i1 false
596 define i32 @test_inv_free_i32(i1 %c1, i1 %c2, i32 %c3, i32 %c4) {
597 ; CHECK-LABEL: @test_inv_free_i32(
598 ; CHECK-NEXT:  entry:
599 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
600 ; CHECK:       b1:
601 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
602 ; CHECK:       b2:
603 ; CHECK-NEXT:    br label [[EXIT]]
604 ; CHECK:       b3:
605 ; CHECK-NEXT:    br label [[EXIT]]
606 ; CHECK:       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]]
611 entry:
612   br i1 %c1, label %b1, label %b2
614   br i1 %c2, label %exit, label %b3
616   br label %exit
618   %invc3 = xor i32 %c3, -1
619   br label %exit
620 exit:
621   %val = phi i32 [ -1, %b1 ], [ 0, %b2 ], [ %invc3, %b3 ]
622   %inv = xor i32 %c4, -1
623   %cond = xor i32 %val, %inv
624   ret i32 %cond
627 ; Negative tests
629 define i1 @test_inv_free_multiuse(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
630 ; CHECK-LABEL: @test_inv_free_multiuse(
631 ; CHECK-NEXT:  entry:
632 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
633 ; CHECK:       b1:
634 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
635 ; CHECK:       b2:
636 ; CHECK-NEXT:    br label [[EXIT]]
637 ; CHECK:       b3:
638 ; CHECK-NEXT:    [[INVC3:%.*]] = xor i1 [[C3:%.*]], true
639 ; CHECK-NEXT:    br label [[EXIT]]
640 ; CHECK:       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:%.*]]
646 ; CHECK:       b4:
647 ; CHECK-NEXT:    ret i1 true
648 ; CHECK:       b5:
649 ; CHECK-NEXT:    ret i1 false
651 entry:
652   br i1 %c1, label %b1, label %b2
654   br i1 %c2, label %exit, label %b3
656   br label %exit
658   %invc3 = xor i1 %c3, true
659   br label %exit
660 exit:
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
667   ret i1 true
669   ret i1 false
672 define i32 @test_inv_free_i32_newinst(i1 %c1, i1 %c2, i32 %c3, i32 %c4) {
673 ; CHECK-LABEL: @test_inv_free_i32_newinst(
674 ; CHECK-NEXT:  entry:
675 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
676 ; CHECK:       b1:
677 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
678 ; CHECK:       b2:
679 ; CHECK-NEXT:    br label [[EXIT]]
680 ; CHECK:       b3:
681 ; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 -8, [[C3:%.*]]
682 ; CHECK-NEXT:    br label [[EXIT]]
683 ; CHECK:       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]]
689 entry:
690   br i1 %c1, label %b1, label %b2
692   br i1 %c2, label %exit, label %b3
694   br label %exit
696   %ashr = ashr i32 -8, %c3
697   br label %exit
698 exit:
699   %val = phi i32 [ -1, %b1 ], [ 0, %b2 ], [ %ashr, %b3 ]
700   %inv = xor i32 %c4, -1
701   %cond = xor i32 %val, %inv
702   ret i32 %cond
705 define i1 @test_inv_free_loop(i1 %c1, i1 %c2, i1 %c3, i1 %c4) {
706 ; CHECK-LABEL: @test_inv_free_loop(
707 ; CHECK-NEXT:  entry:
708 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[B1:%.*]], label [[B2:%.*]]
709 ; CHECK:       b1:
710 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[B3:%.*]]
711 ; CHECK:       b2:
712 ; CHECK-NEXT:    br label [[EXIT]]
713 ; CHECK:       b3:
714 ; CHECK-NEXT:    [[INVC3:%.*]] = xor i1 [[C3:%.*]], true
715 ; CHECK-NEXT:    br label [[EXIT]]
716 ; CHECK:       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:%.*]]
722 ; CHECK:       b4:
723 ; CHECK-NEXT:    ret i1 true
725 entry:
726   br i1 %c1, label %b1, label %b2
728   br i1 %c2, label %exit, label %b3
730   br label %exit
732   %invc3 = xor i1 %c3, true
733   br label %exit
734 exit:
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
741   ret i1 true