1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 ; X | ~(X | Y) --> X | ~Y
6 define i32 @test1(i32 %x, i32 %y) {
8 ; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
9 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
10 ; CHECK-NEXT: ret i32 [[Z]]
13 %not = xor i32 %or, -1
18 ; Commute (rename) the inner 'or' operands:
19 ; Y | ~(X | Y) --> ~X | Y
21 define i32 @test2(i32 %x, i32 %y) {
22 ; CHECK-LABEL: @test2(
23 ; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
24 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
25 ; CHECK-NEXT: ret i32 [[Z]]
28 %not = xor i32 %or, -1
33 ; X | ~(X ^ Y) --> X | ~Y
35 define i32 @test3(i32 %x, i32 %y) {
36 ; CHECK-LABEL: @test3(
37 ; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
38 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
39 ; CHECK-NEXT: ret i32 [[Z]]
42 %not = xor i32 %xor, -1
47 ; Commute (rename) the 'xor' operands:
48 ; Y | ~(X ^ Y) --> ~X | Y
50 define i32 @test4(i32 %x, i32 %y) {
51 ; CHECK-LABEL: @test4(
52 ; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
53 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
54 ; CHECK-NEXT: ret i32 [[Z]]
57 %not = xor i32 %xor, -1
62 define i32 @test5(i32 %x, i32 %y) {
63 ; CHECK-LABEL: @test5(
64 ; CHECK-NEXT: ret i32 -1
67 %not = xor i32 %and, -1
72 define i32 @test6(i32 %x, i32 %y) {
73 ; CHECK-LABEL: @test6(
74 ; CHECK-NEXT: ret i32 -1
77 %not = xor i32 %and, -1
82 define i32 @test7(i32 %x, i32 %y) {
83 ; CHECK-LABEL: @test7(
84 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
85 ; CHECK-NEXT: ret i32 [[Z]]
92 define i32 @test8(i32 %x, i32 %y) {
93 ; CHECK-LABEL: @test8(
94 ; CHECK-NEXT: [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
95 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
96 ; CHECK-NEXT: ret i32 [[Z]]
99 %xor = xor i32 %x, %not
104 define i32 @test9(i32 %x, i32 %y) {
105 ; CHECK-LABEL: @test9(
106 ; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
107 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
108 ; CHECK-NEXT: ret i32 [[Z]]
110 %not = xor i32 %x, -1
111 %xor = xor i32 %not, %y
116 define i32 @test10(i32 %A, i32 %B) {
117 ; CHECK-LABEL: @test10(
118 ; CHECK-NEXT: ret i32 -1
120 %xor1 = xor i32 %B, %A
121 %not = xor i32 %A, -1
122 %xor2 = xor i32 %not, %B
123 %or = or i32 %xor1, %xor2
127 define i32 @test10_commuted(i32 %A, i32 %B) {
128 ; CHECK-LABEL: @test10_commuted(
129 ; CHECK-NEXT: ret i32 -1
131 %xor1 = xor i32 %B, %A
132 %not = xor i32 %A, -1
133 %xor2 = xor i32 %not, %B
134 %or = or i32 %xor2, %xor1
138 ; (x | y) & ((~x) ^ y) -> (x & y)
139 define i32 @test11(i32 %x, i32 %y) {
140 ; CHECK-LABEL: @test11(
141 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
142 ; CHECK-NEXT: ret i32 [[AND]]
145 %neg = xor i32 %x, -1
146 %xor = xor i32 %neg, %y
147 %and = and i32 %or, %xor
151 ; ((~x) ^ y) & (x | y) -> (x & y)
152 define i32 @test12(i32 %x, i32 %y) {
153 ; CHECK-LABEL: @test12(
154 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
155 ; CHECK-NEXT: ret i32 [[AND]]
157 %neg = xor i32 %x, -1
158 %xor = xor i32 %neg, %y
160 %and = and i32 %xor, %or
164 define i32 @test12_commuted(i32 %x, i32 %y) {
165 ; CHECK-LABEL: @test12_commuted(
166 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
167 ; CHECK-NEXT: ret i32 [[AND]]
169 %neg = xor i32 %x, -1
170 %xor = xor i32 %neg, %y
172 %and = and i32 %xor, %or
176 ; ((x | y) ^ (x ^ y)) -> (x & y)
177 define i32 @test13(i32 %x, i32 %y) {
178 ; CHECK-LABEL: @test13(
179 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
180 ; CHECK-NEXT: ret i32 [[TMP1]]
188 ; ((x | ~y) ^ (~x | y)) -> x ^ y
189 define i32 @test14(i32 %x, i32 %y) {
190 ; CHECK-LABEL: @test14(
191 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
192 ; CHECK-NEXT: ret i32 [[XOR]]
194 %noty = xor i32 %y, -1
195 %notx = xor i32 %x, -1
196 %or1 = or i32 %x, %noty
197 %or2 = or i32 %notx, %y
198 %xor = xor i32 %or1, %or2
202 define i32 @test14_commuted(i32 %x, i32 %y) {
203 ; CHECK-LABEL: @test14_commuted(
204 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
205 ; CHECK-NEXT: ret i32 [[XOR]]
207 %noty = xor i32 %y, -1
208 %notx = xor i32 %x, -1
209 %or1 = or i32 %noty, %x
210 %or2 = or i32 %notx, %y
211 %xor = xor i32 %or1, %or2
215 ; ((x & ~y) ^ (~x & y)) -> x ^ y
216 define i32 @test15(i32 %x, i32 %y) {
217 ; CHECK-LABEL: @test15(
218 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
219 ; CHECK-NEXT: ret i32 [[XOR]]
221 %noty = xor i32 %y, -1
222 %notx = xor i32 %x, -1
223 %and1 = and i32 %x, %noty
224 %and2 = and i32 %notx, %y
225 %xor = xor i32 %and1, %and2
229 define i32 @test15_commuted(i32 %x, i32 %y) {
230 ; CHECK-LABEL: @test15_commuted(
231 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
232 ; CHECK-NEXT: ret i32 [[XOR]]
234 %noty = xor i32 %y, -1
235 %notx = xor i32 %x, -1
236 %and1 = and i32 %noty, %x
237 %and2 = and i32 %notx, %y
238 %xor = xor i32 %and1, %and2
242 define i32 @test16(i32 %a, i32 %b) {
243 ; CHECK-LABEL: @test16(
244 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 1
245 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]]
246 ; CHECK-NEXT: ret i32 [[XOR]]
249 %and1 = and i32 %or, 1
250 %and2 = and i32 %b, -2
251 %xor = or i32 %and1, %and2
255 define i8 @not_or(i8 %x) {
256 ; CHECK-LABEL: @not_or(
257 ; CHECK-NEXT: [[NOTX:%.*]] = or i8 [[X:%.*]], 7
258 ; CHECK-NEXT: [[OR:%.*]] = xor i8 [[NOTX]], -8
259 ; CHECK-NEXT: ret i8 [[OR]]
261 %notx = xor i8 %x, -1
266 define i8 @not_or_xor(i8 %x) {
267 ; CHECK-LABEL: @not_or_xor(
268 ; CHECK-NEXT: [[NOTX:%.*]] = or i8 [[X:%.*]], 7
269 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[NOTX]], -12
270 ; CHECK-NEXT: ret i8 [[XOR]]
272 %notx = xor i8 %x, -1
274 %xor = xor i8 %or, 12
278 define i8 @xor_or(i8 %x) {
279 ; CHECK-LABEL: @xor_or(
280 ; CHECK-NEXT: [[XOR:%.*]] = or i8 [[X:%.*]], 7
281 ; CHECK-NEXT: [[OR:%.*]] = xor i8 [[XOR]], 32
282 ; CHECK-NEXT: ret i8 [[OR]]
289 define i8 @xor_or2(i8 %x) {
290 ; CHECK-LABEL: @xor_or2(
291 ; CHECK-NEXT: [[XOR:%.*]] = or i8 [[X:%.*]], 7
292 ; CHECK-NEXT: [[OR:%.*]] = xor i8 [[XOR]], 32
293 ; CHECK-NEXT: ret i8 [[OR]]
300 define i8 @xor_or_xor(i8 %x) {
301 ; CHECK-LABEL: @xor_or_xor(
302 ; CHECK-NEXT: [[XOR1:%.*]] = or i8 [[X:%.*]], 7
303 ; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[XOR1]], 44
304 ; CHECK-NEXT: ret i8 [[XOR2]]
306 %xor1 = xor i8 %x, 33
308 %xor2 = xor i8 %or, 12
312 define i8 @or_xor_or(i8 %x) {
313 ; CHECK-LABEL: @or_xor_or(
314 ; CHECK-NEXT: [[XOR:%.*]] = or i8 [[X:%.*]], 39
315 ; CHECK-NEXT: [[OR2:%.*]] = xor i8 [[XOR]], 8
316 ; CHECK-NEXT: ret i8 [[OR2]]
319 %xor = xor i8 %or1, 12
324 define i8 @test17(i8 %A, i8 %B) {
325 ; CHECK-LABEL: @test17(
326 ; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
327 ; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A]], 33
328 ; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[NOT]], [[B]]
329 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[XOR1]], 33
330 ; CHECK-NEXT: [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
331 ; CHECK-NEXT: ret i8 [[RES]]
333 %xor1 = xor i8 %B, %A
335 %xor2 = xor i8 %not, %B
336 %or = or i8 %xor1, %xor2
337 %res = mul i8 %or, %xor2 ; to increase the use count for the xor
341 define i8 @test18(i8 %A, i8 %B) {
342 ; CHECK-LABEL: @test18(
343 ; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
344 ; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A]], 33
345 ; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[NOT]], [[B]]
346 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[XOR1]], 33
347 ; CHECK-NEXT: [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
348 ; CHECK-NEXT: ret i8 [[RES]]
350 %xor1 = xor i8 %B, %A
352 %xor2 = xor i8 %not, %B
353 %or = or i8 %xor2, %xor1
354 %res = mul i8 %or, %xor2 ; to increase the use count for the xor
358 ; ((x | y) ^ (~x | ~y)) -> ~(x ^ y)
359 define i32 @test19(i32 %x, i32 %y) {
360 ; CHECK-LABEL: @test19(
361 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
362 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1
363 ; CHECK-NEXT: ret i32 [[XOR]]
365 %noty = xor i32 %y, -1
366 %notx = xor i32 %x, -1
368 %or2 = or i32 %notx, %noty
369 %xor = xor i32 %or1, %or2
373 ; ((x | y) ^ (~y | ~x)) -> ~(x ^ y)
374 define i32 @test20(i32 %x, i32 %y) {
375 ; CHECK-LABEL: @test20(
376 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
377 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1
378 ; CHECK-NEXT: ret i32 [[XOR]]
380 %noty = xor i32 %y, -1
381 %notx = xor i32 %x, -1
383 %or2 = or i32 %noty, %notx
384 %xor = xor i32 %or1, %or2
388 ; ((~x | ~y) ^ (x | y)) -> ~(x ^ y)
389 define i32 @test21(i32 %x, i32 %y) {
390 ; CHECK-LABEL: @test21(
391 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
392 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1
393 ; CHECK-NEXT: ret i32 [[XOR]]
395 %noty = xor i32 %y, -1
396 %notx = xor i32 %x, -1
397 %or1 = or i32 %notx, %noty
399 %xor = xor i32 %or1, %or2
403 ; ((~x | ~y) ^ (y | x)) -> ~(x ^ y)
404 define i32 @test22(i32 %x, i32 %y) {
405 ; CHECK-LABEL: @test22(
406 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
407 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1
408 ; CHECK-NEXT: ret i32 [[XOR]]
410 %noty = xor i32 %y, -1
411 %notx = xor i32 %x, -1
412 %or1 = or i32 %notx, %noty
414 %xor = xor i32 %or1, %or2