• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5; https://bugs.llvm.org/show_bug.cgi?id=37104
6
7; X:               [byte1][byte0]
8; Y: [byte3][byte2]
9
10define i8 @out8_constmask(i8 %x, i8 %y) {
11; CHECK-NOBMI-LABEL: out8_constmask:
12; CHECK-NOBMI:       # %bb.0:
13; CHECK-NOBMI-NEXT:    andb $15, %dil
14; CHECK-NOBMI-NEXT:    andb $-16, %sil
15; CHECK-NOBMI-NEXT:    orb %dil, %sil
16; CHECK-NOBMI-NEXT:    movl %esi, %eax
17; CHECK-NOBMI-NEXT:    retq
18;
19; CHECK-BMI-LABEL: out8_constmask:
20; CHECK-BMI:       # %bb.0:
21; CHECK-BMI-NEXT:    andb $15, %dil
22; CHECK-BMI-NEXT:    andb $-16, %sil
23; CHECK-BMI-NEXT:    orb %dil, %sil
24; CHECK-BMI-NEXT:    movl %esi, %eax
25; CHECK-BMI-NEXT:    retq
26  %mx = and i8 %x, 15
27  %my = and i8 %y, -16
28  %r = or i8 %mx, %my
29  ret i8 %r
30}
31
32define i16 @out16_constmask(i16 %x, i16 %y) {
33; CHECK-NOBMI-LABEL: out16_constmask:
34; CHECK-NOBMI:       # %bb.0:
35; CHECK-NOBMI-NEXT:    movzbl %dil, %eax
36; CHECK-NOBMI-NEXT:    andl $-256, %esi
37; CHECK-NOBMI-NEXT:    orl %esi, %eax
38; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
39; CHECK-NOBMI-NEXT:    retq
40;
41; CHECK-BMI-LABEL: out16_constmask:
42; CHECK-BMI:       # %bb.0:
43; CHECK-BMI-NEXT:    movzbl %dil, %eax
44; CHECK-BMI-NEXT:    andl $-256, %esi
45; CHECK-BMI-NEXT:    orl %esi, %eax
46; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
47; CHECK-BMI-NEXT:    retq
48  %mx = and i16 %x, 255
49  %my = and i16 %y, -256
50  %r = or i16 %mx, %my
51  ret i16 %r
52}
53
54define i32 @out32_constmask(i32 %x, i32 %y) {
55; CHECK-NOBMI-LABEL: out32_constmask:
56; CHECK-NOBMI:       # %bb.0:
57; CHECK-NOBMI-NEXT:    movzwl %di, %eax
58; CHECK-NOBMI-NEXT:    andl $-65536, %esi # imm = 0xFFFF0000
59; CHECK-NOBMI-NEXT:    orl %esi, %eax
60; CHECK-NOBMI-NEXT:    retq
61;
62; CHECK-BMI-LABEL: out32_constmask:
63; CHECK-BMI:       # %bb.0:
64; CHECK-BMI-NEXT:    movzwl %di, %eax
65; CHECK-BMI-NEXT:    andl $-65536, %esi # imm = 0xFFFF0000
66; CHECK-BMI-NEXT:    orl %esi, %eax
67; CHECK-BMI-NEXT:    retq
68  %mx = and i32 %x, 65535
69  %my = and i32 %y, -65536
70  %r = or i32 %mx, %my
71  ret i32 %r
72}
73
74define i64 @out64_constmask(i64 %x, i64 %y) {
75; CHECK-NOBMI-LABEL: out64_constmask:
76; CHECK-NOBMI:       # %bb.0:
77; CHECK-NOBMI-NEXT:    movl %edi, %ecx
78; CHECK-NOBMI-NEXT:    movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000
79; CHECK-NOBMI-NEXT:    andq %rsi, %rax
80; CHECK-NOBMI-NEXT:    orq %rcx, %rax
81; CHECK-NOBMI-NEXT:    retq
82;
83; CHECK-BMI-LABEL: out64_constmask:
84; CHECK-BMI:       # %bb.0:
85; CHECK-BMI-NEXT:    movl %edi, %ecx
86; CHECK-BMI-NEXT:    movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000
87; CHECK-BMI-NEXT:    andq %rsi, %rax
88; CHECK-BMI-NEXT:    orq %rcx, %rax
89; CHECK-BMI-NEXT:    retq
90  %mx = and i64 %x, 4294967295
91  %my = and i64 %y, -4294967296
92  %r = or i64 %mx, %my
93  ret i64 %r
94}
95
96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
97; Should be the same as the previous one.
98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
99
100define i8 @in8_constmask(i8 %x, i8 %y) {
101; CHECK-NOBMI-LABEL: in8_constmask:
102; CHECK-NOBMI:       # %bb.0:
103; CHECK-NOBMI-NEXT:    xorl %esi, %edi
104; CHECK-NOBMI-NEXT:    andb $15, %dil
105; CHECK-NOBMI-NEXT:    xorb %dil, %sil
106; CHECK-NOBMI-NEXT:    movl %esi, %eax
107; CHECK-NOBMI-NEXT:    retq
108;
109; CHECK-BMI-LABEL: in8_constmask:
110; CHECK-BMI:       # %bb.0:
111; CHECK-BMI-NEXT:    xorl %esi, %edi
112; CHECK-BMI-NEXT:    andb $15, %dil
113; CHECK-BMI-NEXT:    xorb %dil, %sil
114; CHECK-BMI-NEXT:    movl %esi, %eax
115; CHECK-BMI-NEXT:    retq
116  %n0 = xor i8 %x, %y
117  %n1 = and i8 %n0, 15
118  %r = xor i8 %n1, %y
119  ret i8 %r
120}
121
122define i16 @in16_constmask(i16 %x, i16 %y) {
123; CHECK-NOBMI-LABEL: in16_constmask:
124; CHECK-NOBMI:       # %bb.0:
125; CHECK-NOBMI-NEXT:    xorl %esi, %edi
126; CHECK-NOBMI-NEXT:    movzbl %dil, %eax
127; CHECK-NOBMI-NEXT:    xorl %esi, %eax
128; CHECK-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
129; CHECK-NOBMI-NEXT:    retq
130;
131; CHECK-BMI-LABEL: in16_constmask:
132; CHECK-BMI:       # %bb.0:
133; CHECK-BMI-NEXT:    xorl %esi, %edi
134; CHECK-BMI-NEXT:    movzbl %dil, %eax
135; CHECK-BMI-NEXT:    xorl %esi, %eax
136; CHECK-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
137; CHECK-BMI-NEXT:    retq
138  %n0 = xor i16 %x, %y
139  %n1 = and i16 %n0, 255
140  %r = xor i16 %n1, %y
141  ret i16 %r
142}
143
144define i32 @in32_constmask(i32 %x, i32 %y) {
145; CHECK-NOBMI-LABEL: in32_constmask:
146; CHECK-NOBMI:       # %bb.0:
147; CHECK-NOBMI-NEXT:    xorl %esi, %edi
148; CHECK-NOBMI-NEXT:    movzwl %di, %eax
149; CHECK-NOBMI-NEXT:    xorl %esi, %eax
150; CHECK-NOBMI-NEXT:    retq
151;
152; CHECK-BMI-LABEL: in32_constmask:
153; CHECK-BMI:       # %bb.0:
154; CHECK-BMI-NEXT:    xorl %esi, %edi
155; CHECK-BMI-NEXT:    movzwl %di, %eax
156; CHECK-BMI-NEXT:    xorl %esi, %eax
157; CHECK-BMI-NEXT:    retq
158  %n0 = xor i32 %x, %y
159  %n1 = and i32 %n0, 65535
160  %r = xor i32 %n1, %y
161  ret i32 %r
162}
163
164define i64 @in64_constmask(i64 %x, i64 %y) {
165; CHECK-NOBMI-LABEL: in64_constmask:
166; CHECK-NOBMI:       # %bb.0:
167; CHECK-NOBMI-NEXT:    movl %esi, %eax
168; CHECK-NOBMI-NEXT:    xorl %edi, %eax
169; CHECK-NOBMI-NEXT:    xorq %rsi, %rax
170; CHECK-NOBMI-NEXT:    retq
171;
172; CHECK-BMI-LABEL: in64_constmask:
173; CHECK-BMI:       # %bb.0:
174; CHECK-BMI-NEXT:    movl %esi, %eax
175; CHECK-BMI-NEXT:    xorl %edi, %eax
176; CHECK-BMI-NEXT:    xorq %rsi, %rax
177; CHECK-BMI-NEXT:    retq
178  %n0 = xor i64 %x, %y
179  %n1 = and i64 %n0, 4294967295
180  %r = xor i64 %n1, %y
181  ret i64 %r
182}
183
184; ============================================================================ ;
185; Constant Commutativity tests.
186; ============================================================================ ;
187
188define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
189; CHECK-NOBMI-LABEL: in_constmask_commutativity_0_1:
190; CHECK-NOBMI:       # %bb.0:
191; CHECK-NOBMI-NEXT:    xorl %esi, %edi
192; CHECK-NOBMI-NEXT:    movzwl %di, %eax
193; CHECK-NOBMI-NEXT:    xorl %esi, %eax
194; CHECK-NOBMI-NEXT:    retq
195;
196; CHECK-BMI-LABEL: in_constmask_commutativity_0_1:
197; CHECK-BMI:       # %bb.0:
198; CHECK-BMI-NEXT:    xorl %esi, %edi
199; CHECK-BMI-NEXT:    movzwl %di, %eax
200; CHECK-BMI-NEXT:    xorl %esi, %eax
201; CHECK-BMI-NEXT:    retq
202  %n0 = xor i32 %x, %y
203  %n1 = and i32 %n0, 65535
204  %r = xor i32 %y, %n1 ; swapped
205  ret i32 %r
206}
207
208define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
209; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_0:
210; CHECK-NOBMI:       # %bb.0:
211; CHECK-NOBMI-NEXT:    xorl %edi, %esi
212; CHECK-NOBMI-NEXT:    movzwl %si, %eax
213; CHECK-NOBMI-NEXT:    xorl %edi, %eax
214; CHECK-NOBMI-NEXT:    retq
215;
216; CHECK-BMI-LABEL: in_constmask_commutativity_1_0:
217; CHECK-BMI:       # %bb.0:
218; CHECK-BMI-NEXT:    xorl %edi, %esi
219; CHECK-BMI-NEXT:    movzwl %si, %eax
220; CHECK-BMI-NEXT:    xorl %edi, %eax
221; CHECK-BMI-NEXT:    retq
222  %n0 = xor i32 %x, %y
223  %n1 = and i32 %n0, 65535
224  %r = xor i32 %n1, %x ; %x instead of %y
225  ret i32 %r
226}
227
228define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
229; CHECK-NOBMI-LABEL: in_constmask_commutativity_1_1:
230; CHECK-NOBMI:       # %bb.0:
231; CHECK-NOBMI-NEXT:    xorl %edi, %esi
232; CHECK-NOBMI-NEXT:    movzwl %si, %eax
233; CHECK-NOBMI-NEXT:    xorl %edi, %eax
234; CHECK-NOBMI-NEXT:    retq
235;
236; CHECK-BMI-LABEL: in_constmask_commutativity_1_1:
237; CHECK-BMI:       # %bb.0:
238; CHECK-BMI-NEXT:    xorl %edi, %esi
239; CHECK-BMI-NEXT:    movzwl %si, %eax
240; CHECK-BMI-NEXT:    xorl %edi, %eax
241; CHECK-BMI-NEXT:    retq
242  %n0 = xor i32 %x, %y
243  %n1 = and i32 %n0, 65535
244  %r = xor i32 %x, %n1 ; swapped, %x instead of %y
245  ret i32 %r
246}
247
248; ============================================================================ ;
249; Y is an 'and' too.
250; ============================================================================ ;
251
252define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
253; CHECK-NOBMI-LABEL: in_complex_y0_constmask:
254; CHECK-NOBMI:       # %bb.0:
255; CHECK-NOBMI-NEXT:    andl %edx, %esi
256; CHECK-NOBMI-NEXT:    xorl %esi, %edi
257; CHECK-NOBMI-NEXT:    movzwl %di, %eax
258; CHECK-NOBMI-NEXT:    xorl %esi, %eax
259; CHECK-NOBMI-NEXT:    retq
260;
261; CHECK-BMI-LABEL: in_complex_y0_constmask:
262; CHECK-BMI:       # %bb.0:
263; CHECK-BMI-NEXT:    andl %edx, %esi
264; CHECK-BMI-NEXT:    xorl %esi, %edi
265; CHECK-BMI-NEXT:    movzwl %di, %eax
266; CHECK-BMI-NEXT:    xorl %esi, %eax
267; CHECK-BMI-NEXT:    retq
268  %y = and i32 %y_hi, %y_low
269  %n0 = xor i32 %x, %y
270  %n1 = and i32 %n0, 65535
271  %r = xor i32 %n1, %y
272  ret i32 %r
273}
274
275define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
276; CHECK-NOBMI-LABEL: in_complex_y1_constmask:
277; CHECK-NOBMI:       # %bb.0:
278; CHECK-NOBMI-NEXT:    andl %edx, %esi
279; CHECK-NOBMI-NEXT:    xorl %esi, %edi
280; CHECK-NOBMI-NEXT:    movzwl %di, %eax
281; CHECK-NOBMI-NEXT:    xorl %esi, %eax
282; CHECK-NOBMI-NEXT:    retq
283;
284; CHECK-BMI-LABEL: in_complex_y1_constmask:
285; CHECK-BMI:       # %bb.0:
286; CHECK-BMI-NEXT:    andl %edx, %esi
287; CHECK-BMI-NEXT:    xorl %esi, %edi
288; CHECK-BMI-NEXT:    movzwl %di, %eax
289; CHECK-BMI-NEXT:    xorl %esi, %eax
290; CHECK-BMI-NEXT:    retq
291  %y = and i32 %y_hi, %y_low
292  %n0 = xor i32 %x, %y
293  %n1 = and i32 %n0, 65535
294  %r = xor i32 %y, %n1
295  ret i32 %r
296}
297
298; ============================================================================ ;
299; Negative tests. Should not be folded.
300; ============================================================================ ;
301
302; Multi-use tests.
303
304declare void @use32(i32) nounwind
305
306define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
307; CHECK-NOBMI-LABEL: in_multiuse_A_constmask:
308; CHECK-NOBMI:       # %bb.0:
309; CHECK-NOBMI-NEXT:    pushq %rbp
310; CHECK-NOBMI-NEXT:    pushq %rbx
311; CHECK-NOBMI-NEXT:    pushq %rax
312; CHECK-NOBMI-NEXT:    movl %esi, %ebx
313; CHECK-NOBMI-NEXT:    xorl %esi, %edi
314; CHECK-NOBMI-NEXT:    movzwl %di, %ebp
315; CHECK-NOBMI-NEXT:    movl %ebp, %edi
316; CHECK-NOBMI-NEXT:    callq use32
317; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
318; CHECK-NOBMI-NEXT:    movl %ebp, %eax
319; CHECK-NOBMI-NEXT:    addq $8, %rsp
320; CHECK-NOBMI-NEXT:    popq %rbx
321; CHECK-NOBMI-NEXT:    popq %rbp
322; CHECK-NOBMI-NEXT:    retq
323;
324; CHECK-BMI-LABEL: in_multiuse_A_constmask:
325; CHECK-BMI:       # %bb.0:
326; CHECK-BMI-NEXT:    pushq %rbp
327; CHECK-BMI-NEXT:    pushq %rbx
328; CHECK-BMI-NEXT:    pushq %rax
329; CHECK-BMI-NEXT:    movl %esi, %ebx
330; CHECK-BMI-NEXT:    xorl %esi, %edi
331; CHECK-BMI-NEXT:    movzwl %di, %ebp
332; CHECK-BMI-NEXT:    movl %ebp, %edi
333; CHECK-BMI-NEXT:    callq use32
334; CHECK-BMI-NEXT:    xorl %ebx, %ebp
335; CHECK-BMI-NEXT:    movl %ebp, %eax
336; CHECK-BMI-NEXT:    addq $8, %rsp
337; CHECK-BMI-NEXT:    popq %rbx
338; CHECK-BMI-NEXT:    popq %rbp
339; CHECK-BMI-NEXT:    retq
340  %n0 = xor i32 %x, %y
341  %n1 = and i32 %n0, 65535
342  call void @use32(i32 %n1)
343  %r = xor i32 %n1, %y
344  ret i32 %r
345}
346
347define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
348; CHECK-NOBMI-LABEL: in_multiuse_B_constmask:
349; CHECK-NOBMI:       # %bb.0:
350; CHECK-NOBMI-NEXT:    pushq %rbp
351; CHECK-NOBMI-NEXT:    pushq %rbx
352; CHECK-NOBMI-NEXT:    pushq %rax
353; CHECK-NOBMI-NEXT:    movl %esi, %ebx
354; CHECK-NOBMI-NEXT:    xorl %esi, %edi
355; CHECK-NOBMI-NEXT:    movzwl %di, %ebp
356; CHECK-NOBMI-NEXT:    callq use32
357; CHECK-NOBMI-NEXT:    xorl %ebx, %ebp
358; CHECK-NOBMI-NEXT:    movl %ebp, %eax
359; CHECK-NOBMI-NEXT:    addq $8, %rsp
360; CHECK-NOBMI-NEXT:    popq %rbx
361; CHECK-NOBMI-NEXT:    popq %rbp
362; CHECK-NOBMI-NEXT:    retq
363;
364; CHECK-BMI-LABEL: in_multiuse_B_constmask:
365; CHECK-BMI:       # %bb.0:
366; CHECK-BMI-NEXT:    pushq %rbp
367; CHECK-BMI-NEXT:    pushq %rbx
368; CHECK-BMI-NEXT:    pushq %rax
369; CHECK-BMI-NEXT:    movl %esi, %ebx
370; CHECK-BMI-NEXT:    xorl %esi, %edi
371; CHECK-BMI-NEXT:    movzwl %di, %ebp
372; CHECK-BMI-NEXT:    callq use32
373; CHECK-BMI-NEXT:    xorl %ebx, %ebp
374; CHECK-BMI-NEXT:    movl %ebp, %eax
375; CHECK-BMI-NEXT:    addq $8, %rsp
376; CHECK-BMI-NEXT:    popq %rbx
377; CHECK-BMI-NEXT:    popq %rbp
378; CHECK-BMI-NEXT:    retq
379  %n0 = xor i32 %x, %y
380  %n1 = and i32 %n0, 65535
381  call void @use32(i32 %n0)
382  %r = xor i32 %n1, %y
383  ret i32 %r
384}
385
386; Various bad variants
387
388define i32 @n0_badconstmask(i32 %x, i32 %y) {
389; CHECK-NOBMI-LABEL: n0_badconstmask:
390; CHECK-NOBMI:       # %bb.0:
391; CHECK-NOBMI-NEXT:    movzwl %di, %eax
392; CHECK-NOBMI-NEXT:    andl $-65535, %esi # imm = 0xFFFF0001
393; CHECK-NOBMI-NEXT:    orl %esi, %eax
394; CHECK-NOBMI-NEXT:    retq
395;
396; CHECK-BMI-LABEL: n0_badconstmask:
397; CHECK-BMI:       # %bb.0:
398; CHECK-BMI-NEXT:    movzwl %di, %eax
399; CHECK-BMI-NEXT:    andl $-65535, %esi # imm = 0xFFFF0001
400; CHECK-BMI-NEXT:    orl %esi, %eax
401; CHECK-BMI-NEXT:    retq
402  %mx = and i32 %x, 65535
403  %my = and i32 %y, -65535 ; instead of -65536
404  %r = or i32 %mx, %my
405  ret i32 %r
406}
407
408define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
409; CHECK-NOBMI-LABEL: n1_thirdvar_constmask:
410; CHECK-NOBMI:       # %bb.0:
411; CHECK-NOBMI-NEXT:    xorl %esi, %edi
412; CHECK-NOBMI-NEXT:    movzwl %di, %eax
413; CHECK-NOBMI-NEXT:    xorl %edx, %eax
414; CHECK-NOBMI-NEXT:    retq
415;
416; CHECK-BMI-LABEL: n1_thirdvar_constmask:
417; CHECK-BMI:       # %bb.0:
418; CHECK-BMI-NEXT:    xorl %esi, %edi
419; CHECK-BMI-NEXT:    movzwl %di, %eax
420; CHECK-BMI-NEXT:    xorl %edx, %eax
421; CHECK-BMI-NEXT:    retq
422  %n0 = xor i32 %x, %y
423  %n1 = and i32 %n0, 65535
424  %r = xor i32 %n1, %z ; instead of %y
425  ret i32 %r
426}
427