1025952b0SSimon Pilgrim; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2025952b0SSimon Pilgrim; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86 3025952b0SSimon Pilgrim; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-bmi | FileCheck %s --check-prefixes=X64,X64-NOBMI 4025952b0SSimon Pilgrim; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=X64,X64-BMI 5025952b0SSimon Pilgrim 6025952b0SSimon Pilgrim; PR46472 7025952b0SSimon Pilgrim; bitselect(a,b,m) == or(and(a,not(m)),and(b,m)) 8025952b0SSimon Pilgrim; bitselect(a,b,m) == xor(and(xor(a,b),m),a) 9025952b0SSimon Pilgrim 10025952b0SSimon Pilgrimdefine i8 @bitselect_i8(i8 %a, i8 %b, i8 %m) nounwind { 11025952b0SSimon Pilgrim; X86-LABEL: bitselect_i8: 12025952b0SSimon Pilgrim; X86: # %bb.0: 13025952b0SSimon Pilgrim; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 14025952b0SSimon Pilgrim; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 15025952b0SSimon Pilgrim; X86-NEXT: xorb %cl, %al 16025952b0SSimon Pilgrim; X86-NEXT: andb {{[0-9]+}}(%esp), %al 17025952b0SSimon Pilgrim; X86-NEXT: xorb %cl, %al 18025952b0SSimon Pilgrim; X86-NEXT: retl 19025952b0SSimon Pilgrim; 20025952b0SSimon Pilgrim; X64-LABEL: bitselect_i8: 21025952b0SSimon Pilgrim; X64: # %bb.0: 22025952b0SSimon Pilgrim; X64-NEXT: andl %edx, %esi 23025952b0SSimon Pilgrim; X64-NEXT: movl %edx, %eax 24025952b0SSimon Pilgrim; X64-NEXT: notb %al 25025952b0SSimon Pilgrim; X64-NEXT: andb %dil, %al 26025952b0SSimon Pilgrim; X64-NEXT: orb %sil, %al 27025952b0SSimon Pilgrim; X64-NEXT: retq 28025952b0SSimon Pilgrim %not = xor i8 %m, -1 29025952b0SSimon Pilgrim %ma = and i8 %a, %not 30025952b0SSimon Pilgrim %mb = and i8 %b, %m 31025952b0SSimon Pilgrim %or = or i8 %ma, %mb 32025952b0SSimon Pilgrim ret i8 %or 33025952b0SSimon Pilgrim} 34025952b0SSimon Pilgrim 35025952b0SSimon Pilgrimdefine i16 @bitselect_i16(i16 %a, i16 %b, i16 %m) nounwind { 36025952b0SSimon Pilgrim; X86-LABEL: bitselect_i16: 37025952b0SSimon Pilgrim; X86: # %bb.0: 38025952b0SSimon Pilgrim; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 39025952b0SSimon Pilgrim; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 40025952b0SSimon Pilgrim; X86-NEXT: xorw %ax, %cx 41025952b0SSimon Pilgrim; X86-NEXT: andw {{[0-9]+}}(%esp), %cx 42025952b0SSimon Pilgrim; X86-NEXT: xorl %ecx, %eax 43025952b0SSimon Pilgrim; X86-NEXT: # kill: def $ax killed $ax killed $eax 44025952b0SSimon Pilgrim; X86-NEXT: retl 45025952b0SSimon Pilgrim; 46025952b0SSimon Pilgrim; X64-NOBMI-LABEL: bitselect_i16: 47025952b0SSimon Pilgrim; X64-NOBMI: # %bb.0: 48025952b0SSimon Pilgrim; X64-NOBMI-NEXT: movl %edx, %eax 49025952b0SSimon Pilgrim; X64-NOBMI-NEXT: andl %edx, %esi 50025952b0SSimon Pilgrim; X64-NOBMI-NEXT: notl %eax 51025952b0SSimon Pilgrim; X64-NOBMI-NEXT: andl %edi, %eax 52025952b0SSimon Pilgrim; X64-NOBMI-NEXT: orl %esi, %eax 53025952b0SSimon Pilgrim; X64-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax 54025952b0SSimon Pilgrim; X64-NOBMI-NEXT: retq 55025952b0SSimon Pilgrim; 56025952b0SSimon Pilgrim; X64-BMI-LABEL: bitselect_i16: 57025952b0SSimon Pilgrim; X64-BMI: # %bb.0: 58025952b0SSimon Pilgrim; X64-BMI-NEXT: andnl %edi, %edx, %eax 59025952b0SSimon Pilgrim; X64-BMI-NEXT: andl %edx, %esi 60025952b0SSimon Pilgrim; X64-BMI-NEXT: orl %esi, %eax 61025952b0SSimon Pilgrim; X64-BMI-NEXT: # kill: def $ax killed $ax killed $eax 62025952b0SSimon Pilgrim; X64-BMI-NEXT: retq 63025952b0SSimon Pilgrim %not = xor i16 %m, -1 64025952b0SSimon Pilgrim %ma = and i16 %a, %not 65025952b0SSimon Pilgrim %mb = and i16 %b, %m 66025952b0SSimon Pilgrim %or = or i16 %ma, %mb 67025952b0SSimon Pilgrim ret i16 %or 68025952b0SSimon Pilgrim} 69025952b0SSimon Pilgrim 70025952b0SSimon Pilgrimdefine i32 @bitselect_i32(i32 %a, i32 %b, i32 %m) nounwind { 71025952b0SSimon Pilgrim; X86-LABEL: bitselect_i32: 72025952b0SSimon Pilgrim; X86: # %bb.0: 73025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 74025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 75025952b0SSimon Pilgrim; X86-NEXT: xorl %ecx, %eax 76025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 77025952b0SSimon Pilgrim; X86-NEXT: xorl %ecx, %eax 78025952b0SSimon Pilgrim; X86-NEXT: retl 79025952b0SSimon Pilgrim; 80025952b0SSimon Pilgrim; X64-NOBMI-LABEL: bitselect_i32: 81025952b0SSimon Pilgrim; X64-NOBMI: # %bb.0: 82025952b0SSimon Pilgrim; X64-NOBMI-NEXT: movl %esi, %eax 83025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorl %edi, %eax 84025952b0SSimon Pilgrim; X64-NOBMI-NEXT: andl %edx, %eax 85025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorl %edi, %eax 86025952b0SSimon Pilgrim; X64-NOBMI-NEXT: retq 87025952b0SSimon Pilgrim; 88025952b0SSimon Pilgrim; X64-BMI-LABEL: bitselect_i32: 89025952b0SSimon Pilgrim; X64-BMI: # %bb.0: 90025952b0SSimon Pilgrim; X64-BMI-NEXT: andnl %edi, %edx, %eax 91025952b0SSimon Pilgrim; X64-BMI-NEXT: andl %edx, %esi 92025952b0SSimon Pilgrim; X64-BMI-NEXT: orl %esi, %eax 93025952b0SSimon Pilgrim; X64-BMI-NEXT: retq 94025952b0SSimon Pilgrim %not = xor i32 %m, -1 95025952b0SSimon Pilgrim %ma = and i32 %a, %not 96025952b0SSimon Pilgrim %mb = and i32 %b, %m 97025952b0SSimon Pilgrim %or = or i32 %ma, %mb 98025952b0SSimon Pilgrim ret i32 %or 99025952b0SSimon Pilgrim} 100025952b0SSimon Pilgrim 101025952b0SSimon Pilgrimdefine i64 @bitselect_i64(i64 %a, i64 %b, i64 %m) nounwind { 102025952b0SSimon Pilgrim; X86-LABEL: bitselect_i64: 103025952b0SSimon Pilgrim; X86: # %bb.0: 104025952b0SSimon Pilgrim; X86-NEXT: pushl %esi 105025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 106025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 107025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 108025952b0SSimon Pilgrim; X86-NEXT: xorl %ecx, %eax 109025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 110025952b0SSimon Pilgrim; X86-NEXT: xorl %ecx, %eax 111025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 112025952b0SSimon Pilgrim; X86-NEXT: xorl %esi, %edx 113025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %edx 114025952b0SSimon Pilgrim; X86-NEXT: xorl %esi, %edx 115025952b0SSimon Pilgrim; X86-NEXT: popl %esi 116025952b0SSimon Pilgrim; X86-NEXT: retl 117025952b0SSimon Pilgrim; 118025952b0SSimon Pilgrim; X64-NOBMI-LABEL: bitselect_i64: 119025952b0SSimon Pilgrim; X64-NOBMI: # %bb.0: 120025952b0SSimon Pilgrim; X64-NOBMI-NEXT: movq %rsi, %rax 121025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorq %rdi, %rax 122025952b0SSimon Pilgrim; X64-NOBMI-NEXT: andq %rdx, %rax 123025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorq %rdi, %rax 124025952b0SSimon Pilgrim; X64-NOBMI-NEXT: retq 125025952b0SSimon Pilgrim; 126025952b0SSimon Pilgrim; X64-BMI-LABEL: bitselect_i64: 127025952b0SSimon Pilgrim; X64-BMI: # %bb.0: 128025952b0SSimon Pilgrim; X64-BMI-NEXT: andnq %rdi, %rdx, %rax 129025952b0SSimon Pilgrim; X64-BMI-NEXT: andq %rdx, %rsi 130025952b0SSimon Pilgrim; X64-BMI-NEXT: orq %rsi, %rax 131025952b0SSimon Pilgrim; X64-BMI-NEXT: retq 132025952b0SSimon Pilgrim %not = xor i64 %m, -1 133025952b0SSimon Pilgrim %ma = and i64 %a, %not 134025952b0SSimon Pilgrim %mb = and i64 %b, %m 135025952b0SSimon Pilgrim %or = or i64 %ma, %mb 136025952b0SSimon Pilgrim ret i64 %or 137025952b0SSimon Pilgrim} 138025952b0SSimon Pilgrim 139025952b0SSimon Pilgrimdefine i128 @bitselect_i128(i128 %a, i128 %b, i128 %m) nounwind { 140025952b0SSimon Pilgrim; X86-LABEL: bitselect_i128: 141025952b0SSimon Pilgrim; X86: # %bb.0: 142025952b0SSimon Pilgrim; X86-NEXT: pushl %ebx 143025952b0SSimon Pilgrim; X86-NEXT: pushl %edi 144025952b0SSimon Pilgrim; X86-NEXT: pushl %esi 145025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 146025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 147025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 148025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 149025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 150025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 151025952b0SSimon Pilgrim; X86-NEXT: xorl %edi, %ecx 152025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %ecx 153025952b0SSimon Pilgrim; X86-NEXT: xorl %edi, %ecx 154025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 155025952b0SSimon Pilgrim; X86-NEXT: xorl %ebx, %edi 156025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %edi 157025952b0SSimon Pilgrim; X86-NEXT: xorl %ebx, %edi 158025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 159025952b0SSimon Pilgrim; X86-NEXT: xorl %esi, %ebx 160025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %ebx 161025952b0SSimon Pilgrim; X86-NEXT: xorl %esi, %ebx 162025952b0SSimon Pilgrim; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 163025952b0SSimon Pilgrim; X86-NEXT: xorl %edx, %esi 164025952b0SSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %esi 165025952b0SSimon Pilgrim; X86-NEXT: xorl %edx, %esi 166025952b0SSimon Pilgrim; X86-NEXT: movl %esi, 12(%eax) 167025952b0SSimon Pilgrim; X86-NEXT: movl %ebx, 8(%eax) 168025952b0SSimon Pilgrim; X86-NEXT: movl %edi, 4(%eax) 169025952b0SSimon Pilgrim; X86-NEXT: movl %ecx, (%eax) 170025952b0SSimon Pilgrim; X86-NEXT: popl %esi 171025952b0SSimon Pilgrim; X86-NEXT: popl %edi 172025952b0SSimon Pilgrim; X86-NEXT: popl %ebx 173025952b0SSimon Pilgrim; X86-NEXT: retl $4 174025952b0SSimon Pilgrim; 175025952b0SSimon Pilgrim; X64-NOBMI-LABEL: bitselect_i128: 176025952b0SSimon Pilgrim; X64-NOBMI: # %bb.0: 177025952b0SSimon Pilgrim; X64-NOBMI-NEXT: movq %rdx, %rax 178025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorq %rdi, %rax 179025952b0SSimon Pilgrim; X64-NOBMI-NEXT: andq %r8, %rax 180025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorq %rdi, %rax 181025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorq %rsi, %rcx 182025952b0SSimon Pilgrim; X64-NOBMI-NEXT: andq %r9, %rcx 183025952b0SSimon Pilgrim; X64-NOBMI-NEXT: xorq %rsi, %rcx 184025952b0SSimon Pilgrim; X64-NOBMI-NEXT: movq %rcx, %rdx 185025952b0SSimon Pilgrim; X64-NOBMI-NEXT: retq 186025952b0SSimon Pilgrim; 187025952b0SSimon Pilgrim; X64-BMI-LABEL: bitselect_i128: 188025952b0SSimon Pilgrim; X64-BMI: # %bb.0: 189025952b0SSimon Pilgrim; X64-BMI-NEXT: andnq %rsi, %r9, %rsi 190025952b0SSimon Pilgrim; X64-BMI-NEXT: andnq %rdi, %r8, %rax 191025952b0SSimon Pilgrim; X64-BMI-NEXT: andq %r9, %rcx 192025952b0SSimon Pilgrim; X64-BMI-NEXT: orq %rcx, %rsi 193025952b0SSimon Pilgrim; X64-BMI-NEXT: andq %r8, %rdx 194025952b0SSimon Pilgrim; X64-BMI-NEXT: orq %rdx, %rax 195025952b0SSimon Pilgrim; X64-BMI-NEXT: movq %rsi, %rdx 196025952b0SSimon Pilgrim; X64-BMI-NEXT: retq 197025952b0SSimon Pilgrim %not = xor i128 %m, -1 198025952b0SSimon Pilgrim %ma = and i128 %a, %not 199025952b0SSimon Pilgrim %mb = and i128 %b, %m 200025952b0SSimon Pilgrim %or = or i128 %ma, %mb 201025952b0SSimon Pilgrim ret i128 %or 202025952b0SSimon Pilgrim} 203*96aa76aaSSimon Pilgrim 204*96aa76aaSSimon Pilgrim; 205*96aa76aaSSimon Pilgrim; Bitselect between constants 206*96aa76aaSSimon Pilgrim; 207*96aa76aaSSimon Pilgrim 208*96aa76aaSSimon Pilgrim; bitselect(52, -6553, m) 209*96aa76aaSSimon Pilgrim; TODO: Non-BMI canonicalization is actually better. 210*96aa76aaSSimon Pilgrimdefine i32 @bitselect_constants_i32(i32 %m) nounwind { 211*96aa76aaSSimon Pilgrim; X86-LABEL: bitselect_constants_i32: 212*96aa76aaSSimon Pilgrim; X86: # %bb.0: 213*96aa76aaSSimon Pilgrim; X86-NEXT: movl $-6573, %eax # imm = 0xE653 214*96aa76aaSSimon Pilgrim; X86-NEXT: andl {{[0-9]+}}(%esp), %eax 215*96aa76aaSSimon Pilgrim; X86-NEXT: xorl $52, %eax 216*96aa76aaSSimon Pilgrim; X86-NEXT: retl 217*96aa76aaSSimon Pilgrim; 218*96aa76aaSSimon Pilgrim; X64-NOBMI-LABEL: bitselect_constants_i32: 219*96aa76aaSSimon Pilgrim; X64-NOBMI: # %bb.0: 220*96aa76aaSSimon Pilgrim; X64-NOBMI-NEXT: movl %edi, %eax 221*96aa76aaSSimon Pilgrim; X64-NOBMI-NEXT: andl $-6573, %eax # imm = 0xE653 222*96aa76aaSSimon Pilgrim; X64-NOBMI-NEXT: xorl $52, %eax 223*96aa76aaSSimon Pilgrim; X64-NOBMI-NEXT: retq 224*96aa76aaSSimon Pilgrim; 225*96aa76aaSSimon Pilgrim; X64-BMI-LABEL: bitselect_constants_i32: 226*96aa76aaSSimon Pilgrim; X64-BMI: # %bb.0: 227*96aa76aaSSimon Pilgrim; X64-BMI-NEXT: movl %edi, %eax 228*96aa76aaSSimon Pilgrim; X64-BMI-NEXT: notl %eax 229*96aa76aaSSimon Pilgrim; X64-BMI-NEXT: andl $52, %eax 230*96aa76aaSSimon Pilgrim; X64-BMI-NEXT: andl $-6553, %edi # imm = 0xE667 231*96aa76aaSSimon Pilgrim; X64-BMI-NEXT: orl %edi, %eax 232*96aa76aaSSimon Pilgrim; X64-BMI-NEXT: retq 233*96aa76aaSSimon Pilgrim %not = xor i32 %m, -1 234*96aa76aaSSimon Pilgrim %ma = and i32 52, %not 235*96aa76aaSSimon Pilgrim %mb = and i32 -6553, %m 236*96aa76aaSSimon Pilgrim %or = or i32 %ma, %mb 237*96aa76aaSSimon Pilgrim ret i32 %or 238*96aa76aaSSimon Pilgrim} 239