1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 define i32 @poison(i32 %x) {
5 ; CHECK-LABEL: @poison(
6 ; CHECK-NEXT: ret i32 poison
8 %v = and i32 %x, poison
12 ; (X | Y) & (X | ~Y) --> X (commuted 8 ways)
14 define i8 @or_or_not_commute0(i8 %x, i8 %y) {
15 ; CHECK-LABEL: @or_or_not_commute0(
16 ; CHECK-NEXT: ret i8 [[X:%.*]]
20 %xorynot = or i8 %x, %ynot
21 %and = and i8 %xory, %xorynot
25 define <2 x i5> @or_or_not_commute1(<2 x i5> %x, <2 x i5> %y) {
26 ; CHECK-LABEL: @or_or_not_commute1(
27 ; CHECK-NEXT: ret <2 x i5> [[X:%.*]]
29 %ynot = xor <2 x i5> %y, <i5 -1, i5 -1>
30 %xory = or <2 x i5> %x, %y
31 %xorynot = or <2 x i5> %x, %ynot
32 %and = and <2 x i5> %xorynot, %xory
36 define <2 x i8> @or_or_not_commute2(<2 x i8> %x, <2 x i8> %y) {
37 ; CHECK-LABEL: @or_or_not_commute2(
38 ; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
40 %ynot = xor <2 x i8> %y, <i8 poison, i8 -1>
41 %xory = or <2 x i8> %x, %y
42 %xorynot = or <2 x i8> %ynot, %x
43 %and = and <2 x i8> %xory, %xorynot
47 define i8 @or_or_not_commute3(i8 %x, i8 %y) {
48 ; CHECK-LABEL: @or_or_not_commute3(
49 ; CHECK-NEXT: ret i8 [[X:%.*]]
53 %xorynot = or i8 %ynot, %x
54 %and = and i8 %xorynot, %xory
57 define i8 @or_or_not_commute4(i8 %x, i8 %y) {
58 ; CHECK-LABEL: @or_or_not_commute4(
59 ; CHECK-NEXT: ret i8 [[X:%.*]]
63 %xorynot = or i8 %x, %ynot
64 %and = and i8 %xory, %xorynot
68 define i8 @or_or_not_commute5(i8 %x, i8 %y) {
69 ; CHECK-LABEL: @or_or_not_commute5(
70 ; CHECK-NEXT: ret i8 [[X:%.*]]
74 %xorynot = or i8 %x, %ynot
75 %and = and i8 %xorynot, %xory
79 define i8 @or_or_not_commute6(i8 %x, i8 %y) {
80 ; CHECK-LABEL: @or_or_not_commute6(
81 ; CHECK-NEXT: ret i8 [[X:%.*]]
85 %xorynot = or i8 %ynot, %x
86 %and = and i8 %xory, %xorynot
90 define i8 @or_or_not_commute7(i8 %x, i8 %y) {
91 ; CHECK-LABEL: @or_or_not_commute7(
92 ; CHECK-NEXT: ret i8 [[X:%.*]]
96 %xorynot = or i8 %ynot, %x
97 %and = and i8 %xorynot, %xory
101 ; negative test - wrong logic op
103 define i8 @or_xor_not(i8 %x, i8 %y) {
104 ; CHECK-LABEL: @or_xor_not(
105 ; CHECK-NEXT: [[YNOT:%.*]] = xor i8 [[Y:%.*]], -1
106 ; CHECK-NEXT: [[XXORY:%.*]] = xor i8 [[Y]], [[X:%.*]]
107 ; CHECK-NEXT: [[XORYNOT:%.*]] = or i8 [[X]], [[YNOT]]
108 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[XORYNOT]], [[XXORY]]
109 ; CHECK-NEXT: ret i8 [[AND]]
111 %ynot = xor i8 %y, -1
112 %xxory = xor i8 %y, %x
113 %xorynot = or i8 %x, %ynot
114 %and = and i8 %xorynot, %xxory
118 ; negative test - must have common operands
120 define i8 @or_or_not_no_common_op(i8 %x, i8 %y, i8 %z) {
121 ; CHECK-LABEL: @or_or_not_no_common_op(
122 ; CHECK-NEXT: [[XORZ:%.*]] = or i8 [[Z:%.*]], [[X:%.*]]
123 ; CHECK-NEXT: [[YNOT:%.*]] = xor i8 [[Y:%.*]], -1
124 ; CHECK-NEXT: [[XORYNOT:%.*]] = or i8 [[X]], [[YNOT]]
125 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[XORYNOT]], [[XORZ]]
126 ; CHECK-NEXT: ret i8 [[AND]]
129 %ynot = xor i8 %y, -1
130 %xorynot = or i8 %x, %ynot
131 %and = and i8 %xorynot, %xorz
135 ; ((X | Y) ^ X ) & ((X | Y) ^ Y) --> 0
137 define i8 @or_xor(i8 %x, i8 %y) {
138 ; CHECK-LABEL: @or_xor(
139 ; CHECK-NEXT: ret i8 0
142 %xor1 = xor i8 %or, %x
143 %xor2 = xor i8 %or, %y
144 %and = and i8 %xor1, %xor2
148 ; ((X | Y) ^ Y ) & ((X | Y) ^ X) --> 0
150 define i8 @or_xor_commute1(i8 %x, i8 %y) {
151 ; CHECK-LABEL: @or_xor_commute1(
152 ; CHECK-NEXT: ret i8 0
155 %xor1 = xor i8 %or, %x
156 %xor2 = xor i8 %or, %y
157 %and = and i8 %xor2, %xor1
161 ; (X ^ (X | Y) ) & (Y ^ (X | Y)) --> 0
163 define i71 @or_xor_commute2(i71 %x, i71 %y) {
164 ; CHECK-LABEL: @or_xor_commute2(
165 ; CHECK-NEXT: ret i71 0
168 %xor1 = xor i71 %x, %or
169 %xor2 = xor i71 %y, %or
170 %and = and i71 %xor1, %xor2
174 ; (Y ^ (X | Y) ) & (X ^ (X | Y)) --> 0
176 define <2 x i64> @or_xor_commute3(<2 x i64> %x, <2 x i64> %y) {
177 ; CHECK-LABEL: @or_xor_commute3(
178 ; CHECK-NEXT: ret <2 x i64> zeroinitializer
180 %or = or <2 x i64> %x, %y
181 %xor1 = xor <2 x i64> %y, %or
182 %xor2 = xor <2 x i64> %x, %or
183 %and = and <2 x i64> %xor1, %xor2
187 ; ((X | Y) ^ X ) & (Y ^ (X | Y)) --> 0
189 define i32 @or_xor_commute4(i32 %x, i32 %y) {
190 ; CHECK-LABEL: @or_xor_commute4(
191 ; CHECK-NEXT: ret i32 0
194 %xor1 = xor i32 %or, %x
195 %xor2 = xor i32 %y, %or
196 %and = and i32 %xor1, %xor2
200 ; ((X | Y) ^ Y ) & (X ^ (X | Y)) --> 0
202 define i32 @or_xor_commute5(i32 %x, i32 %y) {
203 ; CHECK-LABEL: @or_xor_commute5(
204 ; CHECK-NEXT: ret i32 0
207 %xor1 = xor i32 %or, %y
208 %xor2 = xor i32 %x, %or
209 %and = and i32 %xor1, %xor2
213 ; (X ^ (X | Y) ) & ((X | Y) ^ Y) --> 0
215 define i32 @or_xor_commute6(i32 %x, i32 %y) {
216 ; CHECK-LABEL: @or_xor_commute6(
217 ; CHECK-NEXT: ret i32 0
220 %xor1 = xor i32 %x, %or
221 %xor2 = xor i32 %or, %y
222 %and = and i32 %xor1, %xor2
226 ; (Y ^ (X | Y) ) & ((X | Y) ^ X) --> 0
228 define i32 @or_xor_commute7(i32 %x, i32 %y) {
229 ; CHECK-LABEL: @or_xor_commute7(
230 ; CHECK-NEXT: ret i32 0
233 %xor1 = xor i32 %y, %or
234 %xor2 = xor i32 %or, %x
235 %and = and i32 %xor1, %xor2
239 ; (Y ^ (X | Y) ) & ((X | Y) ^ X) --> 0
241 define i32 @or_xor_complex_op(i32 %x, i32 %in) {
242 ; CHECK-LABEL: @or_xor_complex_op(
243 ; CHECK-NEXT: ret i32 0
247 %xor1 = xor i32 %y, %or
248 %xor2 = xor i32 %or, %x
249 %and = and i32 %xor1, %xor2
253 define i32 @or_xor_limitation(i32 %x, i32 %y) {
254 ; CHECK-LABEL: @or_xor_limitation(
255 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
256 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[X]], [[Y]]
257 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[Y]], [[OR1]]
258 ; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[OR2]], [[X]]
259 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
260 ; CHECK-NEXT: ret i32 [[AND]]
264 %xor1 = xor i32 %y, %or1
265 %xor2 = xor i32 %or2, %x
266 %and = and i32 %xor1, %xor2