xref: /llvm-project/llvm/test/CodeGen/X86/andnot-patterns.ll (revision f7b5f0c805c899b59bcc37279a0a05dca35d3a25)
13e31e30aSSimon Pilgrim; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
27da0a698SSimon Pilgrim; RUN: llc < %s -mtriple=i686-- -mattr=-bmi | FileCheck %s --check-prefixes=X86,X86-NOBMI
37da0a698SSimon Pilgrim; RUN: llc < %s -mtriple=i686-- -mattr=+bmi | FileCheck %s --check-prefixes=X86,X86-BMI
47da0a698SSimon Pilgrim; RUN: llc < %s -mtriple=x86_64-- -mattr=-bmi | FileCheck %s --check-prefixes=X64,X64-NOBMI
57da0a698SSimon Pilgrim; RUN: llc < %s -mtriple=x86_64-- -mattr=+bmi | FileCheck %s --check-prefixes=X64,X64-BMI
63e31e30aSSimon Pilgrim
73e31e30aSSimon Pilgrim; TODO - PR112425 - attempt to reconstruct andnot patterns through bitwise-agnostic operations
83e31e30aSSimon Pilgrim
93e31e30aSSimon Pilgrimdeclare void @use_i64(i64)
10056cf936SSimon Pilgrimdeclare void @use_i32(i32)
113e31e30aSSimon Pilgrim
123e31e30aSSimon Pilgrim;
133e31e30aSSimon Pilgrim; Fold (and X, (rotl (not Y), Z))) -> (and X, (not (rotl Y, Z)))
143e31e30aSSimon Pilgrim;
153e31e30aSSimon Pilgrim
16e839d2a6SSimon Pilgrimdefine i64 @andnot_rotl_i64(i64 %a0, i64 %a1, i64 %a2) nounwind {
17*f7b5f0c8SSimon Pilgrim; X86-NOBMI-LABEL: andnot_rotl_i64:
18*f7b5f0c8SSimon Pilgrim; X86-NOBMI:       # %bb.0:
19*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    pushl %esi
20*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
21*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
22*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
23*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    testb $32, %cl
24*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    jne .LBB0_1
25*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:  # %bb.2:
26*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %edx
27*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    jmp .LBB0_3
28*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:  .LBB0_1:
29*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %esi, %edx
30*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %esi
31*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:  .LBB0_3:
32*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %esi, %eax
33*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    shldl %cl, %edx, %eax
34*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
35*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
36*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
37*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    shldl %cl, %esi, %edx
38*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %edx
39*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
40*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    popl %esi
41*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    retl
423e31e30aSSimon Pilgrim;
43*f7b5f0c8SSimon Pilgrim; X86-BMI-LABEL: andnot_rotl_i64:
44*f7b5f0c8SSimon Pilgrim; X86-BMI:       # %bb.0:
45*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    pushl %esi
46*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
47*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
48*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
49*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    testb $32, %cl
50*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    jne .LBB0_1
51*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:  # %bb.2:
52*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %esi
53*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    jmp .LBB0_3
54*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:  .LBB0_1:
55*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %edx, %esi
56*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %edx
57*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:  .LBB0_3:
58*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %edx, %eax
59*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    shldl %cl, %esi, %eax
60*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
61*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
62*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    shldl %cl, %edx, %esi
63*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %edx
64*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    popl %esi
65*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    retl
66*f7b5f0c8SSimon Pilgrim;
67*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotl_i64:
68*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
69*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rdx, %rcx
70*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rsi, %rax
71*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
72*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    rolq %cl, %rax
73*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notq %rax
74*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rdi, %rax
75*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
76*f7b5f0c8SSimon Pilgrim;
77*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotl_i64:
78*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
79*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movq %rdx, %rcx
80*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $rcx
81*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    rolq %cl, %rsi
82*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnq %rdi, %rsi, %rax
83*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
84e839d2a6SSimon Pilgrim  %not = xor i64 %a1, -1
85e839d2a6SSimon Pilgrim  %rot = tail call i64 @llvm.fshl.i64(i64 %not, i64 %not, i64 %a2)
863e31e30aSSimon Pilgrim  %and = and i64 %rot, %a0
873e31e30aSSimon Pilgrim  ret i64 %and
883e31e30aSSimon Pilgrim}
893e31e30aSSimon Pilgrim
90e839d2a6SSimon Pilgrimdefine i32 @andnot_rotl_i32(i32 %a0, i32 %a1, i32 %a2) nounwind {
91*f7b5f0c8SSimon Pilgrim; X86-NOBMI-LABEL: andnot_rotl_i32:
92*f7b5f0c8SSimon Pilgrim; X86-NOBMI:       # %bb.0:
93*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
94*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
95*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    roll %cl, %eax
96*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
97*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
98*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    retl
993e31e30aSSimon Pilgrim;
100*f7b5f0c8SSimon Pilgrim; X86-BMI-LABEL: andnot_rotl_i32:
101*f7b5f0c8SSimon Pilgrim; X86-BMI:       # %bb.0:
102*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
103*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
104*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    roll %cl, %eax
105*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
106*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    retl
107*f7b5f0c8SSimon Pilgrim;
108*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotl_i32:
109*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
110*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %edx, %ecx
111*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
112*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
113*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    roll %cl, %eax
114*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
115*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
116*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
117*f7b5f0c8SSimon Pilgrim;
118*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotl_i32:
119*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
120*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %edx, %ecx
121*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
122*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    roll %cl, %esi
123*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %eax
124*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
125e839d2a6SSimon Pilgrim  %not = xor i32 %a1, -1
126e839d2a6SSimon Pilgrim  %rot = tail call i32 @llvm.fshl.i32(i32 %not, i32 %not, i32 %a2)
1273e31e30aSSimon Pilgrim  %and = and i32 %rot, %a0
1283e31e30aSSimon Pilgrim  ret i32 %and
1293e31e30aSSimon Pilgrim}
1303e31e30aSSimon Pilgrim
131e839d2a6SSimon Pilgrimdefine i16 @andnot_rotl_i16(i16 %a0, i16 %a1, i16 %a2) nounwind {
1323e31e30aSSimon Pilgrim; X86-LABEL: andnot_rotl_i16:
1333e31e30aSSimon Pilgrim; X86:       # %bb.0:
1343e31e30aSSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
135*f7b5f0c8SSimon Pilgrim; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1363e31e30aSSimon Pilgrim; X86-NEXT:    rolw %cl, %ax
137*f7b5f0c8SSimon Pilgrim; X86-NEXT:    notl %eax
138e839d2a6SSimon Pilgrim; X86-NEXT:    andw {{[0-9]+}}(%esp), %ax
1393e31e30aSSimon Pilgrim; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1403e31e30aSSimon Pilgrim; X86-NEXT:    retl
1413e31e30aSSimon Pilgrim;
142*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotl_i16:
143*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
144*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %edx, %ecx
145*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
146*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
147*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    rolw %cl, %ax
148*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
149*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
150*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
151*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
152*f7b5f0c8SSimon Pilgrim;
153*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotl_i16:
154*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
155*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %edx, %ecx
156*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
157*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    rolw %cl, %si
158*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %eax
159*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
160*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
161e839d2a6SSimon Pilgrim  %not = xor i16 %a1, -1
162e839d2a6SSimon Pilgrim  %rot = tail call i16 @llvm.fshl.i16(i16 %not, i16 %not, i16 %a2)
1633e31e30aSSimon Pilgrim  %and = and i16 %rot, %a0
1643e31e30aSSimon Pilgrim  ret i16 %and
1653e31e30aSSimon Pilgrim}
1663e31e30aSSimon Pilgrim
167e839d2a6SSimon Pilgrimdefine i8 @andnot_rotl_i8(i8 %a0, i8 %a1, i8 %a2) nounwind {
1683e31e30aSSimon Pilgrim; X86-LABEL: andnot_rotl_i8:
1693e31e30aSSimon Pilgrim; X86:       # %bb.0:
1703e31e30aSSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
171e839d2a6SSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
1723e31e30aSSimon Pilgrim; X86-NEXT:    rolb %cl, %al
173*f7b5f0c8SSimon Pilgrim; X86-NEXT:    notb %al
174e839d2a6SSimon Pilgrim; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
1753e31e30aSSimon Pilgrim; X86-NEXT:    retl
1763e31e30aSSimon Pilgrim;
1773e31e30aSSimon Pilgrim; X64-LABEL: andnot_rotl_i8:
1783e31e30aSSimon Pilgrim; X64:       # %bb.0:
179e839d2a6SSimon Pilgrim; X64-NEXT:    movl %edx, %ecx
180e839d2a6SSimon Pilgrim; X64-NEXT:    movl %esi, %eax
1813e31e30aSSimon Pilgrim; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1823e31e30aSSimon Pilgrim; X64-NEXT:    rolb %cl, %al
183*f7b5f0c8SSimon Pilgrim; X64-NEXT:    notb %al
1843e31e30aSSimon Pilgrim; X64-NEXT:    andb %dil, %al
185e839d2a6SSimon Pilgrim; X64-NEXT:    # kill: def $al killed $al killed $eax
1863e31e30aSSimon Pilgrim; X64-NEXT:    retq
187e839d2a6SSimon Pilgrim  %not = xor i8 %a1, -1
188e839d2a6SSimon Pilgrim  %rot = tail call i8 @llvm.fshl.i8(i8 %not, i8 %not, i8 %a2)
1893e31e30aSSimon Pilgrim  %and = and i8 %rot, %a0
1903e31e30aSSimon Pilgrim  ret i8 %and
1913e31e30aSSimon Pilgrim}
1923e31e30aSSimon Pilgrim
193056cf936SSimon Pilgrimdefine i64 @andnot_rotl_i64_multiuse_rot(i64 %a0, i64 %a1, i64 %a2) nounwind {
194056cf936SSimon Pilgrim; X86-LABEL: andnot_rotl_i64_multiuse_rot:
1953e31e30aSSimon Pilgrim; X86:       # %bb.0:
1963e31e30aSSimon Pilgrim; X86-NEXT:    pushl %ebx
1973e31e30aSSimon Pilgrim; X86-NEXT:    pushl %edi
1983e31e30aSSimon Pilgrim; X86-NEXT:    pushl %esi
1993e31e30aSSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
2003e31e30aSSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
201e839d2a6SSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
202e839d2a6SSimon Pilgrim; X86-NEXT:    notl %edx
203e839d2a6SSimon Pilgrim; X86-NEXT:    notl %esi
2043e31e30aSSimon Pilgrim; X86-NEXT:    testb $32, %cl
2053e31e30aSSimon Pilgrim; X86-NEXT:    jne .LBB4_1
2063e31e30aSSimon Pilgrim; X86-NEXT:  # %bb.2:
207e839d2a6SSimon Pilgrim; X86-NEXT:    movl %esi, %eax
2083e31e30aSSimon Pilgrim; X86-NEXT:    jmp .LBB4_3
2093e31e30aSSimon Pilgrim; X86-NEXT:  .LBB4_1:
210e839d2a6SSimon Pilgrim; X86-NEXT:    movl %edx, %eax
211e839d2a6SSimon Pilgrim; X86-NEXT:    movl %esi, %edx
2123e31e30aSSimon Pilgrim; X86-NEXT:  .LBB4_3:
213e839d2a6SSimon Pilgrim; X86-NEXT:    movl %edx, %ebx
214e839d2a6SSimon Pilgrim; X86-NEXT:    shldl %cl, %eax, %ebx
2153e31e30aSSimon Pilgrim; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
216e839d2a6SSimon Pilgrim; X86-NEXT:    shldl %cl, %edx, %eax
217e839d2a6SSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
218e839d2a6SSimon Pilgrim; X86-NEXT:    andl %eax, %esi
219e839d2a6SSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
2203e31e30aSSimon Pilgrim; X86-NEXT:    andl %ebx, %edi
2213e31e30aSSimon Pilgrim; X86-NEXT:    pushl %ebx
222e839d2a6SSimon Pilgrim; X86-NEXT:    pushl %eax
2233e31e30aSSimon Pilgrim; X86-NEXT:    calll use_i64@PLT
2243e31e30aSSimon Pilgrim; X86-NEXT:    addl $8, %esp
2253e31e30aSSimon Pilgrim; X86-NEXT:    movl %esi, %eax
2263e31e30aSSimon Pilgrim; X86-NEXT:    movl %edi, %edx
2273e31e30aSSimon Pilgrim; X86-NEXT:    popl %esi
2283e31e30aSSimon Pilgrim; X86-NEXT:    popl %edi
2293e31e30aSSimon Pilgrim; X86-NEXT:    popl %ebx
2303e31e30aSSimon Pilgrim; X86-NEXT:    retl
2313e31e30aSSimon Pilgrim;
232056cf936SSimon Pilgrim; X64-LABEL: andnot_rotl_i64_multiuse_rot:
2333e31e30aSSimon Pilgrim; X64:       # %bb.0:
2343e31e30aSSimon Pilgrim; X64-NEXT:    pushq %rbx
235e839d2a6SSimon Pilgrim; X64-NEXT:    movq %rdx, %rcx
2363e31e30aSSimon Pilgrim; X64-NEXT:    movq %rdi, %rbx
237e839d2a6SSimon Pilgrim; X64-NEXT:    notq %rsi
2383e31e30aSSimon Pilgrim; X64-NEXT:    # kill: def $cl killed $cl killed $rcx
239e839d2a6SSimon Pilgrim; X64-NEXT:    rolq %cl, %rsi
240e839d2a6SSimon Pilgrim; X64-NEXT:    andq %rsi, %rbx
241e839d2a6SSimon Pilgrim; X64-NEXT:    movq %rsi, %rdi
2423e31e30aSSimon Pilgrim; X64-NEXT:    callq use_i64@PLT
2433e31e30aSSimon Pilgrim; X64-NEXT:    movq %rbx, %rax
2443e31e30aSSimon Pilgrim; X64-NEXT:    popq %rbx
2453e31e30aSSimon Pilgrim; X64-NEXT:    retq
246e839d2a6SSimon Pilgrim  %not = xor i64 %a1, -1
247e839d2a6SSimon Pilgrim  %rot = tail call i64 @llvm.fshl.i64(i64 %not, i64 %not, i64 %a2)
2483e31e30aSSimon Pilgrim  %and = and i64 %rot, %a0
2493e31e30aSSimon Pilgrim  call void @use_i64(i64 %rot)
2503e31e30aSSimon Pilgrim  ret i64 %and
2513e31e30aSSimon Pilgrim}
2523e31e30aSSimon Pilgrim
2533e31e30aSSimon Pilgrim;
2543e31e30aSSimon Pilgrim; Fold (and X, (rotr (not Y), Z))) -> (and X, (not (rotr Y, Z)))
2553e31e30aSSimon Pilgrim;
2563e31e30aSSimon Pilgrim
257e839d2a6SSimon Pilgrimdefine i64 @andnot_rotr_i64(i64 %a0, i64 %a1, i64 %a2) nounwind {
258*f7b5f0c8SSimon Pilgrim; X86-NOBMI-LABEL: andnot_rotr_i64:
259*f7b5f0c8SSimon Pilgrim; X86-NOBMI:       # %bb.0:
260*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    pushl %esi
261*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
262*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
263*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
264*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    testb $32, %cl
265*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    je .LBB5_1
266*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:  # %bb.2:
267*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %edx
268*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    jmp .LBB5_3
269*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:  .LBB5_1:
270*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %esi, %edx
271*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %esi
272*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:  .LBB5_3:
273*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %esi, %eax
274*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    shrdl %cl, %edx, %eax
275*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
276*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
277*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
278*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    shrdl %cl, %esi, %edx
279*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %edx
280*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
281*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    popl %esi
282*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    retl
2833e31e30aSSimon Pilgrim;
284*f7b5f0c8SSimon Pilgrim; X86-BMI-LABEL: andnot_rotr_i64:
285*f7b5f0c8SSimon Pilgrim; X86-BMI:       # %bb.0:
286*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    pushl %esi
287*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
288*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
289*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
290*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    testb $32, %cl
291*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    je .LBB5_1
292*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:  # %bb.2:
293*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %esi
294*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    jmp .LBB5_3
295*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:  .LBB5_1:
296*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %edx, %esi
297*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %edx
298*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:  .LBB5_3:
299*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %edx, %eax
300*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    shrdl %cl, %esi, %eax
301*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
302*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
303*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    shrdl %cl, %edx, %esi
304*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %esi, %edx
305*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    popl %esi
306*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    retl
307*f7b5f0c8SSimon Pilgrim;
308*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotr_i64:
309*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
310*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rdx, %rcx
311*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rsi, %rax
312*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $rcx
313*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    rorq %cl, %rax
314*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notq %rax
315*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rdi, %rax
316*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
317*f7b5f0c8SSimon Pilgrim;
318*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotr_i64:
319*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
320*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movq %rdx, %rcx
321*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $rcx
322*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    rorq %cl, %rsi
323*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnq %rdi, %rsi, %rax
324*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
325e839d2a6SSimon Pilgrim  %not = xor i64 %a1, -1
326e839d2a6SSimon Pilgrim  %rot = tail call i64 @llvm.fshr.i64(i64 %not, i64 %not, i64 %a2)
3273e31e30aSSimon Pilgrim  %and = and i64 %rot, %a0
3283e31e30aSSimon Pilgrim  ret i64 %and
3293e31e30aSSimon Pilgrim}
3303e31e30aSSimon Pilgrim
331e839d2a6SSimon Pilgrimdefine i32 @andnot_rotr_i32(i32 %a0, i32 %a1, i32 %a2) nounwind {
332*f7b5f0c8SSimon Pilgrim; X86-NOBMI-LABEL: andnot_rotr_i32:
333*f7b5f0c8SSimon Pilgrim; X86-NOBMI:       # %bb.0:
334*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
335*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
336*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    rorl %cl, %eax
337*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
338*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
339*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    retl
3403e31e30aSSimon Pilgrim;
341*f7b5f0c8SSimon Pilgrim; X86-BMI-LABEL: andnot_rotr_i32:
342*f7b5f0c8SSimon Pilgrim; X86-BMI:       # %bb.0:
343*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
344*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
345*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    rorl %cl, %eax
346*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
347*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    retl
348*f7b5f0c8SSimon Pilgrim;
349*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotr_i32:
350*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
351*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %edx, %ecx
352*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
353*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
354*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    rorl %cl, %eax
355*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
356*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
357*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
358*f7b5f0c8SSimon Pilgrim;
359*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotr_i32:
360*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
361*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %edx, %ecx
362*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
363*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    rorl %cl, %esi
364*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %eax
365*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
366e839d2a6SSimon Pilgrim  %not = xor i32 %a1, -1
367e839d2a6SSimon Pilgrim  %rot = tail call i32 @llvm.fshr.i32(i32 %not, i32 %not, i32 %a2)
3683e31e30aSSimon Pilgrim  %and = and i32 %rot, %a0
3693e31e30aSSimon Pilgrim  ret i32 %and
3703e31e30aSSimon Pilgrim}
3713e31e30aSSimon Pilgrim
372e839d2a6SSimon Pilgrimdefine i16 @andnot_rotr_i16(i16 %a0, i16 %a1, i16 %a2) nounwind {
3733e31e30aSSimon Pilgrim; X86-LABEL: andnot_rotr_i16:
3743e31e30aSSimon Pilgrim; X86:       # %bb.0:
3753e31e30aSSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
376*f7b5f0c8SSimon Pilgrim; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
377e839d2a6SSimon Pilgrim; X86-NEXT:    rorw %cl, %ax
378*f7b5f0c8SSimon Pilgrim; X86-NEXT:    notl %eax
379e839d2a6SSimon Pilgrim; X86-NEXT:    andw {{[0-9]+}}(%esp), %ax
3803e31e30aSSimon Pilgrim; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3813e31e30aSSimon Pilgrim; X86-NEXT:    retl
3823e31e30aSSimon Pilgrim;
383*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotr_i16:
384*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
385*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %edx, %ecx
386*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
387*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
388*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    rorw %cl, %ax
389*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
390*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
391*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
392*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
393*f7b5f0c8SSimon Pilgrim;
394*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotr_i16:
395*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
396*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %edx, %ecx
397*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
398*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    rorw %cl, %si
399*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %eax
400*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
401*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
402e839d2a6SSimon Pilgrim  %not = xor i16 %a1, -1
403e839d2a6SSimon Pilgrim  %rot = tail call i16 @llvm.fshr.i16(i16 %not, i16 %not, i16 %a2)
4043e31e30aSSimon Pilgrim  %and = and i16 %rot, %a0
4053e31e30aSSimon Pilgrim  ret i16 %and
4063e31e30aSSimon Pilgrim}
4073e31e30aSSimon Pilgrim
408e839d2a6SSimon Pilgrimdefine i8 @andnot_rotr_i8(i8 %a0, i8 %a1, i8 %a2) nounwind {
4093e31e30aSSimon Pilgrim; X86-LABEL: andnot_rotr_i8:
4103e31e30aSSimon Pilgrim; X86:       # %bb.0:
4113e31e30aSSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
412e839d2a6SSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
413e839d2a6SSimon Pilgrim; X86-NEXT:    rorb %cl, %al
414*f7b5f0c8SSimon Pilgrim; X86-NEXT:    notb %al
415e839d2a6SSimon Pilgrim; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
4163e31e30aSSimon Pilgrim; X86-NEXT:    retl
4173e31e30aSSimon Pilgrim;
4183e31e30aSSimon Pilgrim; X64-LABEL: andnot_rotr_i8:
4193e31e30aSSimon Pilgrim; X64:       # %bb.0:
420e839d2a6SSimon Pilgrim; X64-NEXT:    movl %edx, %ecx
421e839d2a6SSimon Pilgrim; X64-NEXT:    movl %esi, %eax
4223e31e30aSSimon Pilgrim; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
423e839d2a6SSimon Pilgrim; X64-NEXT:    rorb %cl, %al
424*f7b5f0c8SSimon Pilgrim; X64-NEXT:    notb %al
4253e31e30aSSimon Pilgrim; X64-NEXT:    andb %dil, %al
426e839d2a6SSimon Pilgrim; X64-NEXT:    # kill: def $al killed $al killed $eax
4273e31e30aSSimon Pilgrim; X64-NEXT:    retq
428e839d2a6SSimon Pilgrim  %not = xor i8 %a1, -1
429e839d2a6SSimon Pilgrim  %rot = tail call i8 @llvm.fshr.i8(i8 %not, i8 %not, i8 %a2)
4303e31e30aSSimon Pilgrim  %and = and i8 %rot, %a0
4313e31e30aSSimon Pilgrim  ret i8 %and
4323e31e30aSSimon Pilgrim}
4333e31e30aSSimon Pilgrim
434056cf936SSimon Pilgrimdefine i32 @andnot_rotr_i32_multiuse_not(i32 %a0, i32 %a1, i32 %a2) nounwind {
435*f7b5f0c8SSimon Pilgrim; X86-NOBMI-LABEL: andnot_rotr_i32_multiuse_not:
436*f7b5f0c8SSimon Pilgrim; X86-NOBMI:       # %bb.0:
437*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    pushl %esi
438*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
439*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
440*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
441*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %esi
442*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    rorl %cl, %esi
443*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
444*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    pushl %eax
445*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    calll use_i32@PLT
446*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    addl $4, %esp
447*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    movl %esi, %eax
448*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    popl %esi
449*f7b5f0c8SSimon Pilgrim; X86-NOBMI-NEXT:    retl
450056cf936SSimon Pilgrim;
451*f7b5f0c8SSimon Pilgrim; X86-BMI-LABEL: andnot_rotr_i32_multiuse_not:
452*f7b5f0c8SSimon Pilgrim; X86-BMI:       # %bb.0:
453*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    pushl %esi
454*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
455*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
456*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %edx
457*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    notl %edx
458*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    rorl %cl, %eax
459*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %esi
460*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    pushl %edx
461*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    calll use_i32@PLT
462*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    addl $4, %esp
463*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    movl %esi, %eax
464*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    popl %esi
465*f7b5f0c8SSimon Pilgrim; X86-BMI-NEXT:    retl
466*f7b5f0c8SSimon Pilgrim;
467*f7b5f0c8SSimon Pilgrim; X64-NOBMI-LABEL: andnot_rotr_i32_multiuse_not:
468*f7b5f0c8SSimon Pilgrim; X64-NOBMI:       # %bb.0:
469*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    pushq %rbx
470*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %edx, %ecx
471*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    notl %esi
472*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %ebx
473*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
474*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    rorl %cl, %ebx
475*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %ebx
476*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %edi
477*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    callq use_i32@PLT
478*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    movl %ebx, %eax
479*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    popq %rbx
480*f7b5f0c8SSimon Pilgrim; X64-NOBMI-NEXT:    retq
481*f7b5f0c8SSimon Pilgrim;
482*f7b5f0c8SSimon Pilgrim; X64-BMI-LABEL: andnot_rotr_i32_multiuse_not:
483*f7b5f0c8SSimon Pilgrim; X64-BMI:       # %bb.0:
484*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    pushq %rbx
485*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %edx, %ecx
486*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %esi, %eax
487*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    notl %eax
488*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
489*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    rorl %cl, %esi
490*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %ebx
491*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %eax, %edi
492*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    callq use_i32@PLT
493*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    movl %ebx, %eax
494*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    popq %rbx
495*f7b5f0c8SSimon Pilgrim; X64-BMI-NEXT:    retq
496056cf936SSimon Pilgrim  %not = xor i32 %a1, -1
497056cf936SSimon Pilgrim  %rot = tail call i32 @llvm.fshr.i32(i32 %not, i32 %not, i32 %a2)
498056cf936SSimon Pilgrim  %and = and i32 %rot, %a0
499056cf936SSimon Pilgrim  call void @use_i32(i32 %not)
500056cf936SSimon Pilgrim  ret i32 %and
501056cf936SSimon Pilgrim}
502056cf936SSimon Pilgrim
5033e31e30aSSimon Pilgrim;
5043e31e30aSSimon Pilgrim; Fold (and X, (bswap (not Y)))) -> (and X, (not (bswap Y)))
5053e31e30aSSimon Pilgrim;
5063e31e30aSSimon Pilgrim
507e839d2a6SSimon Pilgrimdefine i64 @andnot_bswap_i64(i64 %a0, i64 %a1) nounwind {
508056cf936SSimon Pilgrim; X86-NOBMI-LABEL: andnot_bswap_i64:
509056cf936SSimon Pilgrim; X86-NOBMI:       # %bb.0:
510056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
511056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
512056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %eax
513056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
514056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
515056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %edx
516056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %edx
517056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
518056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    retl
5193e31e30aSSimon Pilgrim;
520056cf936SSimon Pilgrim; X86-BMI-LABEL: andnot_bswap_i64:
521056cf936SSimon Pilgrim; X86-BMI:       # %bb.0:
522056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
523056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
524056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %eax
525056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
526056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %ecx
527056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %ecx, %edx
528056cf936SSimon Pilgrim; X86-BMI-NEXT:    retl
529056cf936SSimon Pilgrim;
530056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bswap_i64:
531056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
532056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rsi, %rax
533056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    bswapq %rax
534056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notq %rax
535056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rdi, %rax
536056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
537056cf936SSimon Pilgrim;
538056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bswap_i64:
539056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
540056cf936SSimon Pilgrim; X64-BMI-NEXT:    bswapq %rsi
541056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnq %rdi, %rsi, %rax
542056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
543e839d2a6SSimon Pilgrim  %not = xor i64 %a1, -1
5443e31e30aSSimon Pilgrim  %bswap = tail call i64 @llvm.bswap.i64(i64 %not)
5453e31e30aSSimon Pilgrim  %and = and i64 %bswap, %a0
5463e31e30aSSimon Pilgrim  ret i64 %and
5473e31e30aSSimon Pilgrim}
5483e31e30aSSimon Pilgrim
549e839d2a6SSimon Pilgrimdefine i32 @andnot_bswap_i32(i32 %a0, i32 %a1) nounwind {
550056cf936SSimon Pilgrim; X86-NOBMI-LABEL: andnot_bswap_i32:
551056cf936SSimon Pilgrim; X86-NOBMI:       # %bb.0:
552056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
553056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %eax
554056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
555056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
556056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    retl
5573e31e30aSSimon Pilgrim;
558056cf936SSimon Pilgrim; X86-BMI-LABEL: andnot_bswap_i32:
559056cf936SSimon Pilgrim; X86-BMI:       # %bb.0:
560056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
561056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %eax
562056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
563056cf936SSimon Pilgrim; X86-BMI-NEXT:    retl
564056cf936SSimon Pilgrim;
565056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bswap_i32:
566056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
567056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
568056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    bswapl %eax
569056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
570056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
571056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
572056cf936SSimon Pilgrim;
573056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bswap_i32:
574056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
575056cf936SSimon Pilgrim; X64-BMI-NEXT:    bswapl %esi
576056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %eax
577056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
578e839d2a6SSimon Pilgrim  %not = xor i32 %a1, -1
5793e31e30aSSimon Pilgrim  %bswap = tail call i32 @llvm.bswap.i32(i32 %not)
5803e31e30aSSimon Pilgrim  %and = and i32 %bswap, %a0
5813e31e30aSSimon Pilgrim  ret i32 %and
5823e31e30aSSimon Pilgrim}
5833e31e30aSSimon Pilgrim
584e839d2a6SSimon Pilgrimdefine i16 @andnot_bswap_i16(i16 %a0, i16 %a1) nounwind {
5853e31e30aSSimon Pilgrim; X86-LABEL: andnot_bswap_i16:
5863e31e30aSSimon Pilgrim; X86:       # %bb.0:
587056cf936SSimon Pilgrim; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
5883e31e30aSSimon Pilgrim; X86-NEXT:    rolw $8, %ax
589056cf936SSimon Pilgrim; X86-NEXT:    notl %eax
590e839d2a6SSimon Pilgrim; X86-NEXT:    andw {{[0-9]+}}(%esp), %ax
5913e31e30aSSimon Pilgrim; X86-NEXT:    # kill: def $ax killed $ax killed $eax
5923e31e30aSSimon Pilgrim; X86-NEXT:    retl
5933e31e30aSSimon Pilgrim;
594056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bswap_i16:
595056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
596056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
597056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    rolw $8, %ax
598056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
599056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
600056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
601056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
602056cf936SSimon Pilgrim;
603056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bswap_i16:
604056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
605056cf936SSimon Pilgrim; X64-BMI-NEXT:    rolw $8, %si
606056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %eax
607056cf936SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
608056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
609e839d2a6SSimon Pilgrim  %not = xor i16 %a1, -1
6103e31e30aSSimon Pilgrim  %bswap = tail call i16 @llvm.bswap.i16(i16 %not)
6113e31e30aSSimon Pilgrim  %and = and i16 %bswap, %a0
6123e31e30aSSimon Pilgrim  ret i16 %and
6133e31e30aSSimon Pilgrim}
6143e31e30aSSimon Pilgrim
615056cf936SSimon Pilgrimdefine i32 @andnot_bswap_i32_multiuse_bswap(i32 %a0, i32 %a1) nounwind {
616056cf936SSimon Pilgrim; X86-LABEL: andnot_bswap_i32_multiuse_bswap:
617056cf936SSimon Pilgrim; X86:       # %bb.0:
618056cf936SSimon Pilgrim; X86-NEXT:    pushl %esi
619056cf936SSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
620056cf936SSimon Pilgrim; X86-NEXT:    notl %eax
621056cf936SSimon Pilgrim; X86-NEXT:    bswapl %eax
622056cf936SSimon Pilgrim; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
623056cf936SSimon Pilgrim; X86-NEXT:    andl %eax, %esi
624056cf936SSimon Pilgrim; X86-NEXT:    pushl %eax
625056cf936SSimon Pilgrim; X86-NEXT:    calll use_i32@PLT
626056cf936SSimon Pilgrim; X86-NEXT:    addl $4, %esp
627056cf936SSimon Pilgrim; X86-NEXT:    movl %esi, %eax
628056cf936SSimon Pilgrim; X86-NEXT:    popl %esi
629056cf936SSimon Pilgrim; X86-NEXT:    retl
630056cf936SSimon Pilgrim;
631056cf936SSimon Pilgrim; X64-LABEL: andnot_bswap_i32_multiuse_bswap:
632056cf936SSimon Pilgrim; X64:       # %bb.0:
633056cf936SSimon Pilgrim; X64-NEXT:    pushq %rbx
634056cf936SSimon Pilgrim; X64-NEXT:    movl %edi, %ebx
635056cf936SSimon Pilgrim; X64-NEXT:    notl %esi
636056cf936SSimon Pilgrim; X64-NEXT:    bswapl %esi
637056cf936SSimon Pilgrim; X64-NEXT:    andl %esi, %ebx
638056cf936SSimon Pilgrim; X64-NEXT:    movl %esi, %edi
639056cf936SSimon Pilgrim; X64-NEXT:    callq use_i32@PLT
640056cf936SSimon Pilgrim; X64-NEXT:    movl %ebx, %eax
641056cf936SSimon Pilgrim; X64-NEXT:    popq %rbx
642056cf936SSimon Pilgrim; X64-NEXT:    retq
643056cf936SSimon Pilgrim  %not = xor i32 %a1, -1
644056cf936SSimon Pilgrim  %bswap = tail call i32 @llvm.bswap.i32(i32 %not)
645056cf936SSimon Pilgrim  %and = and i32 %bswap, %a0
646056cf936SSimon Pilgrim  call void @use_i32(i32 %bswap)
647056cf936SSimon Pilgrim  ret i32 %and
648056cf936SSimon Pilgrim}
649056cf936SSimon Pilgrim
650056cf936SSimon Pilgrimdefine i32 @andnot_bswap_i32_multiuse_not(i32 %a0, i32 %a1) nounwind {
651056cf936SSimon Pilgrim; X86-NOBMI-LABEL: andnot_bswap_i32_multiuse_not:
652056cf936SSimon Pilgrim; X86-NOBMI:       # %bb.0:
653056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    pushl %esi
654056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
655056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
656056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %esi
657056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %esi
658056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %esi
659056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    pushl %eax
660056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    calll use_i32@PLT
661056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    addl $4, %esp
662056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %esi, %eax
663056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    popl %esi
664056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    retl
665056cf936SSimon Pilgrim;
666056cf936SSimon Pilgrim; X86-BMI-LABEL: andnot_bswap_i32_multiuse_not:
667056cf936SSimon Pilgrim; X86-BMI:       # %bb.0:
668056cf936SSimon Pilgrim; X86-BMI-NEXT:    pushl %esi
669056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
670056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %ecx
671056cf936SSimon Pilgrim; X86-BMI-NEXT:    notl %ecx
672056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %eax
673056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %esi
674056cf936SSimon Pilgrim; X86-BMI-NEXT:    pushl %ecx
675056cf936SSimon Pilgrim; X86-BMI-NEXT:    calll use_i32@PLT
676056cf936SSimon Pilgrim; X86-BMI-NEXT:    addl $4, %esp
677056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %esi, %eax
678056cf936SSimon Pilgrim; X86-BMI-NEXT:    popl %esi
679056cf936SSimon Pilgrim; X86-BMI-NEXT:    retl
680056cf936SSimon Pilgrim;
681056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bswap_i32_multiuse_not:
682056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
683056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    pushq %rbx
684056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notl %esi
685056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %ebx
686056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    bswapl %ebx
687056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %ebx
688056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %edi
689056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    callq use_i32@PLT
690056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %ebx, %eax
691056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    popq %rbx
692056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
693056cf936SSimon Pilgrim;
694056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bswap_i32_multiuse_not:
695056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
696056cf936SSimon Pilgrim; X64-BMI-NEXT:    pushq %rbx
697056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %esi, %eax
698056cf936SSimon Pilgrim; X64-BMI-NEXT:    notl %eax
699056cf936SSimon Pilgrim; X64-BMI-NEXT:    bswapl %esi
700056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %esi, %ebx
701056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %eax, %edi
702056cf936SSimon Pilgrim; X64-BMI-NEXT:    callq use_i32@PLT
703056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %ebx, %eax
704056cf936SSimon Pilgrim; X64-BMI-NEXT:    popq %rbx
705056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
706056cf936SSimon Pilgrim  %not = xor i32 %a1, -1
707056cf936SSimon Pilgrim  %bswap = tail call i32 @llvm.bswap.i32(i32 %not)
708056cf936SSimon Pilgrim  %and = and i32 %bswap, %a0
709056cf936SSimon Pilgrim  call void @use_i32(i32 %not)
710056cf936SSimon Pilgrim  ret i32 %and
711056cf936SSimon Pilgrim}
712056cf936SSimon Pilgrim
7133e31e30aSSimon Pilgrim;
7143e31e30aSSimon Pilgrim; Fold (and X, (bitreverse (not Y)))) -> (and X, (not (bitreverse Y)))
7153e31e30aSSimon Pilgrim;
7163e31e30aSSimon Pilgrim
717e839d2a6SSimon Pilgrimdefine i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
718056cf936SSimon Pilgrim; X86-NOBMI-LABEL: andnot_bitreverse_i64:
719056cf936SSimon Pilgrim; X86-NOBMI:       # %bb.0:
720056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
721056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
722056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %eax
723056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %edx
724056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $252645135, %edx # imm = 0xF0F0F0F
725056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shll $4, %edx
726056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl $4, %eax
727056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $252645135, %eax # imm = 0xF0F0F0F
728056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    orl %edx, %eax
729056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %edx
730056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $858993459, %edx # imm = 0x33333333
731056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl $2, %eax
732056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
733056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    leal (%eax,%edx,4), %eax
734056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %edx
735056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
736056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl %eax
737056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
738056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    leal (%eax,%edx,2), %eax
739056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
740056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
741056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %ecx
742056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %ecx, %edx
743056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $252645135, %edx # imm = 0xF0F0F0F
744056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shll $4, %edx
745056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl $4, %ecx
746056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
747056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    orl %edx, %ecx
748056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %ecx, %edx
749056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $858993459, %edx # imm = 0x33333333
750056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl $2, %ecx
751056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $858993459, %ecx # imm = 0x33333333
752056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    leal (%ecx,%edx,4), %ecx
753056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %ecx, %edx
754056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
755056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl %ecx
756056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
757056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    leal (%ecx,%edx,2), %edx
758056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %edx
759056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
760056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    retl
7613e31e30aSSimon Pilgrim;
762056cf936SSimon Pilgrim; X86-BMI-LABEL: andnot_bitreverse_i64:
763056cf936SSimon Pilgrim; X86-BMI:       # %bb.0:
764056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
765056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
766056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %eax
767056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %edx
768056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $252645135, %edx # imm = 0xF0F0F0F
769056cf936SSimon Pilgrim; X86-BMI-NEXT:    shll $4, %edx
770056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl $4, %eax
771056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $252645135, %eax # imm = 0xF0F0F0F
772056cf936SSimon Pilgrim; X86-BMI-NEXT:    orl %edx, %eax
773056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %edx
774056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $858993459, %edx # imm = 0x33333333
775056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl $2, %eax
776056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
777056cf936SSimon Pilgrim; X86-BMI-NEXT:    leal (%eax,%edx,4), %eax
778056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %edx
779056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
780056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl %eax
781056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
782056cf936SSimon Pilgrim; X86-BMI-NEXT:    leal (%eax,%edx,2), %eax
783056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
784056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %ecx
785056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %ecx, %edx
786056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $252645135, %edx # imm = 0xF0F0F0F
787056cf936SSimon Pilgrim; X86-BMI-NEXT:    shll $4, %edx
788056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl $4, %ecx
789056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
790056cf936SSimon Pilgrim; X86-BMI-NEXT:    orl %edx, %ecx
791056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %ecx, %edx
792056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $858993459, %edx # imm = 0x33333333
793056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl $2, %ecx
794056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $858993459, %ecx # imm = 0x33333333
795056cf936SSimon Pilgrim; X86-BMI-NEXT:    leal (%ecx,%edx,4), %ecx
796056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %ecx, %edx
797056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
798056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl %ecx
799056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
800056cf936SSimon Pilgrim; X86-BMI-NEXT:    leal (%ecx,%edx,2), %ecx
801056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %ecx, %edx
802056cf936SSimon Pilgrim; X86-BMI-NEXT:    retl
803056cf936SSimon Pilgrim;
804056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bitreverse_i64:
805056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
806056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    bswapq %rsi
807056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rsi, %rax
808056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrq $4, %rax
809056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movabsq $1085102592571150095, %rcx # imm = 0xF0F0F0F0F0F0F0F
810056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rcx, %rax
811056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rcx, %rsi
812056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shlq $4, %rsi
813056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    orq %rax, %rsi
814056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movabsq $3689348814741910323, %rax # imm = 0x3333333333333333
815056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rsi, %rcx
816056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rax, %rcx
817056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrq $2, %rsi
818056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rax, %rsi
819056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    leaq (%rsi,%rcx,4), %rax
820056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555
821056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movq %rax, %rdx
822056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rcx, %rdx
823056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrq %rax
824056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rcx, %rax
825056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    leaq (%rax,%rdx,2), %rax
826056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notq %rax
827056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andq %rdi, %rax
828056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
829056cf936SSimon Pilgrim;
830056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bitreverse_i64:
831056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
832056cf936SSimon Pilgrim; X64-BMI-NEXT:    bswapq %rsi
833056cf936SSimon Pilgrim; X64-BMI-NEXT:    movq %rsi, %rax
834056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrq $4, %rax
835056cf936SSimon Pilgrim; X64-BMI-NEXT:    movabsq $1085102592571150095, %rcx # imm = 0xF0F0F0F0F0F0F0F
836056cf936SSimon Pilgrim; X64-BMI-NEXT:    andq %rcx, %rax
837056cf936SSimon Pilgrim; X64-BMI-NEXT:    andq %rcx, %rsi
838056cf936SSimon Pilgrim; X64-BMI-NEXT:    shlq $4, %rsi
839056cf936SSimon Pilgrim; X64-BMI-NEXT:    orq %rax, %rsi
840056cf936SSimon Pilgrim; X64-BMI-NEXT:    movabsq $3689348814741910323, %rax # imm = 0x3333333333333333
841056cf936SSimon Pilgrim; X64-BMI-NEXT:    movq %rsi, %rcx
842056cf936SSimon Pilgrim; X64-BMI-NEXT:    andq %rax, %rcx
843056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrq $2, %rsi
844056cf936SSimon Pilgrim; X64-BMI-NEXT:    andq %rax, %rsi
845056cf936SSimon Pilgrim; X64-BMI-NEXT:    leaq (%rsi,%rcx,4), %rax
846056cf936SSimon Pilgrim; X64-BMI-NEXT:    movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555
847056cf936SSimon Pilgrim; X64-BMI-NEXT:    movq %rax, %rdx
848056cf936SSimon Pilgrim; X64-BMI-NEXT:    andq %rcx, %rdx
849056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrq %rax
850056cf936SSimon Pilgrim; X64-BMI-NEXT:    andq %rcx, %rax
851056cf936SSimon Pilgrim; X64-BMI-NEXT:    leaq (%rax,%rdx,2), %rax
852056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnq %rdi, %rax, %rax
853056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
854e839d2a6SSimon Pilgrim  %not = xor i64 %a1, -1
8553e31e30aSSimon Pilgrim  %bitrev = tail call i64 @llvm.bitreverse.i64(i64 %not)
8563e31e30aSSimon Pilgrim  %and = and i64 %bitrev, %a0
8573e31e30aSSimon Pilgrim  ret i64 %and
8583e31e30aSSimon Pilgrim}
8593e31e30aSSimon Pilgrim
860e839d2a6SSimon Pilgrimdefine i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
861056cf936SSimon Pilgrim; X86-NOBMI-LABEL: andnot_bitreverse_i32:
862056cf936SSimon Pilgrim; X86-NOBMI:       # %bb.0:
863056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
864056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    bswapl %eax
865056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %ecx
866056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
867056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shll $4, %ecx
868056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl $4, %eax
869056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $252645135, %eax # imm = 0xF0F0F0F
870056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    orl %ecx, %eax
871056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %ecx
872056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $858993459, %ecx # imm = 0x33333333
873056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl $2, %eax
874056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
875056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    leal (%eax,%ecx,4), %eax
876056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    movl %eax, %ecx
877056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
878056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    shrl %eax
879056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
880056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    leal (%eax,%ecx,2), %eax
881056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    notl %eax
882056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
883056cf936SSimon Pilgrim; X86-NOBMI-NEXT:    retl
8843e31e30aSSimon Pilgrim;
885056cf936SSimon Pilgrim; X86-BMI-LABEL: andnot_bitreverse_i32:
886056cf936SSimon Pilgrim; X86-BMI:       # %bb.0:
887056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
888056cf936SSimon Pilgrim; X86-BMI-NEXT:    bswapl %eax
889056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %ecx
890056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $252645135, %ecx # imm = 0xF0F0F0F
891056cf936SSimon Pilgrim; X86-BMI-NEXT:    shll $4, %ecx
892056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl $4, %eax
893056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $252645135, %eax # imm = 0xF0F0F0F
894056cf936SSimon Pilgrim; X86-BMI-NEXT:    orl %ecx, %eax
895056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %ecx
896056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $858993459, %ecx # imm = 0x33333333
897056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl $2, %eax
898056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
899056cf936SSimon Pilgrim; X86-BMI-NEXT:    leal (%eax,%ecx,4), %eax
900056cf936SSimon Pilgrim; X86-BMI-NEXT:    movl %eax, %ecx
901056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
902056cf936SSimon Pilgrim; X86-BMI-NEXT:    shrl %eax
903056cf936SSimon Pilgrim; X86-BMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
904056cf936SSimon Pilgrim; X86-BMI-NEXT:    leal (%eax,%ecx,2), %eax
905056cf936SSimon Pilgrim; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
906056cf936SSimon Pilgrim; X86-BMI-NEXT:    retl
907056cf936SSimon Pilgrim;
908056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bitreverse_i32:
909056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
910056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $esi killed $esi def $rsi
911056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    bswapl %esi
912056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
913056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $252645135, %eax # imm = 0xF0F0F0F
914056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shll $4, %eax
915056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrl $4, %esi
916056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $252645135, %esi # imm = 0xF0F0F0F
917056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    orl %eax, %esi
918056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
919056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
920056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrl $2, %esi
921056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $858993459, %esi # imm = 0x33333333
922056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    leal (%rsi,%rax,4), %eax
923056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %eax, %ecx
924056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
925056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrl %eax
926056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
927056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    leal (%rax,%rcx,2), %eax
928056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
929056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
930056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
931056cf936SSimon Pilgrim;
932056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bitreverse_i32:
933056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
934056cf936SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $esi killed $esi def $rsi
935056cf936SSimon Pilgrim; X64-BMI-NEXT:    bswapl %esi
936056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %esi, %eax
937056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $252645135, %eax # imm = 0xF0F0F0F
938056cf936SSimon Pilgrim; X64-BMI-NEXT:    shll $4, %eax
939056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrl $4, %esi
940056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $252645135, %esi # imm = 0xF0F0F0F
941056cf936SSimon Pilgrim; X64-BMI-NEXT:    orl %eax, %esi
942056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %esi, %eax
943056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
944056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrl $2, %esi
945056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $858993459, %esi # imm = 0x33333333
946056cf936SSimon Pilgrim; X64-BMI-NEXT:    leal (%rsi,%rax,4), %eax
947056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %eax, %ecx
948056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
949056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrl %eax
950056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
951056cf936SSimon Pilgrim; X64-BMI-NEXT:    leal (%rax,%rcx,2), %eax
952056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %eax, %eax
953056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
954e839d2a6SSimon Pilgrim  %not = xor i32 %a1, -1
9553e31e30aSSimon Pilgrim  %bitrev = tail call i32 @llvm.bitreverse.i32(i32 %not)
9563e31e30aSSimon Pilgrim  %and = and i32 %bitrev, %a0
9573e31e30aSSimon Pilgrim  ret i32 %and
9583e31e30aSSimon Pilgrim}
9593e31e30aSSimon Pilgrim
960e839d2a6SSimon Pilgrimdefine i16 @andnot_bitreverse_i16(i16 %a0, i16 %a1) nounwind {
9613e31e30aSSimon Pilgrim; X86-LABEL: andnot_bitreverse_i16:
9623e31e30aSSimon Pilgrim; X86:       # %bb.0:
963056cf936SSimon Pilgrim; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
9643e31e30aSSimon Pilgrim; X86-NEXT:    rolw $8, %ax
965e839d2a6SSimon Pilgrim; X86-NEXT:    movl %eax, %ecx
966e839d2a6SSimon Pilgrim; X86-NEXT:    andl $3855, %ecx # imm = 0xF0F
967e839d2a6SSimon Pilgrim; X86-NEXT:    shll $4, %ecx
9683e31e30aSSimon Pilgrim; X86-NEXT:    shrl $4, %eax
9693e31e30aSSimon Pilgrim; X86-NEXT:    andl $3855, %eax # imm = 0xF0F
970e839d2a6SSimon Pilgrim; X86-NEXT:    orl %ecx, %eax
971e839d2a6SSimon Pilgrim; X86-NEXT:    movl %eax, %ecx
972e839d2a6SSimon Pilgrim; X86-NEXT:    andl $13107, %ecx # imm = 0x3333
9733e31e30aSSimon Pilgrim; X86-NEXT:    shrl $2, %eax
9743e31e30aSSimon Pilgrim; X86-NEXT:    andl $13107, %eax # imm = 0x3333
975e839d2a6SSimon Pilgrim; X86-NEXT:    leal (%eax,%ecx,4), %eax
976e839d2a6SSimon Pilgrim; X86-NEXT:    movl %eax, %ecx
977e839d2a6SSimon Pilgrim; X86-NEXT:    andl $21845, %ecx # imm = 0x5555
9783e31e30aSSimon Pilgrim; X86-NEXT:    shrl %eax
9793e31e30aSSimon Pilgrim; X86-NEXT:    andl $21845, %eax # imm = 0x5555
980e839d2a6SSimon Pilgrim; X86-NEXT:    leal (%eax,%ecx,2), %eax
981056cf936SSimon Pilgrim; X86-NEXT:    notl %eax
982e839d2a6SSimon Pilgrim; X86-NEXT:    andw {{[0-9]+}}(%esp), %ax
9833e31e30aSSimon Pilgrim; X86-NEXT:    # kill: def $ax killed $ax killed $eax
9843e31e30aSSimon Pilgrim; X86-NEXT:    retl
9853e31e30aSSimon Pilgrim;
986056cf936SSimon Pilgrim; X64-NOBMI-LABEL: andnot_bitreverse_i16:
987056cf936SSimon Pilgrim; X64-NOBMI:       # %bb.0:
988056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $esi killed $esi def $rsi
989056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    rolw $8, %si
990056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
991056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $3855, %eax # imm = 0xF0F
992056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shll $4, %eax
993056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrl $4, %esi
994056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $3855, %esi # imm = 0xF0F
995056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    orl %eax, %esi
996056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %esi, %eax
997056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $13107, %eax # imm = 0x3333
998056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrl $2, %esi
999056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $13107, %esi # imm = 0x3333
1000056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    leal (%rsi,%rax,4), %eax
1001056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    movl %eax, %ecx
1002056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $21845, %ecx # imm = 0x5555
1003056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    shrl %eax
1004056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl $21845, %eax # imm = 0x5555
1005056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    leal (%rax,%rcx,2), %eax
1006056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    notl %eax
1007056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    andl %edi, %eax
1008056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
1009056cf936SSimon Pilgrim; X64-NOBMI-NEXT:    retq
1010056cf936SSimon Pilgrim;
1011056cf936SSimon Pilgrim; X64-BMI-LABEL: andnot_bitreverse_i16:
1012056cf936SSimon Pilgrim; X64-BMI:       # %bb.0:
1013056cf936SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $esi killed $esi def $rsi
1014056cf936SSimon Pilgrim; X64-BMI-NEXT:    rolw $8, %si
1015056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %esi, %eax
1016056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $3855, %eax # imm = 0xF0F
1017056cf936SSimon Pilgrim; X64-BMI-NEXT:    shll $4, %eax
1018056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrl $4, %esi
1019056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $3855, %esi # imm = 0xF0F
1020056cf936SSimon Pilgrim; X64-BMI-NEXT:    orl %eax, %esi
1021056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %esi, %eax
1022056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $13107, %eax # imm = 0x3333
1023056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrl $2, %esi
1024056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $13107, %esi # imm = 0x3333
1025056cf936SSimon Pilgrim; X64-BMI-NEXT:    leal (%rsi,%rax,4), %eax
1026056cf936SSimon Pilgrim; X64-BMI-NEXT:    movl %eax, %ecx
1027056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $21845, %ecx # imm = 0x5555
1028056cf936SSimon Pilgrim; X64-BMI-NEXT:    shrl %eax
1029056cf936SSimon Pilgrim; X64-BMI-NEXT:    andl $21845, %eax # imm = 0x5555
1030056cf936SSimon Pilgrim; X64-BMI-NEXT:    leal (%rax,%rcx,2), %eax
1031056cf936SSimon Pilgrim; X64-BMI-NEXT:    andnl %edi, %eax, %eax
1032056cf936SSimon Pilgrim; X64-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
1033056cf936SSimon Pilgrim; X64-BMI-NEXT:    retq
1034e839d2a6SSimon Pilgrim  %not = xor i16 %a1, -1
10353e31e30aSSimon Pilgrim  %bitrev = tail call i16 @llvm.bitreverse.i16(i16 %not)
10363e31e30aSSimon Pilgrim  %and = and i16 %bitrev, %a0
10373e31e30aSSimon Pilgrim  ret i16 %and
10383e31e30aSSimon Pilgrim}
10393e31e30aSSimon Pilgrim
1040e839d2a6SSimon Pilgrimdefine i8 @andnot_bitreverse_i8(i8 %a0, i8 %a1) nounwind {
10413e31e30aSSimon Pilgrim; X86-LABEL: andnot_bitreverse_i8:
10423e31e30aSSimon Pilgrim; X86:       # %bb.0:
1043e839d2a6SSimon Pilgrim; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
10443e31e30aSSimon Pilgrim; X86-NEXT:    rolb $4, %al
1045e839d2a6SSimon Pilgrim; X86-NEXT:    movl %eax, %ecx
1046e839d2a6SSimon Pilgrim; X86-NEXT:    andb $51, %cl
1047e839d2a6SSimon Pilgrim; X86-NEXT:    shlb $2, %cl
10483e31e30aSSimon Pilgrim; X86-NEXT:    shrb $2, %al
10493e31e30aSSimon Pilgrim; X86-NEXT:    andb $51, %al
1050e839d2a6SSimon Pilgrim; X86-NEXT:    orb %cl, %al
1051e839d2a6SSimon Pilgrim; X86-NEXT:    movl %eax, %ecx
1052e839d2a6SSimon Pilgrim; X86-NEXT:    andb $85, %cl
1053e839d2a6SSimon Pilgrim; X86-NEXT:    addb %cl, %cl
10543e31e30aSSimon Pilgrim; X86-NEXT:    shrb %al
10553e31e30aSSimon Pilgrim; X86-NEXT:    andb $85, %al
1056e839d2a6SSimon Pilgrim; X86-NEXT:    orb %cl, %al
1057056cf936SSimon Pilgrim; X86-NEXT:    notb %al
1058e839d2a6SSimon Pilgrim; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
10593e31e30aSSimon Pilgrim; X86-NEXT:    retl
10603e31e30aSSimon Pilgrim;
10613e31e30aSSimon Pilgrim; X64-LABEL: andnot_bitreverse_i8:
10623e31e30aSSimon Pilgrim; X64:       # %bb.0:
1063e839d2a6SSimon Pilgrim; X64-NEXT:    rolb $4, %sil
1064e839d2a6SSimon Pilgrim; X64-NEXT:    movl %esi, %eax
10653e31e30aSSimon Pilgrim; X64-NEXT:    andb $51, %al
1066e839d2a6SSimon Pilgrim; X64-NEXT:    shlb $2, %al
1067e839d2a6SSimon Pilgrim; X64-NEXT:    shrb $2, %sil
1068e839d2a6SSimon Pilgrim; X64-NEXT:    andb $51, %sil
1069e839d2a6SSimon Pilgrim; X64-NEXT:    orb %sil, %al
10703e31e30aSSimon Pilgrim; X64-NEXT:    movl %eax, %ecx
10713e31e30aSSimon Pilgrim; X64-NEXT:    andb $85, %cl
10723e31e30aSSimon Pilgrim; X64-NEXT:    addb %cl, %cl
10733e31e30aSSimon Pilgrim; X64-NEXT:    shrb %al
10743e31e30aSSimon Pilgrim; X64-NEXT:    andb $85, %al
10753e31e30aSSimon Pilgrim; X64-NEXT:    orb %cl, %al
1076056cf936SSimon Pilgrim; X64-NEXT:    notb %al
10773e31e30aSSimon Pilgrim; X64-NEXT:    andb %dil, %al
10783e31e30aSSimon Pilgrim; X64-NEXT:    retq
1079e839d2a6SSimon Pilgrim  %not = xor i8 %a1, -1
10803e31e30aSSimon Pilgrim  %bitrev = tail call i8 @llvm.bitreverse.i8(i8 %not)
10813e31e30aSSimon Pilgrim  %and = and i8 %bitrev, %a0
10823e31e30aSSimon Pilgrim  ret i8 %and
10833e31e30aSSimon Pilgrim}
1084