[AArch64,ELF] Restrict MOVZ/MOVK to non-PIC large code model (#70178)
[llvm-project.git] / llvm / test / CodeGen / X86 / bitselect.ll
blob2922113b14ea90d662e6806dba77d87abb6d5018
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
6 ; PR46472
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:
12 ; X86:       # %bb.0:
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
18 ; X86-NEXT:    retl
20 ; X64-LABEL: bitselect_i8:
21 ; X64:       # %bb.0:
22 ; X64-NEXT:    andl %edx, %esi
23 ; X64-NEXT:    movl %edx, %eax
24 ; X64-NEXT:    notb %al
25 ; X64-NEXT:    andb %dil, %al
26 ; X64-NEXT:    orb %sil, %al
27 ; X64-NEXT:    retq
28   %not = xor i8 %m, -1
29   %ma = and i8 %a, %not
30   %mb = and i8 %b, %m
31   %or = or i8 %ma, %mb
32   ret i8 %or
35 define i16 @bitselect_i16(i16 %a, i16 %b, i16 %m) nounwind {
36 ; X86-LABEL: bitselect_i16:
37 ; X86:       # %bb.0:
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
44 ; X86-NEXT:    retl
46 ; X64-NOBMI-LABEL: bitselect_i16:
47 ; X64-NOBMI:       # %bb.0:
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:
57 ; X64-BMI:       # %bb.0:
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
62 ; X64-BMI-NEXT:    retq
63   %not = xor i16 %m, -1
64   %ma = and i16 %a, %not
65   %mb = and i16 %b, %m
66   %or = or i16 %ma, %mb
67   ret i16 %or
70 define i32 @bitselect_i32(i32 %a, i32 %b, i32 %m) nounwind {
71 ; X86-LABEL: bitselect_i32:
72 ; X86:       # %bb.0:
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
78 ; X86-NEXT:    retl
80 ; X64-NOBMI-LABEL: bitselect_i32:
81 ; X64-NOBMI:       # %bb.0:
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:
89 ; X64-BMI:       # %bb.0:
90 ; X64-BMI-NEXT:    andnl %edi, %edx, %eax
91 ; X64-BMI-NEXT:    andl %edx, %esi
92 ; X64-BMI-NEXT:    orl %esi, %eax
93 ; X64-BMI-NEXT:    retq
94   %not = xor i32 %m, -1
95   %ma = and i32 %a, %not
96   %mb = and i32 %b, %m
97   %or = or i32 %ma, %mb
98   ret i32 %or
101 define i64 @bitselect_i64(i64 %a, i64 %b, i64 %m) nounwind {
102 ; X86-LABEL: bitselect_i64:
103 ; X86:       # %bb.0:
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
116 ; X86-NEXT:    retl
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:
127 ; X64-BMI:       # %bb.0:
128 ; X64-BMI-NEXT:    andnq %rdi, %rdx, %rax
129 ; X64-BMI-NEXT:    andq %rdx, %rsi
130 ; X64-BMI-NEXT:    orq %rsi, %rax
131 ; X64-BMI-NEXT:    retq
132   %not = xor i64 %m, -1
133   %ma = and i64 %a, %not
134   %mb = and i64 %b, %m
135   %or = or i64 %ma, %mb
136   ret i64 %or
139 define i128 @bitselect_i128(i128 %a, i128 %b, i128 %m) nounwind {
140 ; X86-LABEL: bitselect_i128:
141 ; X86:       # %bb.0:
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
173 ; X86-NEXT:    retl $4
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:
188 ; X64-BMI:       # %bb.0:
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
196 ; X64-BMI-NEXT:    retq
197   %not = xor i128 %m, -1
198   %ma = and i128 %a, %not
199   %mb = and i128 %b, %m
200   %or = or i128 %ma, %mb
201   ret i128 %or
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:
212 ; X86:       # %bb.0:
213 ; X86-NEXT:    movl $-6573, %eax # imm = 0xE653
214 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
215 ; X86-NEXT:    xorl $52, %eax
216 ; X86-NEXT:    retl
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:
226 ; X64-BMI:       # %bb.0:
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
232 ; X64-BMI-NEXT:    retq
233   %not = xor i32 %m, -1
234   %ma = and i32 52, %not
235   %mb = and i32 -6553, %m
236   %or = or i32 %ma, %mb
237   ret i32 %or