[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / invert-variable-mask-in-masked-merge-vector.ll
blob44e12fb64b957834c9951bf01623da17d87dfc12
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; If we have a masked merge, in the form of: (M is not constant)
5 ;   ((x ^ y) & ~M) ^ y
6 ; We can de-invert the M:
7 ;   ((x ^ y) & M) ^ x
9 define <2 x i4> @vector (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
10 ; CHECK-LABEL: @vector(
11 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
12 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
13 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
14 ; CHECK-NEXT:    ret <2 x i4> [[R]]
16   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
17   %n0 = xor <2 x i4> %x, %y
18   %n1 = and <2 x i4> %n0, %im
19   %r  = xor <2 x i4> %n1, %y
20   ret <2 x i4> %r
23 define <3 x i4> @vector_undef (<3 x i4> %x, <3 x i4> %y, <3 x i4> %m) {
24 ; CHECK-LABEL: @vector_undef(
25 ; CHECK-NEXT:    [[N0:%.*]] = xor <3 x i4> [[X:%.*]], [[Y:%.*]]
26 ; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[N0]], [[M:%.*]]
27 ; CHECK-NEXT:    [[R:%.*]] = xor <3 x i4> [[TMP1]], [[X]]
28 ; CHECK-NEXT:    ret <3 x i4> [[R]]
30   %im = xor <3 x i4> %m, <i4 -1, i4 undef, i4 -1>
31   %n0 = xor <3 x i4> %x, %y
32   %n1 = and <3 x i4> %n0, %im
33   %r  = xor <3 x i4> %n1, %y
34   ret <3 x i4> %r
37 ; ============================================================================ ;
38 ; Various cases with %x and/or %y being a constant
39 ; ============================================================================ ;
41 define <2 x i4> @in_constant_varx_mone_invmask(<2 x i4> %x, <2 x i4> %mask) {
42 ; CHECK-LABEL: @in_constant_varx_mone_invmask(
43 ; CHECK-NEXT:    [[N1_DEMORGAN:%.*]] = or <2 x i4> [[X:%.*]], [[MASK:%.*]]
44 ; CHECK-NEXT:    ret <2 x i4> [[N1_DEMORGAN]]
46   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
47   %n0 = xor <2 x i4> %x, <i4 -1, i4 -1> ; %x
48   %n1 = and <2 x i4> %n0, %notmask
49   %r = xor <2 x i4> %n1, <i4 -1, i4 -1>
50   ret <2 x i4> %r
53 define <2 x i4> @in_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) {
54 ; CHECK-LABEL: @in_constant_varx_6_invmask(
55 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 6>
56 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
57 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
58 ; CHECK-NEXT:    ret <2 x i4> [[R]]
60   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
61   %n0 = xor <2 x i4> %x, <i4 6, i4 6> ; %x
62   %n1 = and <2 x i4> %n0, %notmask
63   %r = xor <2 x i4> %n1, <i4 6, i4 6>
64   ret <2 x i4> %r
67 define <2 x i4> @in_constant_varx_6_invmask_nonsplat(<2 x i4> %x, <2 x i4> %mask) {
68 ; CHECK-LABEL: @in_constant_varx_6_invmask_nonsplat(
69 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 7>
70 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
71 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
72 ; CHECK-NEXT:    ret <2 x i4> [[R]]
74   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
75   %n0 = xor <2 x i4> %x, <i4 6, i4 7> ; %x
76   %n1 = and <2 x i4> %n0, %notmask
77   %r = xor <2 x i4> %n1, <i4 6, i4 7>
78   ret <2 x i4> %r
81 define <3 x i4> @in_constant_varx_6_invmask_undef(<3 x i4> %x, <3 x i4> %mask) {
82 ; CHECK-LABEL: @in_constant_varx_6_invmask_undef(
83 ; CHECK-NEXT:    [[N0:%.*]] = xor <3 x i4> [[X:%.*]], <i4 6, i4 undef, i4 7>
84 ; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]]
85 ; CHECK-NEXT:    [[R:%.*]] = xor <3 x i4> [[TMP1]], [[X]]
86 ; CHECK-NEXT:    ret <3 x i4> [[R]]
88   %notmask = xor <3 x i4> %mask, <i4 -1, i4 undef, i4 -1>
89   %n0 = xor <3 x i4> %x, <i4 6, i4 undef, i4 7> ; %x
90   %n1 = and <3 x i4> %n0, %notmask
91   %r = xor <3 x i4> %n1, <i4 6, i4 undef, i4 7>
92   ret <3 x i4> %r
95 define <2 x i4> @in_constant_mone_vary_invmask(<2 x i4> %y, <2 x i4> %mask) {
96 ; CHECK-LABEL: @in_constant_mone_vary_invmask(
97 ; CHECK-NEXT:    [[MASK_NOT:%.*]] = xor <2 x i4> [[MASK:%.*]], <i4 -1, i4 -1>
98 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i4> [[MASK_NOT]], [[Y:%.*]]
99 ; CHECK-NEXT:    ret <2 x i4> [[R]]
101   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
102   %n0 = xor <2 x i4> <i4 -1, i4 -1>, %y ; %x
103   %n1 = and <2 x i4> %n0, %notmask
104   %r = xor <2 x i4> %n1, %y
105   ret <2 x i4> %r
108 define <2 x i4> @in_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) {
109 ; CHECK-LABEL: @in_constant_6_vary_invmask(
110 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 6>
111 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
112 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 6>
113 ; CHECK-NEXT:    ret <2 x i4> [[R]]
115   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
116   %n0 = xor <2 x i4> %y, <i4 6, i4 6> ; %x
117   %n1 = and <2 x i4> %n0, %notmask
118   %r = xor <2 x i4> %n1, %y
119   ret <2 x i4> %r
122 define <2 x i4> @in_constant_6_vary_invmask_nonsplat(<2 x i4> %y, <2 x i4> %mask) {
123 ; CHECK-LABEL: @in_constant_6_vary_invmask_nonsplat(
124 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 7>
125 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
126 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 7>
127 ; CHECK-NEXT:    ret <2 x i4> [[R]]
129   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
130   %n0 = xor <2 x i4> %y, <i4 6, i4 7> ; %x
131   %n1 = and <2 x i4> %n0, %notmask
132   %r = xor <2 x i4> %n1, %y
133   ret <2 x i4> %r
136 define <3 x i4> @in_constant_6_vary_invmask_undef(<3 x i4> %y, <3 x i4> %mask) {
137 ; CHECK-LABEL: @in_constant_6_vary_invmask_undef(
138 ; CHECK-NEXT:    [[N0:%.*]] = xor <3 x i4> [[Y:%.*]], <i4 6, i4 undef, i4 6>
139 ; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]]
140 ; CHECK-NEXT:    [[R:%.*]] = xor <3 x i4> [[TMP1]], <i4 6, i4 undef, i4 6>
141 ; CHECK-NEXT:    ret <3 x i4> [[R]]
143   %notmask = xor <3 x i4> %mask, <i4 -1, i4 undef, i4 -1>
144   %n0 = xor <3 x i4> %y, <i4 6, i4 undef, i4 6> ; %x
145   %n1 = and <3 x i4> %n0, %notmask
146   %r = xor <3 x i4> %n1, %y
147   ret <3 x i4> %r
150 ; ============================================================================ ;
151 ; Commutativity
152 ; ============================================================================ ;
154 ; Used to make sure that the IR complexity sorting does not interfere.
155 declare <2 x i4> @gen4()
157 ; FIXME: should  %n1 = and <2 x i4> %im, %n0  swapped order pattern be tested?
159 define <2 x i4> @c_1_0_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
160 ; CHECK-LABEL: @c_1_0_0(
161 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
162 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
163 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
164 ; CHECK-NEXT:    ret <2 x i4> [[R]]
166   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
167   %n0 = xor <2 x i4> %y, %x ; swapped order
168   %n1 = and <2 x i4> %n0, %im
169   %r  = xor <2 x i4> %n1, %y
170   ret <2 x i4> %r
173 define <2 x i4> @c_0_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
174 ; CHECK-LABEL: @c_0_1_0(
175 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
176 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
177 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
178 ; CHECK-NEXT:    ret <2 x i4> [[R]]
180   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
181   %n0 = xor <2 x i4> %x, %y
182   %n1 = and <2 x i4> %n0, %im
183   %r  = xor <2 x i4> %n1, %x ; %x instead of %y
184   ret <2 x i4> %r
187 define <2 x i4> @c_0_0_1 (<2 x i4> %m) {
188 ; CHECK-LABEL: @c_0_0_1(
189 ; CHECK-NEXT:    [[X:%.*]] = call <2 x i4> @gen4()
190 ; CHECK-NEXT:    [[Y:%.*]] = call <2 x i4> @gen4()
191 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X]], [[Y]]
192 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
193 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
194 ; CHECK-NEXT:    ret <2 x i4> [[R]]
196   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
197   %x  = call <2 x i4> @gen4()
198   %y  = call <2 x i4> @gen4()
199   %n0 = xor <2 x i4> %x, %y
200   %n1 = and <2 x i4> %n0, %im
201   %r  = xor <2 x i4> %y, %n1 ; swapped order
202   ret <2 x i4> %r
205 define <2 x i4> @c_1_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
206 ; CHECK-LABEL: @c_1_1_0(
207 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
208 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
209 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
210 ; CHECK-NEXT:    ret <2 x i4> [[R]]
212   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
213   %n0 = xor <2 x i4> %y, %x ; swapped order
214   %n1 = and <2 x i4> %n0, %im
215   %r  = xor <2 x i4> %n1, %x ; %x instead of %y
216   ret <2 x i4> %r
219 define <2 x i4> @c_1_0_1 (<2 x i4> %x, <2 x i4> %m) {
220 ; CHECK-LABEL: @c_1_0_1(
221 ; CHECK-NEXT:    [[Y:%.*]] = call <2 x i4> @gen4()
222 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y]], [[X:%.*]]
223 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
224 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
225 ; CHECK-NEXT:    ret <2 x i4> [[R]]
227   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
228   %y  = call <2 x i4> @gen4()
229   %n0 = xor <2 x i4> %y, %x ; swapped order
230   %n1 = and <2 x i4> %n0, %im
231   %r  = xor <2 x i4> %y, %n1 ; swapped order
232   ret <2 x i4> %r
235 define <2 x i4> @c_0_1_1 (<2 x i4> %y, <2 x i4> %m) {
236 ; CHECK-LABEL: @c_0_1_1(
237 ; CHECK-NEXT:    [[X:%.*]] = call <2 x i4> @gen4()
238 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X]], [[Y:%.*]]
239 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
240 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
241 ; CHECK-NEXT:    ret <2 x i4> [[R]]
243   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
244   %x  = call <2 x i4> @gen4()
245   %n0 = xor <2 x i4> %x, %y
246   %n1 = and <2 x i4> %n0, %im
247   %r  = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y
248   ret <2 x i4> %r
251 define <2 x i4> @c_1_1_1 (<2 x i4> %m) {
252 ; CHECK-LABEL: @c_1_1_1(
253 ; CHECK-NEXT:    [[X:%.*]] = call <2 x i4> @gen4()
254 ; CHECK-NEXT:    [[Y:%.*]] = call <2 x i4> @gen4()
255 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y]], [[X]]
256 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
257 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
258 ; CHECK-NEXT:    ret <2 x i4> [[R]]
260   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
261   %x  = call <2 x i4> @gen4()
262   %y  = call <2 x i4> @gen4()
263   %n0 = xor <2 x i4> %y, %x ; swapped order
264   %n1 = and <2 x i4> %n0, %im
265   %r  = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y
266   ret <2 x i4> %r
269 define <2 x i4> @commutativity_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) {
270 ; CHECK-LABEL: @commutativity_constant_varx_6_invmask(
271 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 6>
272 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
273 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
274 ; CHECK-NEXT:    ret <2 x i4> [[R]]
276   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
277   %n0 = xor <2 x i4> %x, <i4 6, i4 6> ; %x
278   %n1 = and <2 x i4> %notmask, %n0 ; swapped
279   %r = xor <2 x i4> %n1, <i4 6, i4 6>
280   ret <2 x i4> %r
283 define <2 x i4> @commutativity_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) {
284 ; CHECK-LABEL: @commutativity_constant_6_vary_invmask(
285 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 6>
286 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
287 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 6>
288 ; CHECK-NEXT:    ret <2 x i4> [[R]]
290   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
291   %n0 = xor <2 x i4> %y, <i4 6, i4 6> ; %x
292   %n1 = and <2 x i4> %notmask, %n0 ; swapped
293   %r = xor <2 x i4> %n1, %y
294   ret <2 x i4> %r
297 ; ============================================================================ ;
298 ; Negative tests. Should not be folded.
299 ; ============================================================================ ;
301 ; One use only.
303 declare void @use4(<2 x i4>)
305 define <2 x i4> @n_oneuse_D_is_ok (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
306 ; CHECK-LABEL: @n_oneuse_D_is_ok(
307 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
308 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
309 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
310 ; CHECK-NEXT:    call void @use4(<2 x i4> [[N0]])
311 ; CHECK-NEXT:    ret <2 x i4> [[R]]
313   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
314   %n0 = xor <2 x i4> %x, %y ; two uses of %n0, THIS IS OK!
315   %n1 = and <2 x i4> %n0, %im
316   %r  = xor <2 x i4> %n1, %y
317   call void @use4(<2 x i4> %n0)
318   ret <2 x i4> %r
321 define <2 x i4> @n_oneuse_A (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
322 ; CHECK-LABEL: @n_oneuse_A(
323 ; CHECK-NEXT:    [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 -1>
324 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
325 ; CHECK-NEXT:    [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
326 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
327 ; CHECK-NEXT:    call void @use4(<2 x i4> [[N1]])
328 ; CHECK-NEXT:    ret <2 x i4> [[R]]
330   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
331   %n0 = xor <2 x i4> %x, %y
332   %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
333   %r  = xor <2 x i4> %n1, %y
334   call void @use4(<2 x i4> %n1)
335   ret <2 x i4> %r
338 define <2 x i4> @n_oneuse_AD (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
339 ; CHECK-LABEL: @n_oneuse_AD(
340 ; CHECK-NEXT:    [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 -1>
341 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
342 ; CHECK-NEXT:    [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
343 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
344 ; CHECK-NEXT:    call void @use4(<2 x i4> [[N0]])
345 ; CHECK-NEXT:    call void @use4(<2 x i4> [[N1]])
346 ; CHECK-NEXT:    ret <2 x i4> [[R]]
348   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
349   %n0 = xor <2 x i4> %x, %y ; two uses of %n0 IS OK
350   %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
351   %r  = xor <2 x i4> %n1, %y
352   call void @use4(<2 x i4> %n0)
353   call void @use4(<2 x i4> %n1)
354   ret <2 x i4> %r
357 ; Some third variable is used
359 define <2 x i4> @n_third_var (<2 x i4> %x, <2 x i4> %y, <2 x i4> %z, <2 x i4> %m) {
360 ; CHECK-LABEL: @n_third_var(
361 ; CHECK-NEXT:    [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 -1>
362 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
363 ; CHECK-NEXT:    [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
364 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[N1]], [[Z:%.*]]
365 ; CHECK-NEXT:    ret <2 x i4> [[R]]
367   %im = xor <2 x i4> %m, <i4 -1, i4 -1>
368   %n0 = xor <2 x i4> %x, %y
369   %n1 = and <2 x i4> %n0, %im
370   %r  = xor <2 x i4> %n1, %z ; not %x or %y
371   ret <2 x i4> %r
375 define <2 x i4> @n_third_var_const(<2 x i4> %x, <2 x i4> %y, <2 x i4> %mask) {
376 ; CHECK-LABEL: @n_third_var_const(
377 ; CHECK-NEXT:    [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], <i4 -1, i4 -1>
378 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 7>
379 ; CHECK-NEXT:    [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]]
380 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[N1]], <i4 7, i4 6>
381 ; CHECK-NEXT:    ret <2 x i4> [[R]]
383   %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
384   %n0 = xor <2 x i4> %x, <i4 6, i4 7> ; %x
385   %n1 = and <2 x i4> %n0, %notmask
386   %r = xor <2 x i4> %n1, <i4 7, i4 6>
387   ret <2 x i4> %r
390 ; Bad xor
392 define <2 x i4> @n_badxor_splat (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
393 ; CHECK-LABEL: @n_badxor_splat(
394 ; CHECK-NEXT:    [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 1, i4 1>
395 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
396 ; CHECK-NEXT:    [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
397 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
398 ; CHECK-NEXT:    ret <2 x i4> [[R]]
400   %im = xor <2 x i4> %m, <i4 1, i4 1> ; not -1
401   %n0 = xor <2 x i4> %x, %y
402   %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
403   %r  = xor <2 x i4> %n1, %y
404   ret <2 x i4> %r
407 define <2 x i4> @n_badxor (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
408 ; CHECK-LABEL: @n_badxor(
409 ; CHECK-NEXT:    [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 1>
410 ; CHECK-NEXT:    [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
411 ; CHECK-NEXT:    [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
412 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
413 ; CHECK-NEXT:    ret <2 x i4> [[R]]
415   %im = xor <2 x i4> %m, <i4 -1, i4 1> ; not -1
416   %n0 = xor <2 x i4> %x, %y
417   %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
418   %r  = xor <2 x i4> %n1, %y
419   ret <2 x i4> %r