1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-bmi | FileCheck %s --check-prefixes=X64,X64-NOBMI
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=X64,X64-BMI
7 ; bitselect(a,b,m) == or(and(a,not(m)),and(b,m))
8 ; bitselect(a,b,m) == xor(and(xor(a,b),m),a)
10 define i8 @bitselect_i8(i8 %a, i8 %b, i8 %m) nounwind {
11 ; X86-LABEL: bitselect_i8:
13 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
14 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
15 ; X86-NEXT: xorb %cl, %al
16 ; X86-NEXT: andb {{[0-9]+}}(%esp), %al
17 ; X86-NEXT: xorb %cl, %al
20 ; X64-LABEL: bitselect_i8:
22 ; X64-NEXT: andl %edx, %esi
23 ; X64-NEXT: movl %edx, %eax
25 ; X64-NEXT: andb %dil, %al
26 ; X64-NEXT: orb %sil, %al
35 define i16 @bitselect_i16(i16 %a, i16 %b, i16 %m) nounwind {
36 ; X86-LABEL: bitselect_i16:
38 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
39 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
40 ; X86-NEXT: xorw %ax, %cx
41 ; X86-NEXT: andw {{[0-9]+}}(%esp), %cx
42 ; X86-NEXT: xorl %ecx, %eax
43 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
46 ; X64-NOBMI-LABEL: bitselect_i16:
48 ; X64-NOBMI-NEXT: movl %edx, %eax
49 ; X64-NOBMI-NEXT: andl %edx, %esi
50 ; X64-NOBMI-NEXT: notl %eax
51 ; X64-NOBMI-NEXT: andl %edi, %eax
52 ; X64-NOBMI-NEXT: orl %esi, %eax
53 ; X64-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax
54 ; X64-NOBMI-NEXT: retq
56 ; X64-BMI-LABEL: bitselect_i16:
58 ; X64-BMI-NEXT: andnl %edi, %edx, %eax
59 ; X64-BMI-NEXT: andl %edx, %esi
60 ; X64-BMI-NEXT: orl %esi, %eax
61 ; X64-BMI-NEXT: # kill: def $ax killed $ax killed $eax
64 %ma = and i16 %a, %not
70 define i32 @bitselect_i32(i32 %a, i32 %b, i32 %m) nounwind {
71 ; X86-LABEL: bitselect_i32:
73 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
74 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
75 ; X86-NEXT: xorl %ecx, %eax
76 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
77 ; X86-NEXT: xorl %ecx, %eax
80 ; X64-NOBMI-LABEL: bitselect_i32:
82 ; X64-NOBMI-NEXT: movl %esi, %eax
83 ; X64-NOBMI-NEXT: xorl %edi, %eax
84 ; X64-NOBMI-NEXT: andl %edx, %eax
85 ; X64-NOBMI-NEXT: xorl %edi, %eax
86 ; X64-NOBMI-NEXT: retq
88 ; X64-BMI-LABEL: bitselect_i32:
90 ; X64-BMI-NEXT: andnl %edi, %edx, %eax
91 ; X64-BMI-NEXT: andl %edx, %esi
92 ; X64-BMI-NEXT: orl %esi, %eax
95 %ma = and i32 %a, %not
101 define i64 @bitselect_i64(i64 %a, i64 %b, i64 %m) nounwind {
102 ; X86-LABEL: bitselect_i64:
104 ; X86-NEXT: pushl %esi
105 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
106 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
107 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
108 ; X86-NEXT: xorl %ecx, %eax
109 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
110 ; X86-NEXT: xorl %ecx, %eax
111 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
112 ; X86-NEXT: xorl %esi, %edx
113 ; X86-NEXT: andl {{[0-9]+}}(%esp), %edx
114 ; X86-NEXT: xorl %esi, %edx
115 ; X86-NEXT: popl %esi
118 ; X64-NOBMI-LABEL: bitselect_i64:
119 ; X64-NOBMI: # %bb.0:
120 ; X64-NOBMI-NEXT: movq %rsi, %rax
121 ; X64-NOBMI-NEXT: xorq %rdi, %rax
122 ; X64-NOBMI-NEXT: andq %rdx, %rax
123 ; X64-NOBMI-NEXT: xorq %rdi, %rax
124 ; X64-NOBMI-NEXT: retq
126 ; X64-BMI-LABEL: bitselect_i64:
128 ; X64-BMI-NEXT: andnq %rdi, %rdx, %rax
129 ; X64-BMI-NEXT: andq %rdx, %rsi
130 ; X64-BMI-NEXT: orq %rsi, %rax
132 %not = xor i64 %m, -1
133 %ma = and i64 %a, %not
135 %or = or i64 %ma, %mb
139 define i128 @bitselect_i128(i128 %a, i128 %b, i128 %m) nounwind {
140 ; X86-LABEL: bitselect_i128:
142 ; X86-NEXT: pushl %ebx
143 ; X86-NEXT: pushl %edi
144 ; X86-NEXT: pushl %esi
145 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
146 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
147 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
148 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
149 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
150 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
151 ; X86-NEXT: xorl %edi, %ecx
152 ; X86-NEXT: andl {{[0-9]+}}(%esp), %ecx
153 ; X86-NEXT: xorl %edi, %ecx
154 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
155 ; X86-NEXT: xorl %ebx, %edi
156 ; X86-NEXT: andl {{[0-9]+}}(%esp), %edi
157 ; X86-NEXT: xorl %ebx, %edi
158 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
159 ; X86-NEXT: xorl %esi, %ebx
160 ; X86-NEXT: andl {{[0-9]+}}(%esp), %ebx
161 ; X86-NEXT: xorl %esi, %ebx
162 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
163 ; X86-NEXT: xorl %edx, %esi
164 ; X86-NEXT: andl {{[0-9]+}}(%esp), %esi
165 ; X86-NEXT: xorl %edx, %esi
166 ; X86-NEXT: movl %esi, 12(%eax)
167 ; X86-NEXT: movl %ebx, 8(%eax)
168 ; X86-NEXT: movl %edi, 4(%eax)
169 ; X86-NEXT: movl %ecx, (%eax)
170 ; X86-NEXT: popl %esi
171 ; X86-NEXT: popl %edi
172 ; X86-NEXT: popl %ebx
175 ; X64-NOBMI-LABEL: bitselect_i128:
176 ; X64-NOBMI: # %bb.0:
177 ; X64-NOBMI-NEXT: movq %rdx, %rax
178 ; X64-NOBMI-NEXT: xorq %rdi, %rax
179 ; X64-NOBMI-NEXT: andq %r8, %rax
180 ; X64-NOBMI-NEXT: xorq %rdi, %rax
181 ; X64-NOBMI-NEXT: xorq %rsi, %rcx
182 ; X64-NOBMI-NEXT: andq %r9, %rcx
183 ; X64-NOBMI-NEXT: xorq %rsi, %rcx
184 ; X64-NOBMI-NEXT: movq %rcx, %rdx
185 ; X64-NOBMI-NEXT: retq
187 ; X64-BMI-LABEL: bitselect_i128:
189 ; X64-BMI-NEXT: andnq %rsi, %r9, %rsi
190 ; X64-BMI-NEXT: andnq %rdi, %r8, %rax
191 ; X64-BMI-NEXT: andq %r9, %rcx
192 ; X64-BMI-NEXT: orq %rcx, %rsi
193 ; X64-BMI-NEXT: andq %r8, %rdx
194 ; X64-BMI-NEXT: orq %rdx, %rax
195 ; X64-BMI-NEXT: movq %rsi, %rdx
197 %not = xor i128 %m, -1
198 %ma = and i128 %a, %not
199 %mb = and i128 %b, %m
200 %or = or i128 %ma, %mb
205 ; Bitselect between constants
208 ; bitselect(52, -6553, m)
209 ; TODO: Non-BMI canonicalization is actually better.
210 define i32 @bitselect_constants_i32(i32 %m) nounwind {
211 ; X86-LABEL: bitselect_constants_i32:
213 ; X86-NEXT: movl $-6573, %eax # imm = 0xE653
214 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
215 ; X86-NEXT: xorl $52, %eax
218 ; X64-NOBMI-LABEL: bitselect_constants_i32:
219 ; X64-NOBMI: # %bb.0:
220 ; X64-NOBMI-NEXT: movl %edi, %eax
221 ; X64-NOBMI-NEXT: andl $-6573, %eax # imm = 0xE653
222 ; X64-NOBMI-NEXT: xorl $52, %eax
223 ; X64-NOBMI-NEXT: retq
225 ; X64-BMI-LABEL: bitselect_constants_i32:
227 ; X64-BMI-NEXT: movl %edi, %eax
228 ; X64-BMI-NEXT: notl %eax
229 ; X64-BMI-NEXT: andl $52, %eax
230 ; X64-BMI-NEXT: andl $-6553, %edi # imm = 0xE667
231 ; X64-BMI-NEXT: orl %edi, %eax
233 %not = xor i32 %m, -1
234 %ma = and i32 52, %not
235 %mb = and i32 -6553, %m
236 %or = or i32 %ma, %mb