248 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-bmi | FileCheck %s --check-prefixes=X64-NOBMI4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=X64-BMI5 6; PR464727; bitselect(a,b,m) == or(and(a,not(m)),and(b,m))8; bitselect(a,b,m) == xor(and(xor(a,b),m),a)9 10define 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), %ecx14; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax15; X86-NEXT: xorb %cl, %al16; X86-NEXT: andb {{[0-9]+}}(%esp), %al17; X86-NEXT: xorb %cl, %al18; X86-NEXT: retl19;20; X64-NOBMI-LABEL: bitselect_i8:21; X64-NOBMI: # %bb.0:22; X64-NOBMI-NEXT: movl %esi, %eax23; X64-NOBMI-NEXT: xorl %edi, %eax24; X64-NOBMI-NEXT: andl %edx, %eax25; X64-NOBMI-NEXT: xorl %edi, %eax26; X64-NOBMI-NEXT: # kill: def $al killed $al killed $eax27; X64-NOBMI-NEXT: retq28;29; X64-BMI-LABEL: bitselect_i8:30; X64-BMI: # %bb.0:31; X64-BMI-NEXT: andnl %edi, %edx, %eax32; X64-BMI-NEXT: andl %edx, %esi33; X64-BMI-NEXT: orl %esi, %eax34; X64-BMI-NEXT: # kill: def $al killed $al killed $eax35; X64-BMI-NEXT: retq36 %not = xor i8 %m, -137 %ma = and i8 %a, %not38 %mb = and i8 %b, %m39 %or = or i8 %ma, %mb40 ret i8 %or41}42 43define i16 @bitselect_i16(i16 %a, i16 %b, i16 %m) nounwind {44; X86-LABEL: bitselect_i16:45; X86: # %bb.0:46; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx47; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax48; X86-NEXT: xorw %cx, %ax49; X86-NEXT: andw {{[0-9]+}}(%esp), %ax50; X86-NEXT: xorl %ecx, %eax51; X86-NEXT: # kill: def $ax killed $ax killed $eax52; X86-NEXT: retl53;54; X64-NOBMI-LABEL: bitselect_i16:55; X64-NOBMI: # %bb.0:56; X64-NOBMI-NEXT: movl %esi, %eax57; X64-NOBMI-NEXT: xorl %edi, %eax58; X64-NOBMI-NEXT: andl %edx, %eax59; X64-NOBMI-NEXT: xorl %edi, %eax60; X64-NOBMI-NEXT: # kill: def $ax killed $ax killed $eax61; X64-NOBMI-NEXT: retq62;63; X64-BMI-LABEL: bitselect_i16:64; X64-BMI: # %bb.0:65; X64-BMI-NEXT: andnl %edi, %edx, %eax66; X64-BMI-NEXT: andl %edx, %esi67; X64-BMI-NEXT: orl %esi, %eax68; X64-BMI-NEXT: # kill: def $ax killed $ax killed $eax69; X64-BMI-NEXT: retq70 %not = xor i16 %m, -171 %ma = and i16 %a, %not72 %mb = and i16 %b, %m73 %or = or i16 %ma, %mb74 ret i16 %or75}76 77define i32 @bitselect_i32(i32 %a, i32 %b, i32 %m) nounwind {78; X86-LABEL: bitselect_i32:79; X86: # %bb.0:80; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx81; X86-NEXT: movl {{[0-9]+}}(%esp), %eax82; X86-NEXT: xorl %ecx, %eax83; X86-NEXT: andl {{[0-9]+}}(%esp), %eax84; X86-NEXT: xorl %ecx, %eax85; X86-NEXT: retl86;87; X64-NOBMI-LABEL: bitselect_i32:88; X64-NOBMI: # %bb.0:89; X64-NOBMI-NEXT: movl %esi, %eax90; X64-NOBMI-NEXT: xorl %edi, %eax91; X64-NOBMI-NEXT: andl %edx, %eax92; X64-NOBMI-NEXT: xorl %edi, %eax93; X64-NOBMI-NEXT: retq94;95; X64-BMI-LABEL: bitselect_i32:96; X64-BMI: # %bb.0:97; X64-BMI-NEXT: andnl %edi, %edx, %eax98; X64-BMI-NEXT: andl %edx, %esi99; X64-BMI-NEXT: orl %esi, %eax100; X64-BMI-NEXT: retq101 %not = xor i32 %m, -1102 %ma = and i32 %a, %not103 %mb = and i32 %b, %m104 %or = or i32 %ma, %mb105 ret i32 %or106}107 108define i64 @bitselect_i64(i64 %a, i64 %b, i64 %m) nounwind {109; X86-LABEL: bitselect_i64:110; X86: # %bb.0:111; X86-NEXT: pushl %esi112; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx113; X86-NEXT: movl {{[0-9]+}}(%esp), %esi114; X86-NEXT: movl {{[0-9]+}}(%esp), %eax115; X86-NEXT: xorl %ecx, %eax116; X86-NEXT: andl {{[0-9]+}}(%esp), %eax117; X86-NEXT: xorl %ecx, %eax118; X86-NEXT: movl {{[0-9]+}}(%esp), %edx119; X86-NEXT: xorl %esi, %edx120; X86-NEXT: andl {{[0-9]+}}(%esp), %edx121; X86-NEXT: xorl %esi, %edx122; X86-NEXT: popl %esi123; X86-NEXT: retl124;125; X64-NOBMI-LABEL: bitselect_i64:126; X64-NOBMI: # %bb.0:127; X64-NOBMI-NEXT: movq %rsi, %rax128; X64-NOBMI-NEXT: xorq %rdi, %rax129; X64-NOBMI-NEXT: andq %rdx, %rax130; X64-NOBMI-NEXT: xorq %rdi, %rax131; X64-NOBMI-NEXT: retq132;133; X64-BMI-LABEL: bitselect_i64:134; X64-BMI: # %bb.0:135; X64-BMI-NEXT: andnq %rdi, %rdx, %rax136; X64-BMI-NEXT: andq %rdx, %rsi137; X64-BMI-NEXT: orq %rsi, %rax138; X64-BMI-NEXT: retq139 %not = xor i64 %m, -1140 %ma = and i64 %a, %not141 %mb = and i64 %b, %m142 %or = or i64 %ma, %mb143 ret i64 %or144}145 146define i128 @bitselect_i128(i128 %a, i128 %b, i128 %m) nounwind {147; X86-LABEL: bitselect_i128:148; X86: # %bb.0:149; X86-NEXT: pushl %ebp150; X86-NEXT: movl %esp, %ebp151; X86-NEXT: pushl %edi152; X86-NEXT: pushl %esi153; X86-NEXT: andl $-16, %esp154; X86-NEXT: movl 32(%ebp), %edx155; X86-NEXT: movl 36(%ebp), %eax156; X86-NEXT: movl 24(%ebp), %esi157; X86-NEXT: movl 28(%ebp), %edi158; X86-NEXT: movl 40(%ebp), %ecx159; X86-NEXT: xorl %esi, %ecx160; X86-NEXT: andl 56(%ebp), %ecx161; X86-NEXT: xorl %esi, %ecx162; X86-NEXT: movl 44(%ebp), %esi163; X86-NEXT: xorl %edi, %esi164; X86-NEXT: andl 60(%ebp), %esi165; X86-NEXT: xorl %edi, %esi166; X86-NEXT: movl 48(%ebp), %edi167; X86-NEXT: xorl %edx, %edi168; X86-NEXT: andl 64(%ebp), %edi169; X86-NEXT: xorl %edx, %edi170; X86-NEXT: movl 52(%ebp), %edx171; X86-NEXT: xorl %eax, %edx172; X86-NEXT: andl 68(%ebp), %edx173; X86-NEXT: xorl %eax, %edx174; X86-NEXT: movl 8(%ebp), %eax175; X86-NEXT: movl %edx, 12(%eax)176; X86-NEXT: movl %edi, 8(%eax)177; X86-NEXT: movl %esi, 4(%eax)178; X86-NEXT: movl %ecx, (%eax)179; X86-NEXT: leal -8(%ebp), %esp180; X86-NEXT: popl %esi181; X86-NEXT: popl %edi182; X86-NEXT: popl %ebp183; X86-NEXT: retl $4184;185; X64-NOBMI-LABEL: bitselect_i128:186; X64-NOBMI: # %bb.0:187; X64-NOBMI-NEXT: movq %rdx, %rax188; X64-NOBMI-NEXT: xorq %rdi, %rax189; X64-NOBMI-NEXT: andq %r8, %rax190; X64-NOBMI-NEXT: xorq %rdi, %rax191; X64-NOBMI-NEXT: xorq %rsi, %rcx192; X64-NOBMI-NEXT: andq %r9, %rcx193; X64-NOBMI-NEXT: xorq %rsi, %rcx194; X64-NOBMI-NEXT: movq %rcx, %rdx195; X64-NOBMI-NEXT: retq196;197; X64-BMI-LABEL: bitselect_i128:198; X64-BMI: # %bb.0:199; X64-BMI-NEXT: andnq %rdi, %r8, %rax200; X64-BMI-NEXT: andq %r8, %rdx201; X64-BMI-NEXT: orq %rdx, %rax202; X64-BMI-NEXT: andnq %rsi, %r9, %rdx203; X64-BMI-NEXT: andq %r9, %rcx204; X64-BMI-NEXT: orq %rcx, %rdx205; X64-BMI-NEXT: retq206 %not = xor i128 %m, -1207 %ma = and i128 %a, %not208 %mb = and i128 %b, %m209 %or = or i128 %ma, %mb210 ret i128 %or211}212 213;214; Bitselect between constants215;216 217; bitselect(52, -6553, m)218; TODO: Non-BMI canonicalization is actually better.219define i32 @bitselect_constants_i32(i32 %m) nounwind {220; X86-LABEL: bitselect_constants_i32:221; X86: # %bb.0:222; X86-NEXT: movl $-6573, %eax # imm = 0xE653223; X86-NEXT: andl {{[0-9]+}}(%esp), %eax224; X86-NEXT: xorl $52, %eax225; X86-NEXT: retl226;227; X64-NOBMI-LABEL: bitselect_constants_i32:228; X64-NOBMI: # %bb.0:229; X64-NOBMI-NEXT: movl %edi, %eax230; X64-NOBMI-NEXT: andl $-6573, %eax # imm = 0xE653231; X64-NOBMI-NEXT: xorl $52, %eax232; X64-NOBMI-NEXT: retq233;234; X64-BMI-LABEL: bitselect_constants_i32:235; X64-BMI: # %bb.0:236; X64-BMI-NEXT: movl %edi, %eax237; X64-BMI-NEXT: notl %eax238; X64-BMI-NEXT: andl $52, %eax239; X64-BMI-NEXT: andl $-6553, %edi # imm = 0xE667240; X64-BMI-NEXT: orl %edi, %eax241; X64-BMI-NEXT: retq242 %not = xor i32 %m, -1243 %ma = and i32 52, %not244 %mb = and i32 -6553, %m245 %or = or i32 %ma, %mb246 ret i32 %or247}248