]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll
Vendor import of llvm trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / test / CodeGen / X86 / unfold-masked-merge-scalar-variablemask.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=-bmi < %s | FileCheck %s --check-prefix=CHECK-NOBMI
3 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefix=CHECK-BMI
4 ; https://bugs.llvm.org/show_bug.cgi?id=37104
5
6 define i8 @out8(i8 %x, i8 %y, i8 %mask) {
7 ; CHECK-NOBMI-LABEL: out8:
8 ; CHECK-NOBMI:       # %bb.0:
9 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
10 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
11 ; CHECK-NOBMI-NEXT:    notb %al
12 ; CHECK-NOBMI-NEXT:    andb %sil, %al
13 ; CHECK-NOBMI-NEXT:    orb %dil, %al
14 ; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
15 ; CHECK-NOBMI-NEXT:    retq
16 ;
17 ; CHECK-BMI-LABEL: out8:
18 ; CHECK-BMI:       # %bb.0:
19 ; CHECK-BMI-NEXT:    movl %edx, %eax
20 ; CHECK-BMI-NEXT:    andl %edx, %edi
21 ; CHECK-BMI-NEXT:    notb %al
22 ; CHECK-BMI-NEXT:    andb %sil, %al
23 ; CHECK-BMI-NEXT:    orb %dil, %al
24 ; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
25 ; CHECK-BMI-NEXT:    retq
26   %mx = and i8 %x, %mask
27   %notmask = xor i8 %mask, -1
28   %my = and i8 %y, %notmask
29   %r = or i8 %mx, %my
30   ret i8 %r
31 }
32
33 define i16 @out16(i16 %x, i16 %y, i16 %mask) {
34 ; CHECK-NOBMI-LABEL: out16:
35 ; CHECK-NOBMI:       # %bb.0:
36 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
37 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
38 ; CHECK-NOBMI-NEXT:    notl %eax
39 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
40 ; CHECK-NOBMI-NEXT:    orl %edi, %eax
41 ; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
42 ; CHECK-NOBMI-NEXT:    retq
43 ;
44 ; CHECK-BMI-LABEL: out16:
45 ; CHECK-BMI:       # %bb.0:
46 ; CHECK-BMI-NEXT:    andl %edx, %edi
47 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
48 ; CHECK-BMI-NEXT:    orl %edi, %eax
49 ; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
50 ; CHECK-BMI-NEXT:    retq
51   %mx = and i16 %x, %mask
52   %notmask = xor i16 %mask, -1
53   %my = and i16 %y, %notmask
54   %r = or i16 %mx, %my
55   ret i16 %r
56 }
57
58 define i32 @out32(i32 %x, i32 %y, i32 %mask) {
59 ; CHECK-NOBMI-LABEL: out32:
60 ; CHECK-NOBMI:       # %bb.0:
61 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
62 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
63 ; CHECK-NOBMI-NEXT:    notl %eax
64 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
65 ; CHECK-NOBMI-NEXT:    orl %edi, %eax
66 ; CHECK-NOBMI-NEXT:    retq
67 ;
68 ; CHECK-BMI-LABEL: out32:
69 ; CHECK-BMI:       # %bb.0:
70 ; CHECK-BMI-NEXT:    andl %edx, %edi
71 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
72 ; CHECK-BMI-NEXT:    orl %edi, %eax
73 ; CHECK-BMI-NEXT:    retq
74   %mx = and i32 %x, %mask
75   %notmask = xor i32 %mask, -1
76   %my = and i32 %y, %notmask
77   %r = or i32 %mx, %my
78   ret i32 %r
79 }
80
81 define i64 @out64(i64 %x, i64 %y, i64 %mask) {
82 ; CHECK-NOBMI-LABEL: out64:
83 ; CHECK-NOBMI:       # %bb.0:
84 ; CHECK-NOBMI-NEXT:    movq %rdx, %rax
85 ; CHECK-NOBMI-NEXT:    andq %rdx, %rdi
86 ; CHECK-NOBMI-NEXT:    notq %rax
87 ; CHECK-NOBMI-NEXT:    andq %rsi, %rax
88 ; CHECK-NOBMI-NEXT:    orq %rdi, %rax
89 ; CHECK-NOBMI-NEXT:    retq
90 ;
91 ; CHECK-BMI-LABEL: out64:
92 ; CHECK-BMI:       # %bb.0:
93 ; CHECK-BMI-NEXT:    andq %rdx, %rdi
94 ; CHECK-BMI-NEXT:    andnq %rsi, %rdx, %rax
95 ; CHECK-BMI-NEXT:    orq %rdi, %rax
96 ; CHECK-BMI-NEXT:    retq
97   %mx = and i64 %x, %mask
98   %notmask = xor i64 %mask, -1
99   %my = and i64 %y, %notmask
100   %r = or i64 %mx, %my
101   ret i64 %r
102 }
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104 ; Should be the same as the previous one.
105 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
106
107 define i8 @in8(i8 %x, i8 %y, i8 %mask) {
108 ; CHECK-NOBMI-LABEL: in8:
109 ; CHECK-NOBMI:       # %bb.0:
110 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
111 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
112 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
113 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
114 ; CHECK-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
115 ; CHECK-NOBMI-NEXT:    retq
116 ;
117 ; CHECK-BMI-LABEL: in8:
118 ; CHECK-BMI:       # %bb.0:
119 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
120 ; CHECK-BMI-NEXT:    andl %edx, %edi
121 ; CHECK-BMI-NEXT:    orl %edi, %eax
122 ; CHECK-BMI-NEXT:    # kill: def $al killed $al killed $eax
123 ; CHECK-BMI-NEXT:    retq
124   %n0 = xor i8 %x, %y
125   %n1 = and i8 %n0, %mask
126   %r = xor i8 %n1, %y
127   ret i8 %r
128 }
129
130 define i16 @in16(i16 %x, i16 %y, i16 %mask) {
131 ; CHECK-NOBMI-LABEL: in16:
132 ; CHECK-NOBMI:       # %bb.0:
133 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
134 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
135 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
136 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
137 ; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
138 ; CHECK-NOBMI-NEXT:    retq
139 ;
140 ; CHECK-BMI-LABEL: in16:
141 ; CHECK-BMI:       # %bb.0:
142 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
143 ; CHECK-BMI-NEXT:    andl %edx, %edi
144 ; CHECK-BMI-NEXT:    orl %edi, %eax
145 ; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
146 ; CHECK-BMI-NEXT:    retq
147   %n0 = xor i16 %x, %y
148   %n1 = and i16 %n0, %mask
149   %r = xor i16 %n1, %y
150   ret i16 %r
151 }
152
153 define i32 @in32(i32 %x, i32 %y, i32 %mask) {
154 ; CHECK-NOBMI-LABEL: in32:
155 ; CHECK-NOBMI:       # %bb.0:
156 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
157 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
158 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
159 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
160 ; CHECK-NOBMI-NEXT:    retq
161 ;
162 ; CHECK-BMI-LABEL: in32:
163 ; CHECK-BMI:       # %bb.0:
164 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
165 ; CHECK-BMI-NEXT:    andl %edx, %edi
166 ; CHECK-BMI-NEXT:    orl %edi, %eax
167 ; CHECK-BMI-NEXT:    retq
168   %n0 = xor i32 %x, %y
169   %n1 = and i32 %n0, %mask
170   %r = xor i32 %n1, %y
171   ret i32 %r
172 }
173
174 define i64 @in64(i64 %x, i64 %y, i64 %mask) {
175 ; CHECK-NOBMI-LABEL: in64:
176 ; CHECK-NOBMI:       # %bb.0:
177 ; CHECK-NOBMI-NEXT:    movq %rdi, %rax
178 ; CHECK-NOBMI-NEXT:    xorq %rsi, %rax
179 ; CHECK-NOBMI-NEXT:    andq %rdx, %rax
180 ; CHECK-NOBMI-NEXT:    xorq %rsi, %rax
181 ; CHECK-NOBMI-NEXT:    retq
182 ;
183 ; CHECK-BMI-LABEL: in64:
184 ; CHECK-BMI:       # %bb.0:
185 ; CHECK-BMI-NEXT:    andnq %rsi, %rdx, %rax
186 ; CHECK-BMI-NEXT:    andq %rdx, %rdi
187 ; CHECK-BMI-NEXT:    orq %rdi, %rax
188 ; CHECK-BMI-NEXT:    retq
189   %n0 = xor i64 %x, %y
190   %n1 = and i64 %n0, %mask
191   %r = xor i64 %n1, %y
192   ret i64 %r
193 }
194 ; ============================================================================ ;
195 ; Commutativity tests.
196 ; ============================================================================ ;
197 define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) {
198 ; CHECK-NOBMI-LABEL: in_commutativity_0_0_1:
199 ; CHECK-NOBMI:       # %bb.0:
200 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
201 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
202 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
203 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
204 ; CHECK-NOBMI-NEXT:    retq
205 ;
206 ; CHECK-BMI-LABEL: in_commutativity_0_0_1:
207 ; CHECK-BMI:       # %bb.0:
208 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
209 ; CHECK-BMI-NEXT:    andl %edx, %edi
210 ; CHECK-BMI-NEXT:    orl %edi, %eax
211 ; CHECK-BMI-NEXT:    retq
212   %n0 = xor i32 %x, %y
213   %n1 = and i32 %mask, %n0 ; swapped
214   %r = xor i32 %n1, %y
215   ret i32 %r
216 }
217 define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) {
218 ; CHECK-NOBMI-LABEL: in_commutativity_0_1_0:
219 ; CHECK-NOBMI:       # %bb.0:
220 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
221 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
222 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
223 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
224 ; CHECK-NOBMI-NEXT:    retq
225 ;
226 ; CHECK-BMI-LABEL: in_commutativity_0_1_0:
227 ; CHECK-BMI:       # %bb.0:
228 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
229 ; CHECK-BMI-NEXT:    andl %edx, %edi
230 ; CHECK-BMI-NEXT:    orl %edi, %eax
231 ; CHECK-BMI-NEXT:    retq
232   %n0 = xor i32 %x, %y
233   %n1 = and i32 %n0, %mask
234   %r = xor i32 %y, %n1 ; swapped
235   ret i32 %r
236 }
237 define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) {
238 ; CHECK-NOBMI-LABEL: in_commutativity_0_1_1:
239 ; CHECK-NOBMI:       # %bb.0:
240 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
241 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
242 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
243 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
244 ; CHECK-NOBMI-NEXT:    retq
245 ;
246 ; CHECK-BMI-LABEL: in_commutativity_0_1_1:
247 ; CHECK-BMI:       # %bb.0:
248 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
249 ; CHECK-BMI-NEXT:    andl %edx, %edi
250 ; CHECK-BMI-NEXT:    orl %edi, %eax
251 ; CHECK-BMI-NEXT:    retq
252   %n0 = xor i32 %x, %y
253   %n1 = and i32 %mask, %n0 ; swapped
254   %r = xor i32 %y, %n1 ; swapped
255   ret i32 %r
256 }
257 define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) {
258 ; CHECK-NOBMI-LABEL: in_commutativity_1_0_0:
259 ; CHECK-NOBMI:       # %bb.0:
260 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
261 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
262 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
263 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
264 ; CHECK-NOBMI-NEXT:    retq
265 ;
266 ; CHECK-BMI-LABEL: in_commutativity_1_0_0:
267 ; CHECK-BMI:       # %bb.0:
268 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
269 ; CHECK-BMI-NEXT:    andl %edx, %esi
270 ; CHECK-BMI-NEXT:    orl %esi, %eax
271 ; CHECK-BMI-NEXT:    retq
272   %n0 = xor i32 %x, %y
273   %n1 = and i32 %n0, %mask
274   %r = xor i32 %n1, %x ; %x instead of %y
275   ret i32 %r
276 }
277 define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) {
278 ; CHECK-NOBMI-LABEL: in_commutativity_1_0_1:
279 ; CHECK-NOBMI:       # %bb.0:
280 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
281 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
282 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
283 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
284 ; CHECK-NOBMI-NEXT:    retq
285 ;
286 ; CHECK-BMI-LABEL: in_commutativity_1_0_1:
287 ; CHECK-BMI:       # %bb.0:
288 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
289 ; CHECK-BMI-NEXT:    andl %edx, %esi
290 ; CHECK-BMI-NEXT:    orl %esi, %eax
291 ; CHECK-BMI-NEXT:    retq
292   %n0 = xor i32 %x, %y
293   %n1 = and i32 %mask, %n0 ; swapped
294   %r = xor i32 %n1, %x ; %x instead of %y
295   ret i32 %r
296 }
297 define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) {
298 ; CHECK-NOBMI-LABEL: in_commutativity_1_1_0:
299 ; CHECK-NOBMI:       # %bb.0:
300 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
301 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
302 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
303 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
304 ; CHECK-NOBMI-NEXT:    retq
305 ;
306 ; CHECK-BMI-LABEL: in_commutativity_1_1_0:
307 ; CHECK-BMI:       # %bb.0:
308 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
309 ; CHECK-BMI-NEXT:    andl %edx, %esi
310 ; CHECK-BMI-NEXT:    orl %esi, %eax
311 ; CHECK-BMI-NEXT:    retq
312   %n0 = xor i32 %x, %y
313   %n1 = and i32 %n0, %mask
314   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
315   ret i32 %r
316 }
317 define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) {
318 ; CHECK-NOBMI-LABEL: in_commutativity_1_1_1:
319 ; CHECK-NOBMI:       # %bb.0:
320 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
321 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
322 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
323 ; CHECK-NOBMI-NEXT:    xorl %edi, %eax
324 ; CHECK-NOBMI-NEXT:    retq
325 ;
326 ; CHECK-BMI-LABEL: in_commutativity_1_1_1:
327 ; CHECK-BMI:       # %bb.0:
328 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
329 ; CHECK-BMI-NEXT:    andl %edx, %esi
330 ; CHECK-BMI-NEXT:    orl %esi, %eax
331 ; CHECK-BMI-NEXT:    retq
332   %n0 = xor i32 %x, %y
333   %n1 = and i32 %mask, %n0 ; swapped
334   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
335   ret i32 %r
336 }
337 ; ============================================================================ ;
338 ; Y is an 'and' too.
339 ; ============================================================================ ;
340 define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
341 ; CHECK-NOBMI-LABEL: in_complex_y0:
342 ; CHECK-NOBMI:       # %bb.0:
343 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
344 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
345 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
346 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
347 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
348 ; CHECK-NOBMI-NEXT:    retq
349 ;
350 ; CHECK-BMI-LABEL: in_complex_y0:
351 ; CHECK-BMI:       # %bb.0:
352 ; CHECK-BMI-NEXT:    andl %edx, %esi
353 ; CHECK-BMI-NEXT:    andl %ecx, %edi
354 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
355 ; CHECK-BMI-NEXT:    orl %edi, %eax
356 ; CHECK-BMI-NEXT:    retq
357   %y = and i32 %y_hi, %y_low
358   %n0 = xor i32 %x, %y
359   %n1 = and i32 %n0, %mask
360   %r = xor i32 %n1, %y
361   ret i32 %r
362 }
363 define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) {
364 ; CHECK-NOBMI-LABEL: in_complex_y1:
365 ; CHECK-NOBMI:       # %bb.0:
366 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
367 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
368 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
369 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
370 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
371 ; CHECK-NOBMI-NEXT:    retq
372 ;
373 ; CHECK-BMI-LABEL: in_complex_y1:
374 ; CHECK-BMI:       # %bb.0:
375 ; CHECK-BMI-NEXT:    andl %edx, %esi
376 ; CHECK-BMI-NEXT:    andl %ecx, %edi
377 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
378 ; CHECK-BMI-NEXT:    orl %edi, %eax
379 ; CHECK-BMI-NEXT:    retq
380   %y = and i32 %y_hi, %y_low
381   %n0 = xor i32 %x, %y
382   %n1 = and i32 %n0, %mask
383   %r = xor i32 %y, %n1
384   ret i32 %r
385 }
386 ; ============================================================================ ;
387 ; M is an 'xor' too.
388 ; ============================================================================ ;
389 define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
390 ; CHECK-NOBMI-LABEL: in_complex_m0:
391 ; CHECK-NOBMI:       # %bb.0:
392 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
393 ; CHECK-NOBMI-NEXT:    xorl %ecx, %edx
394 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
395 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
396 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
397 ; CHECK-NOBMI-NEXT:    retq
398 ;
399 ; CHECK-BMI-LABEL: in_complex_m0:
400 ; CHECK-BMI:       # %bb.0:
401 ; CHECK-BMI-NEXT:    xorl %ecx, %edx
402 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
403 ; CHECK-BMI-NEXT:    andl %edi, %edx
404 ; CHECK-BMI-NEXT:    orl %edx, %eax
405 ; CHECK-BMI-NEXT:    retq
406   %mask = xor i32 %m_a, %m_b
407   %n0 = xor i32 %x, %y
408   %n1 = and i32 %n0, %mask
409   %r = xor i32 %n1, %y
410   ret i32 %r
411 }
412 define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) {
413 ; CHECK-NOBMI-LABEL: in_complex_m1:
414 ; CHECK-NOBMI:       # %bb.0:
415 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
416 ; CHECK-NOBMI-NEXT:    xorl %ecx, %edx
417 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
418 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
419 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
420 ; CHECK-NOBMI-NEXT:    retq
421 ;
422 ; CHECK-BMI-LABEL: in_complex_m1:
423 ; CHECK-BMI:       # %bb.0:
424 ; CHECK-BMI-NEXT:    xorl %ecx, %edx
425 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
426 ; CHECK-BMI-NEXT:    andl %edi, %edx
427 ; CHECK-BMI-NEXT:    orl %edx, %eax
428 ; CHECK-BMI-NEXT:    retq
429   %mask = xor i32 %m_a, %m_b
430   %n0 = xor i32 %x, %y
431   %n1 = and i32 %mask, %n0
432   %r = xor i32 %n1, %y
433   ret i32 %r
434 }
435 ; ============================================================================ ;
436 ; Both Y and M are complex.
437 ; ============================================================================ ;
438 define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
439 ; CHECK-NOBMI-LABEL: in_complex_y0_m0:
440 ; CHECK-NOBMI:       # %bb.0:
441 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
442 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
443 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
444 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
445 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
446 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
447 ; CHECK-NOBMI-NEXT:    retq
448 ;
449 ; CHECK-BMI-LABEL: in_complex_y0_m0:
450 ; CHECK-BMI:       # %bb.0:
451 ; CHECK-BMI-NEXT:    andl %edx, %esi
452 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
453 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
454 ; CHECK-BMI-NEXT:    andl %edi, %ecx
455 ; CHECK-BMI-NEXT:    orl %ecx, %eax
456 ; CHECK-BMI-NEXT:    retq
457   %y = and i32 %y_hi, %y_low
458   %mask = xor i32 %m_a, %m_b
459   %n0 = xor i32 %x, %y
460   %n1 = and i32 %n0, %mask
461   %r = xor i32 %n1, %y
462   ret i32 %r
463 }
464 define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
465 ; CHECK-NOBMI-LABEL: in_complex_y1_m0:
466 ; CHECK-NOBMI:       # %bb.0:
467 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
468 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
469 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
470 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
471 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
472 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
473 ; CHECK-NOBMI-NEXT:    retq
474 ;
475 ; CHECK-BMI-LABEL: in_complex_y1_m0:
476 ; CHECK-BMI:       # %bb.0:
477 ; CHECK-BMI-NEXT:    andl %edx, %esi
478 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
479 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
480 ; CHECK-BMI-NEXT:    andl %edi, %ecx
481 ; CHECK-BMI-NEXT:    orl %ecx, %eax
482 ; CHECK-BMI-NEXT:    retq
483   %y = and i32 %y_hi, %y_low
484   %mask = xor i32 %m_a, %m_b
485   %n0 = xor i32 %x, %y
486   %n1 = and i32 %n0, %mask
487   %r = xor i32 %y, %n1
488   ret i32 %r
489 }
490 define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
491 ; CHECK-NOBMI-LABEL: in_complex_y0_m1:
492 ; CHECK-NOBMI:       # %bb.0:
493 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
494 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
495 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
496 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
497 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
498 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
499 ; CHECK-NOBMI-NEXT:    retq
500 ;
501 ; CHECK-BMI-LABEL: in_complex_y0_m1:
502 ; CHECK-BMI:       # %bb.0:
503 ; CHECK-BMI-NEXT:    andl %edx, %esi
504 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
505 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
506 ; CHECK-BMI-NEXT:    andl %edi, %ecx
507 ; CHECK-BMI-NEXT:    orl %ecx, %eax
508 ; CHECK-BMI-NEXT:    retq
509   %y = and i32 %y_hi, %y_low
510   %mask = xor i32 %m_a, %m_b
511   %n0 = xor i32 %x, %y
512   %n1 = and i32 %mask, %n0
513   %r = xor i32 %n1, %y
514   ret i32 %r
515 }
516 define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) {
517 ; CHECK-NOBMI-LABEL: in_complex_y1_m1:
518 ; CHECK-NOBMI:       # %bb.0:
519 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
520 ; CHECK-NOBMI-NEXT:    andl %edx, %esi
521 ; CHECK-NOBMI-NEXT:    xorl %r8d, %ecx
522 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
523 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
524 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
525 ; CHECK-NOBMI-NEXT:    retq
526 ;
527 ; CHECK-BMI-LABEL: in_complex_y1_m1:
528 ; CHECK-BMI:       # %bb.0:
529 ; CHECK-BMI-NEXT:    andl %edx, %esi
530 ; CHECK-BMI-NEXT:    xorl %r8d, %ecx
531 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
532 ; CHECK-BMI-NEXT:    andl %edi, %ecx
533 ; CHECK-BMI-NEXT:    orl %ecx, %eax
534 ; CHECK-BMI-NEXT:    retq
535   %y = and i32 %y_hi, %y_low
536   %mask = xor i32 %m_a, %m_b
537   %n0 = xor i32 %x, %y
538   %n1 = and i32 %mask, %n0
539   %r = xor i32 %y, %n1
540   ret i32 %r
541 }
542 ; ============================================================================ ;
543 ; Various cases with %x and/or %y being a constant
544 ; ============================================================================ ;
545 define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
546 ; CHECK-NOBMI-LABEL: out_constant_varx_mone:
547 ; CHECK-NOBMI:       # %bb.0:
548 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
549 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
550 ; CHECK-NOBMI-NEXT:    notl %edx
551 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
552 ; CHECK-NOBMI-NEXT:    retq
553 ;
554 ; CHECK-BMI-LABEL: out_constant_varx_mone:
555 ; CHECK-BMI:       # %bb.0:
556 ; CHECK-BMI-NEXT:    movl %edi, %eax
557 ; CHECK-BMI-NEXT:    andl %edx, %eax
558 ; CHECK-BMI-NEXT:    notl %edx
559 ; CHECK-BMI-NEXT:    orl %edx, %eax
560 ; CHECK-BMI-NEXT:    retq
561   %notmask = xor i32 %mask, -1
562   %mx = and i32 %mask, %x
563   %my = and i32 %notmask, -1
564   %r = or i32 %mx, %my
565   ret i32 %r
566 }
567 define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) {
568 ; CHECK-NOBMI-LABEL: in_constant_varx_mone:
569 ; CHECK-NOBMI:       # %bb.0:
570 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
571 ; CHECK-NOBMI-NEXT:    notl %eax
572 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
573 ; CHECK-NOBMI-NEXT:    notl %eax
574 ; CHECK-NOBMI-NEXT:    retq
575 ;
576 ; CHECK-BMI-LABEL: in_constant_varx_mone:
577 ; CHECK-BMI:       # %bb.0:
578 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
579 ; CHECK-BMI-NEXT:    notl %eax
580 ; CHECK-BMI-NEXT:    retq
581   %n0 = xor i32 %x, -1 ; %x
582   %n1 = and i32 %n0, %mask
583   %r = xor i32 %n1, -1
584   ret i32 %r
585 }
586 ; This is not a canonical form. Testing for completeness only.
587 define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
588 ; CHECK-NOBMI-LABEL: out_constant_varx_mone_invmask:
589 ; CHECK-NOBMI:       # %bb.0:
590 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
591 ; CHECK-NOBMI-NEXT:    notl %eax
592 ; CHECK-NOBMI-NEXT:    andl %edi, %eax
593 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
594 ; CHECK-NOBMI-NEXT:    retq
595 ;
596 ; CHECK-BMI-LABEL: out_constant_varx_mone_invmask:
597 ; CHECK-BMI:       # %bb.0:
598 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
599 ; CHECK-BMI-NEXT:    orl %edx, %eax
600 ; CHECK-BMI-NEXT:    retq
601   %notmask = xor i32 %mask, -1
602   %mx = and i32 %notmask, %x
603   %my = and i32 %mask, -1
604   %r = or i32 %mx, %my
605   ret i32 %r
606 }
607 ; This is not a canonical form. Testing for completeness only.
608 define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) {
609 ; CHECK-NOBMI-LABEL: in_constant_varx_mone_invmask:
610 ; CHECK-NOBMI:       # %bb.0:
611 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
612 ; CHECK-NOBMI-NEXT:    notl %edx
613 ; CHECK-NOBMI-NEXT:    notl %eax
614 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
615 ; CHECK-NOBMI-NEXT:    notl %eax
616 ; CHECK-NOBMI-NEXT:    retq
617 ;
618 ; CHECK-BMI-LABEL: in_constant_varx_mone_invmask:
619 ; CHECK-BMI:       # %bb.0:
620 ; CHECK-BMI-NEXT:    notl %edx
621 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
622 ; CHECK-BMI-NEXT:    notl %eax
623 ; CHECK-BMI-NEXT:    retq
624   %notmask = xor i32 %mask, -1
625   %n0 = xor i32 %x, -1 ; %x
626   %n1 = and i32 %n0, %notmask
627   %r = xor i32 %n1, -1
628   ret i32 %r
629 }
630 define i32 @out_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
631 ; CHECK-NOBMI-LABEL: out_constant_varx_42:
632 ; CHECK-NOBMI:       # %bb.0:
633 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
634 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
635 ; CHECK-NOBMI-NEXT:    notl %eax
636 ; CHECK-NOBMI-NEXT:    andl $42, %eax
637 ; CHECK-NOBMI-NEXT:    orl %edi, %eax
638 ; CHECK-NOBMI-NEXT:    retq
639 ;
640 ; CHECK-BMI-LABEL: out_constant_varx_42:
641 ; CHECK-BMI:       # %bb.0:
642 ; CHECK-BMI-NEXT:    andl %edx, %edi
643 ; CHECK-BMI-NEXT:    movl %edx, %eax
644 ; CHECK-BMI-NEXT:    notl %eax
645 ; CHECK-BMI-NEXT:    andl $42, %eax
646 ; CHECK-BMI-NEXT:    orl %edi, %eax
647 ; CHECK-BMI-NEXT:    retq
648   %notmask = xor i32 %mask, -1
649   %mx = and i32 %mask, %x
650   %my = and i32 %notmask, 42
651   %r = or i32 %mx, %my
652   ret i32 %r
653 }
654 define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) {
655 ; CHECK-NOBMI-LABEL: in_constant_varx_42:
656 ; CHECK-NOBMI:       # %bb.0:
657 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
658 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
659 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
660 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
661 ; CHECK-NOBMI-NEXT:    retq
662 ;
663 ; CHECK-BMI-LABEL: in_constant_varx_42:
664 ; CHECK-BMI:       # %bb.0:
665 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
666 ; CHECK-BMI-NEXT:    orl $42, %edx
667 ; CHECK-BMI-NEXT:    andnl %edx, %eax, %eax
668 ; CHECK-BMI-NEXT:    retq
669   %n0 = xor i32 %x, 42 ; %x
670   %n1 = and i32 %n0, %mask
671   %r = xor i32 %n1, 42
672   ret i32 %r
673 }
674 ; This is not a canonical form. Testing for completeness only.
675 define i32 @out_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
676 ; CHECK-NOBMI-LABEL: out_constant_varx_42_invmask:
677 ; CHECK-NOBMI:       # %bb.0:
678 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
679 ; CHECK-NOBMI-NEXT:    movl %edx, %ecx
680 ; CHECK-NOBMI-NEXT:    notl %ecx
681 ; CHECK-NOBMI-NEXT:    andl %edi, %ecx
682 ; CHECK-NOBMI-NEXT:    andl $42, %eax
683 ; CHECK-NOBMI-NEXT:    orl %ecx, %eax
684 ; CHECK-NOBMI-NEXT:    retq
685 ;
686 ; CHECK-BMI-LABEL: out_constant_varx_42_invmask:
687 ; CHECK-BMI:       # %bb.0:
688 ; CHECK-BMI-NEXT:    andnl %edi, %edx, %eax
689 ; CHECK-BMI-NEXT:    andl $42, %edx
690 ; CHECK-BMI-NEXT:    orl %edx, %eax
691 ; CHECK-BMI-NEXT:    retq
692   %notmask = xor i32 %mask, -1
693   %mx = and i32 %notmask, %x
694   %my = and i32 %mask, 42
695   %r = or i32 %mx, %my
696   ret i32 %r
697 }
698 ; This is not a canonical form. Testing for completeness only.
699 define i32 @in_constant_varx_42_invmask(i32 %x, i32 %y, i32 %mask) {
700 ; CHECK-NOBMI-LABEL: in_constant_varx_42_invmask:
701 ; CHECK-NOBMI:       # %bb.0:
702 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
703 ; CHECK-NOBMI-NEXT:    notl %edx
704 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
705 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
706 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
707 ; CHECK-NOBMI-NEXT:    retq
708 ;
709 ; CHECK-BMI-LABEL: in_constant_varx_42_invmask:
710 ; CHECK-BMI:       # %bb.0:
711 ; CHECK-BMI-NEXT:    notl %edx
712 ; CHECK-BMI-NEXT:    andnl %edx, %edi, %eax
713 ; CHECK-BMI-NEXT:    orl $42, %edx
714 ; CHECK-BMI-NEXT:    andnl %edx, %eax, %eax
715 ; CHECK-BMI-NEXT:    retq
716   %notmask = xor i32 %mask, -1
717   %n0 = xor i32 %x, 42 ; %x
718   %n1 = and i32 %n0, %notmask
719   %r = xor i32 %n1, 42
720   ret i32 %r
721 }
722 define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
723 ; CHECK-NOBMI-LABEL: out_constant_mone_vary:
724 ; CHECK-NOBMI:       # %bb.0:
725 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
726 ; CHECK-NOBMI-NEXT:    notl %eax
727 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
728 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
729 ; CHECK-NOBMI-NEXT:    retq
730 ;
731 ; CHECK-BMI-LABEL: out_constant_mone_vary:
732 ; CHECK-BMI:       # %bb.0:
733 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
734 ; CHECK-BMI-NEXT:    orl %edx, %eax
735 ; CHECK-BMI-NEXT:    retq
736   %notmask = xor i32 %mask, -1
737   %mx = and i32 %mask, -1
738   %my = and i32 %notmask, %y
739   %r = or i32 %mx, %my
740   ret i32 %r
741 }
742 define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
743 ; CHECK-NOBMI-LABEL: in_constant_mone_vary:
744 ; CHECK-NOBMI:       # %bb.0:
745 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
746 ; CHECK-NOBMI-NEXT:    notl %eax
747 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
748 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
749 ; CHECK-NOBMI-NEXT:    retq
750 ;
751 ; CHECK-BMI-LABEL: in_constant_mone_vary:
752 ; CHECK-BMI:       # %bb.0:
753 ; CHECK-BMI-NEXT:    andnl %edx, %esi, %eax
754 ; CHECK-BMI-NEXT:    xorl %esi, %eax
755 ; CHECK-BMI-NEXT:    retq
756   %n0 = xor i32 -1, %y ; %x
757   %n1 = and i32 %n0, %mask
758   %r = xor i32 %n1, %y
759   ret i32 %r
760 }
761 ; This is not a canonical form. Testing for completeness only.
762 define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
763 ; CHECK-NOBMI-LABEL: out_constant_mone_vary_invmask:
764 ; CHECK-NOBMI:       # %bb.0:
765 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
766 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
767 ; CHECK-NOBMI-NEXT:    notl %edx
768 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
769 ; CHECK-NOBMI-NEXT:    retq
770 ;
771 ; CHECK-BMI-LABEL: out_constant_mone_vary_invmask:
772 ; CHECK-BMI:       # %bb.0:
773 ; CHECK-BMI-NEXT:    movl %esi, %eax
774 ; CHECK-BMI-NEXT:    andl %edx, %eax
775 ; CHECK-BMI-NEXT:    notl %edx
776 ; CHECK-BMI-NEXT:    orl %edx, %eax
777 ; CHECK-BMI-NEXT:    retq
778   %notmask = xor i32 %mask, -1
779   %mx = and i32 %notmask, -1
780   %my = and i32 %mask, %y
781   %r = or i32 %mx, %my
782   ret i32 %r
783 }
784 ; This is not a canonical form. Testing for completeness only.
785 define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
786 ; CHECK-NOBMI-LABEL: in_constant_mone_vary_invmask:
787 ; CHECK-NOBMI:       # %bb.0:
788 ; CHECK-NOBMI-NEXT:    notl %edx
789 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
790 ; CHECK-NOBMI-NEXT:    notl %eax
791 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
792 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
793 ; CHECK-NOBMI-NEXT:    retq
794 ;
795 ; CHECK-BMI-LABEL: in_constant_mone_vary_invmask:
796 ; CHECK-BMI:       # %bb.0:
797 ; CHECK-BMI-NEXT:    notl %edx
798 ; CHECK-BMI-NEXT:    andnl %edx, %esi, %eax
799 ; CHECK-BMI-NEXT:    xorl %esi, %eax
800 ; CHECK-BMI-NEXT:    retq
801   %notmask = xor i32 %mask, -1
802   %n0 = xor i32 -1, %y ; %x
803   %n1 = and i32 %n0, %notmask
804   %r = xor i32 %n1, %y
805   ret i32 %r
806 }
807 define i32 @out_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
808 ; CHECK-NOBMI-LABEL: out_constant_42_vary:
809 ; CHECK-NOBMI:       # %bb.0:
810 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
811 ; CHECK-NOBMI-NEXT:    notl %eax
812 ; CHECK-NOBMI-NEXT:    andl $42, %edx
813 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
814 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
815 ; CHECK-NOBMI-NEXT:    retq
816 ;
817 ; CHECK-BMI-LABEL: out_constant_42_vary:
818 ; CHECK-BMI:       # %bb.0:
819 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
820 ; CHECK-BMI-NEXT:    andl $42, %edx
821 ; CHECK-BMI-NEXT:    orl %edx, %eax
822 ; CHECK-BMI-NEXT:    retq
823   %notmask = xor i32 %mask, -1
824   %mx = and i32 %mask, 42
825   %my = and i32 %notmask, %y
826   %r = or i32 %mx, %my
827   ret i32 %r
828 }
829 define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) {
830 ; CHECK-NOBMI-LABEL: in_constant_42_vary:
831 ; CHECK-NOBMI:       # %bb.0:
832 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
833 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
834 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
835 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
836 ; CHECK-NOBMI-NEXT:    retq
837 ;
838 ; CHECK-BMI-LABEL: in_constant_42_vary:
839 ; CHECK-BMI:       # %bb.0:
840 ; CHECK-BMI-NEXT:    andnl %esi, %edx, %eax
841 ; CHECK-BMI-NEXT:    andl $42, %edx
842 ; CHECK-BMI-NEXT:    orl %edx, %eax
843 ; CHECK-BMI-NEXT:    retq
844   %n0 = xor i32 42, %y ; %x
845   %n1 = and i32 %n0, %mask
846   %r = xor i32 %n1, %y
847   ret i32 %r
848 }
849 ; This is not a canonical form. Testing for completeness only.
850 define i32 @out_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
851 ; CHECK-NOBMI-LABEL: out_constant_42_vary_invmask:
852 ; CHECK-NOBMI:       # %bb.0:
853 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
854 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
855 ; CHECK-NOBMI-NEXT:    notl %edx
856 ; CHECK-NOBMI-NEXT:    andl $42, %edx
857 ; CHECK-NOBMI-NEXT:    orl %edx, %eax
858 ; CHECK-NOBMI-NEXT:    retq
859 ;
860 ; CHECK-BMI-LABEL: out_constant_42_vary_invmask:
861 ; CHECK-BMI:       # %bb.0:
862 ; CHECK-BMI-NEXT:    movl %esi, %eax
863 ; CHECK-BMI-NEXT:    andl %edx, %eax
864 ; CHECK-BMI-NEXT:    notl %edx
865 ; CHECK-BMI-NEXT:    andl $42, %edx
866 ; CHECK-BMI-NEXT:    orl %edx, %eax
867 ; CHECK-BMI-NEXT:    retq
868   %notmask = xor i32 %mask, -1
869   %mx = and i32 %notmask, 42
870   %my = and i32 %mask, %y
871   %r = or i32 %mx, %my
872   ret i32 %r
873 }
874 ; This is not a canonical form. Testing for completeness only.
875 define i32 @in_constant_42_vary_invmask(i32 %x, i32 %y, i32 %mask) {
876 ; CHECK-NOBMI-LABEL: in_constant_42_vary_invmask:
877 ; CHECK-NOBMI:       # %bb.0:
878 ; CHECK-NOBMI-NEXT:    notl %edx
879 ; CHECK-NOBMI-NEXT:    movl %esi, %eax
880 ; CHECK-NOBMI-NEXT:    xorl $42, %eax
881 ; CHECK-NOBMI-NEXT:    andl %edx, %eax
882 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
883 ; CHECK-NOBMI-NEXT:    retq
884 ;
885 ; CHECK-BMI-LABEL: in_constant_42_vary_invmask:
886 ; CHECK-BMI:       # %bb.0:
887 ; CHECK-BMI-NEXT:    movl %edx, %eax
888 ; CHECK-BMI-NEXT:    andl %edx, %esi
889 ; CHECK-BMI-NEXT:    notl %eax
890 ; CHECK-BMI-NEXT:    andl $42, %eax
891 ; CHECK-BMI-NEXT:    orl %esi, %eax
892 ; CHECK-BMI-NEXT:    retq
893   %notmask = xor i32 %mask, -1
894   %n0 = xor i32 42, %y ; %x
895   %n1 = and i32 %n0, %notmask
896   %r = xor i32 %n1, %y
897   ret i32 %r
898 }
899 ; ============================================================================ ;
900 ; Negative tests. Should not be folded.
901 ; ============================================================================ ;
902 ; Multi-use tests.
903 declare void @use32(i32) nounwind
904 define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
905 ; CHECK-NOBMI-LABEL: in_multiuse_A:
906 ; CHECK-NOBMI:       # %bb.0:
907 ; CHECK-NOBMI-NEXT:    pushq %rbp
908 ; CHECK-NOBMI-NEXT:    pushq %rbx
909 ; CHECK-NOBMI-NEXT:    pushq %rax
910 ; CHECK-NOBMI-NEXT:    movl %esi, %ebx
911 ; CHECK-NOBMI-NEXT:    movl %edi, %ebp
912 ; CHECK-NOBMI-NEXT:    xorl %esi, %ebp
913 ; CHECK-NOBMI-NEXT:    andl %ecx, %ebp
914 ; CHECK-NOBMI-NEXT:    movl %ebp, %edi
915 ; CHECK-NOBMI-NEXT:    callq use32
916 ; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
917 ; CHECK-NOBMI-NEXT:    movl %ebp, %eax
918 ; CHECK-NOBMI-NEXT:    addq $8, %rsp
919 ; CHECK-NOBMI-NEXT:    popq %rbx
920 ; CHECK-NOBMI-NEXT:    popq %rbp
921 ; CHECK-NOBMI-NEXT:    retq
922 ;
923 ; CHECK-BMI-LABEL: in_multiuse_A:
924 ; CHECK-BMI:       # %bb.0:
925 ; CHECK-BMI-NEXT:    pushq %rbp
926 ; CHECK-BMI-NEXT:    pushq %rbx
927 ; CHECK-BMI-NEXT:    pushq %rax
928 ; CHECK-BMI-NEXT:    movl %esi, %ebx
929 ; CHECK-BMI-NEXT:    movl %edi, %ebp
930 ; CHECK-BMI-NEXT:    xorl %esi, %ebp
931 ; CHECK-BMI-NEXT:    andl %ecx, %ebp
932 ; CHECK-BMI-NEXT:    movl %ebp, %edi
933 ; CHECK-BMI-NEXT:    callq use32
934 ; CHECK-BMI-NEXT:    xorl %ebx, %ebp
935 ; CHECK-BMI-NEXT:    movl %ebp, %eax
936 ; CHECK-BMI-NEXT:    addq $8, %rsp
937 ; CHECK-BMI-NEXT:    popq %rbx
938 ; CHECK-BMI-NEXT:    popq %rbp
939 ; CHECK-BMI-NEXT:    retq
940   %n0 = xor i32 %x, %y
941   %n1 = and i32 %n0, %mask
942   call void @use32(i32 %n1)
943   %r = xor i32 %n1, %y
944   ret i32 %r
945 }
946 define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
947 ; CHECK-NOBMI-LABEL: in_multiuse_B:
948 ; CHECK-NOBMI:       # %bb.0:
949 ; CHECK-NOBMI-NEXT:    pushq %rbp
950 ; CHECK-NOBMI-NEXT:    pushq %rbx
951 ; CHECK-NOBMI-NEXT:    pushq %rax
952 ; CHECK-NOBMI-NEXT:    movl %ecx, %ebx
953 ; CHECK-NOBMI-NEXT:    movl %esi, %ebp
954 ; CHECK-NOBMI-NEXT:    xorl %esi, %edi
955 ; CHECK-NOBMI-NEXT:    andl %edi, %ebx
956 ; CHECK-NOBMI-NEXT:    callq use32
957 ; CHECK-NOBMI-NEXT:    xorl %ebp, %ebx
958 ; CHECK-NOBMI-NEXT:    movl %ebx, %eax
959 ; CHECK-NOBMI-NEXT:    addq $8, %rsp
960 ; CHECK-NOBMI-NEXT:    popq %rbx
961 ; CHECK-NOBMI-NEXT:    popq %rbp
962 ; CHECK-NOBMI-NEXT:    retq
963 ;
964 ; CHECK-BMI-LABEL: in_multiuse_B:
965 ; CHECK-BMI:       # %bb.0:
966 ; CHECK-BMI-NEXT:    pushq %rbp
967 ; CHECK-BMI-NEXT:    pushq %rbx
968 ; CHECK-BMI-NEXT:    pushq %rax
969 ; CHECK-BMI-NEXT:    movl %ecx, %ebx
970 ; CHECK-BMI-NEXT:    movl %esi, %ebp
971 ; CHECK-BMI-NEXT:    xorl %esi, %edi
972 ; CHECK-BMI-NEXT:    andl %edi, %ebx
973 ; CHECK-BMI-NEXT:    callq use32
974 ; CHECK-BMI-NEXT:    xorl %ebp, %ebx
975 ; CHECK-BMI-NEXT:    movl %ebx, %eax
976 ; CHECK-BMI-NEXT:    addq $8, %rsp
977 ; CHECK-BMI-NEXT:    popq %rbx
978 ; CHECK-BMI-NEXT:    popq %rbp
979 ; CHECK-BMI-NEXT:    retq
980   %n0 = xor i32 %x, %y
981   %n1 = and i32 %n0, %mask
982   call void @use32(i32 %n0)
983   %r = xor i32 %n1, %y
984   ret i32 %r
985 }
986 ; Various bad variants
987 define i32 @n0_badmask(i32 %x, i32 %y, i32 %mask, i32 %mask2) {
988 ; CHECK-NOBMI-LABEL: n0_badmask:
989 ; CHECK-NOBMI:       # %bb.0:
990 ; CHECK-NOBMI-NEXT:    movl %ecx, %eax
991 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
992 ; CHECK-NOBMI-NEXT:    notl %eax
993 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
994 ; CHECK-NOBMI-NEXT:    orl %edi, %eax
995 ; CHECK-NOBMI-NEXT:    retq
996 ;
997 ; CHECK-BMI-LABEL: n0_badmask:
998 ; CHECK-BMI:       # %bb.0:
999 ; CHECK-BMI-NEXT:    andl %edx, %edi
1000 ; CHECK-BMI-NEXT:    andnl %esi, %ecx, %eax
1001 ; CHECK-BMI-NEXT:    orl %edi, %eax
1002 ; CHECK-BMI-NEXT:    retq
1003   %mx = and i32 %x, %mask
1004   %notmask = xor i32 %mask2, -1 ; %mask2 instead of %mask
1005   %my = and i32 %y, %notmask
1006   %r = or i32 %mx, %my
1007   ret i32 %r
1008 }
1009 define i32 @n0_badxor(i32 %x, i32 %y, i32 %mask) {
1010 ; CHECK-NOBMI-LABEL: n0_badxor:
1011 ; CHECK-NOBMI:       # %bb.0:
1012 ; CHECK-NOBMI-NEXT:    movl %edx, %eax
1013 ; CHECK-NOBMI-NEXT:    andl %edx, %edi
1014 ; CHECK-NOBMI-NEXT:    xorl $1, %eax
1015 ; CHECK-NOBMI-NEXT:    andl %esi, %eax
1016 ; CHECK-NOBMI-NEXT:    orl %edi, %eax
1017 ; CHECK-NOBMI-NEXT:    retq
1018 ;
1019 ; CHECK-BMI-LABEL: n0_badxor:
1020 ; CHECK-BMI:       # %bb.0:
1021 ; CHECK-BMI-NEXT:    movl %edx, %eax
1022 ; CHECK-BMI-NEXT:    andl %edx, %edi
1023 ; CHECK-BMI-NEXT:    xorl $1, %eax
1024 ; CHECK-BMI-NEXT:    andl %esi, %eax
1025 ; CHECK-BMI-NEXT:    orl %edi, %eax
1026 ; CHECK-BMI-NEXT:    retq
1027   %mx = and i32 %x, %mask
1028   %notmask = xor i32 %mask, 1 ; instead of -1
1029   %my = and i32 %y, %notmask
1030   %r = or i32 %mx, %my
1031   ret i32 %r
1032 }
1033 define i32 @n1_thirdvar(i32 %x, i32 %y, i32 %z, i32 %mask) {
1034 ; CHECK-NOBMI-LABEL: n1_thirdvar:
1035 ; CHECK-NOBMI:       # %bb.0:
1036 ; CHECK-NOBMI-NEXT:    movl %edi, %eax
1037 ; CHECK-NOBMI-NEXT:    xorl %esi, %eax
1038 ; CHECK-NOBMI-NEXT:    andl %ecx, %eax
1039 ; CHECK-NOBMI-NEXT:    xorl %edx, %eax
1040 ; CHECK-NOBMI-NEXT:    retq
1041 ;
1042 ; CHECK-BMI-LABEL: n1_thirdvar:
1043 ; CHECK-BMI:       # %bb.0:
1044 ; CHECK-BMI-NEXT:    movl %edi, %eax
1045 ; CHECK-BMI-NEXT:    xorl %esi, %eax
1046 ; CHECK-BMI-NEXT:    andl %ecx, %eax
1047 ; CHECK-BMI-NEXT:    xorl %edx, %eax
1048 ; CHECK-BMI-NEXT:    retq
1049   %n0 = xor i32 %x, %y
1050   %n1 = and i32 %n0, %mask
1051   %r = xor i32 %n1, %z ; instead of %y
1052   ret i32 %r
1053 }