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: [[N1_DEMORGAN:%.*]] = or <2 x i4> [[Y:%.*]], [[MASK:%.*]]
98 ; CHECK-NEXT: [[N1:%.*]] = xor <2 x i4> [[N1_DEMORGAN]], <i4 -1, i4 -1>
99 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
100 ; CHECK-NEXT: ret <2 x i4> [[R]]
102 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
103 %n0 = xor <2 x i4> <i4 -1, i4 -1>, %y ; %x
104 %n1 = and <2 x i4> %n0, %notmask
105 %r = xor <2 x i4> %n1, %y
109 define <2 x i4> @in_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) {
110 ; CHECK-LABEL: @in_constant_6_vary_invmask(
111 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 6>
112 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
113 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 6>
114 ; CHECK-NEXT: ret <2 x i4> [[R]]
116 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
117 %n0 = xor <2 x i4> %y, <i4 6, i4 6> ; %x
118 %n1 = and <2 x i4> %n0, %notmask
119 %r = xor <2 x i4> %n1, %y
123 define <2 x i4> @in_constant_6_vary_invmask_nonsplat(<2 x i4> %y, <2 x i4> %mask) {
124 ; CHECK-LABEL: @in_constant_6_vary_invmask_nonsplat(
125 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 7>
126 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
127 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 7>
128 ; CHECK-NEXT: ret <2 x i4> [[R]]
130 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
131 %n0 = xor <2 x i4> %y, <i4 6, i4 7> ; %x
132 %n1 = and <2 x i4> %n0, %notmask
133 %r = xor <2 x i4> %n1, %y
137 define <3 x i4> @in_constant_6_vary_invmask_undef(<3 x i4> %y, <3 x i4> %mask) {
138 ; CHECK-LABEL: @in_constant_6_vary_invmask_undef(
139 ; CHECK-NEXT: [[N0:%.*]] = xor <3 x i4> [[Y:%.*]], <i4 6, i4 undef, i4 6>
140 ; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i4> [[N0]], [[MASK:%.*]]
141 ; CHECK-NEXT: [[R:%.*]] = xor <3 x i4> [[TMP1]], <i4 6, i4 undef, i4 6>
142 ; CHECK-NEXT: ret <3 x i4> [[R]]
144 %notmask = xor <3 x i4> %mask, <i4 -1, i4 undef, i4 -1>
145 %n0 = xor <3 x i4> %y, <i4 6, i4 undef, i4 6> ; %x
146 %n1 = and <3 x i4> %n0, %notmask
147 %r = xor <3 x i4> %n1, %y
151 ; ============================================================================ ;
153 ; ============================================================================ ;
155 ; Used to make sure that the IR complexity sorting does not interfere.
156 declare <2 x i4> @gen4()
158 ; FIXME: should %n1 = and <2 x i4> %im, %n0 swapped order pattern be tested?
160 define <2 x i4> @c_1_0_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
161 ; CHECK-LABEL: @c_1_0_0(
162 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
163 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
164 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
165 ; CHECK-NEXT: ret <2 x i4> [[R]]
167 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
168 %n0 = xor <2 x i4> %y, %x ; swapped order
169 %n1 = and <2 x i4> %n0, %im
170 %r = xor <2 x i4> %n1, %y
174 define <2 x i4> @c_0_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
175 ; CHECK-LABEL: @c_0_1_0(
176 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
177 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
178 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
179 ; CHECK-NEXT: ret <2 x i4> [[R]]
181 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
182 %n0 = xor <2 x i4> %x, %y
183 %n1 = and <2 x i4> %n0, %im
184 %r = xor <2 x i4> %n1, %x ; %x instead of %y
188 define <2 x i4> @c_0_0_1 (<2 x i4> %m) {
189 ; CHECK-LABEL: @c_0_0_1(
190 ; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4()
191 ; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4()
192 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X]], [[Y]]
193 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
194 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
195 ; CHECK-NEXT: ret <2 x i4> [[R]]
197 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
198 %x = call <2 x i4> @gen4()
199 %y = call <2 x i4> @gen4()
200 %n0 = xor <2 x i4> %x, %y
201 %n1 = and <2 x i4> %n0, %im
202 %r = xor <2 x i4> %y, %n1 ; swapped order
206 define <2 x i4> @c_1_1_0 (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
207 ; CHECK-LABEL: @c_1_1_0(
208 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
209 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
210 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
211 ; CHECK-NEXT: ret <2 x i4> [[R]]
213 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
214 %n0 = xor <2 x i4> %y, %x ; swapped order
215 %n1 = and <2 x i4> %n0, %im
216 %r = xor <2 x i4> %n1, %x ; %x instead of %y
220 define <2 x i4> @c_1_0_1 (<2 x i4> %x, <2 x i4> %m) {
221 ; CHECK-LABEL: @c_1_0_1(
222 ; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4()
223 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y]], [[X:%.*]]
224 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
225 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
226 ; CHECK-NEXT: ret <2 x i4> [[R]]
228 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
229 %y = call <2 x i4> @gen4()
230 %n0 = xor <2 x i4> %y, %x ; swapped order
231 %n1 = and <2 x i4> %n0, %im
232 %r = xor <2 x i4> %y, %n1 ; swapped order
236 define <2 x i4> @c_0_1_1 (<2 x i4> %y, <2 x i4> %m) {
237 ; CHECK-LABEL: @c_0_1_1(
238 ; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4()
239 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X]], [[Y:%.*]]
240 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
241 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
242 ; CHECK-NEXT: ret <2 x i4> [[R]]
244 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
245 %x = call <2 x i4> @gen4()
246 %n0 = xor <2 x i4> %x, %y
247 %n1 = and <2 x i4> %n0, %im
248 %r = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y
252 define <2 x i4> @c_1_1_1 (<2 x i4> %m) {
253 ; CHECK-LABEL: @c_1_1_1(
254 ; CHECK-NEXT: [[X:%.*]] = call <2 x i4> @gen4()
255 ; CHECK-NEXT: [[Y:%.*]] = call <2 x i4> @gen4()
256 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y]], [[X]]
257 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
258 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[Y]]
259 ; CHECK-NEXT: ret <2 x i4> [[R]]
261 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
262 %x = call <2 x i4> @gen4()
263 %y = call <2 x i4> @gen4()
264 %n0 = xor <2 x i4> %y, %x ; swapped order
265 %n1 = and <2 x i4> %n0, %im
266 %r = xor <2 x i4> %x, %n1 ; swapped order, %x instead of %y
270 define <2 x i4> @commutativity_constant_varx_6_invmask(<2 x i4> %x, <2 x i4> %mask) {
271 ; CHECK-LABEL: @commutativity_constant_varx_6_invmask(
272 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 6>
273 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
274 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
275 ; CHECK-NEXT: ret <2 x i4> [[R]]
277 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
278 %n0 = xor <2 x i4> %x, <i4 6, i4 6> ; %x
279 %n1 = and <2 x i4> %notmask, %n0 ; swapped
280 %r = xor <2 x i4> %n1, <i4 6, i4 6>
284 define <2 x i4> @commutativity_constant_6_vary_invmask(<2 x i4> %y, <2 x i4> %mask) {
285 ; CHECK-LABEL: @commutativity_constant_6_vary_invmask(
286 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[Y:%.*]], <i4 6, i4 6>
287 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[MASK:%.*]]
288 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], <i4 6, i4 6>
289 ; CHECK-NEXT: ret <2 x i4> [[R]]
291 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
292 %n0 = xor <2 x i4> %y, <i4 6, i4 6> ; %x
293 %n1 = and <2 x i4> %notmask, %n0 ; swapped
294 %r = xor <2 x i4> %n1, %y
298 ; ============================================================================ ;
299 ; Negative tests. Should not be folded.
300 ; ============================================================================ ;
304 declare void @use4(<2 x i4>)
306 define <2 x i4> @n_oneuse_D_is_ok (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
307 ; CHECK-LABEL: @n_oneuse_D_is_ok(
308 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
309 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i4> [[N0]], [[M:%.*]]
310 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[TMP1]], [[X]]
311 ; CHECK-NEXT: call void @use4(<2 x i4> [[N0]])
312 ; CHECK-NEXT: ret <2 x i4> [[R]]
314 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
315 %n0 = xor <2 x i4> %x, %y ; two uses of %n0, THIS IS OK!
316 %n1 = and <2 x i4> %n0, %im
317 %r = xor <2 x i4> %n1, %y
318 call void @use4(<2 x i4> %n0)
322 define <2 x i4> @n_oneuse_A (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
323 ; CHECK-LABEL: @n_oneuse_A(
324 ; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 -1>
325 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
326 ; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
327 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
328 ; CHECK-NEXT: call void @use4(<2 x i4> [[N1]])
329 ; CHECK-NEXT: ret <2 x i4> [[R]]
331 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
332 %n0 = xor <2 x i4> %x, %y
333 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
334 %r = xor <2 x i4> %n1, %y
335 call void @use4(<2 x i4> %n1)
339 define <2 x i4> @n_oneuse_AD (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
340 ; CHECK-LABEL: @n_oneuse_AD(
341 ; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 -1>
342 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
343 ; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
344 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
345 ; CHECK-NEXT: call void @use4(<2 x i4> [[N0]])
346 ; CHECK-NEXT: call void @use4(<2 x i4> [[N1]])
347 ; CHECK-NEXT: ret <2 x i4> [[R]]
349 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
350 %n0 = xor <2 x i4> %x, %y ; two uses of %n0 IS OK
351 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
352 %r = xor <2 x i4> %n1, %y
353 call void @use4(<2 x i4> %n0)
354 call void @use4(<2 x i4> %n1)
358 ; Some third variable is used
360 define <2 x i4> @n_third_var (<2 x i4> %x, <2 x i4> %y, <2 x i4> %z, <2 x i4> %m) {
361 ; CHECK-LABEL: @n_third_var(
362 ; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 -1>
363 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
364 ; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
365 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Z:%.*]]
366 ; CHECK-NEXT: ret <2 x i4> [[R]]
368 %im = xor <2 x i4> %m, <i4 -1, i4 -1>
369 %n0 = xor <2 x i4> %x, %y
370 %n1 = and <2 x i4> %n0, %im
371 %r = xor <2 x i4> %n1, %z ; not %x or %y
376 define <2 x i4> @n_third_var_const(<2 x i4> %x, <2 x i4> %y, <2 x i4> %mask) {
377 ; CHECK-LABEL: @n_third_var_const(
378 ; CHECK-NEXT: [[NOTMASK:%.*]] = xor <2 x i4> [[MASK:%.*]], <i4 -1, i4 -1>
379 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], <i4 6, i4 7>
380 ; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[NOTMASK]]
381 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], <i4 7, i4 6>
382 ; CHECK-NEXT: ret <2 x i4> [[R]]
384 %notmask = xor <2 x i4> %mask, <i4 -1, i4 -1>
385 %n0 = xor <2 x i4> %x, <i4 6, i4 7> ; %x
386 %n1 = and <2 x i4> %n0, %notmask
387 %r = xor <2 x i4> %n1, <i4 7, i4 6>
393 define <2 x i4> @n_badxor_splat (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
394 ; CHECK-LABEL: @n_badxor_splat(
395 ; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 1, i4 1>
396 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
397 ; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
398 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
399 ; CHECK-NEXT: ret <2 x i4> [[R]]
401 %im = xor <2 x i4> %m, <i4 1, i4 1> ; not -1
402 %n0 = xor <2 x i4> %x, %y
403 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
404 %r = xor <2 x i4> %n1, %y
408 define <2 x i4> @n_badxor (<2 x i4> %x, <2 x i4> %y, <2 x i4> %m) {
409 ; CHECK-LABEL: @n_badxor(
410 ; CHECK-NEXT: [[IM:%.*]] = xor <2 x i4> [[M:%.*]], <i4 -1, i4 1>
411 ; CHECK-NEXT: [[N0:%.*]] = xor <2 x i4> [[X:%.*]], [[Y:%.*]]
412 ; CHECK-NEXT: [[N1:%.*]] = and <2 x i4> [[N0]], [[IM]]
413 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i4> [[N1]], [[Y]]
414 ; CHECK-NEXT: ret <2 x i4> [[R]]
416 %im = xor <2 x i4> %m, <i4 -1, i4 1> ; not -1
417 %n0 = xor <2 x i4> %x, %y
418 %n1 = and <2 x i4> %n0, %im ; two uses of %n1, which is going to be replaced
419 %r = xor <2 x i4> %n1, %y