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)
6 ; We can de-invert the M:
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
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
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>
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>
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>
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>
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
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
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
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
150 ; ============================================================================ ;
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
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
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
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
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
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
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
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>
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
297 ; ============================================================================ ;
298 ; Negative tests. Should not be folded.
299 ; ============================================================================ ;
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)
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)
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)
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
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>
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
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