328 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc < %s -mtriple=i686-- -mattr=-bmi,+sse2 | FileCheck %s --check-prefixes=X86,X86-NOBMI3; RUN: llc < %s -mtriple=i686-- -mattr=+bmi,+sse2 | FileCheck %s --check-prefixes=X86,X86-BMI4; RUN: llc < %s -mtriple=x86_64-- -mattr=-bmi | FileCheck %s --check-prefixes=X64,X64-NOBMI5; RUN: llc < %s -mtriple=x86_64-- -mattr=+bmi | FileCheck %s --check-prefixes=X64,X64-BMI6 7declare void @use(i32)8 9define i32 @fold_and_xor_neg_v1_32(i32 %x, i32 %y) nounwind {10; X86-NOBMI-LABEL: fold_and_xor_neg_v1_32:11; X86-NOBMI: # %bb.0:12; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx13; X86-NOBMI-NEXT: movl %ecx, %eax14; X86-NOBMI-NEXT: negl %eax15; X86-NOBMI-NEXT: xorl %ecx, %eax16; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax17; X86-NOBMI-NEXT: retl18;19; X86-BMI-LABEL: fold_and_xor_neg_v1_32:20; X86-BMI: # %bb.0:21; X86-BMI-NEXT: blsmskl {{[0-9]+}}(%esp), %eax22; X86-BMI-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax23; X86-BMI-NEXT: retl24;25; X64-NOBMI-LABEL: fold_and_xor_neg_v1_32:26; X64-NOBMI: # %bb.0:27; X64-NOBMI-NEXT: movl %edi, %eax28; X64-NOBMI-NEXT: negl %eax29; X64-NOBMI-NEXT: xorl %edi, %eax30; X64-NOBMI-NEXT: andl %esi, %eax31; X64-NOBMI-NEXT: retq32;33; X64-BMI-LABEL: fold_and_xor_neg_v1_32:34; X64-BMI: # %bb.0:35; X64-BMI-NEXT: blsmskl %edi, %eax36; X64-BMI-NEXT: andnl %esi, %eax, %eax37; X64-BMI-NEXT: retq38 %neg = sub i32 0, %x39 %xor = xor i32 %x, %neg40 %and = and i32 %xor, %y41 ret i32 %and42}43 44define i32 @fold_and_xor_neg_v2_32(i32 %x, i32 %y) nounwind {45; X86-NOBMI-LABEL: fold_and_xor_neg_v2_32:46; X86-NOBMI: # %bb.0:47; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx48; X86-NOBMI-NEXT: movl %ecx, %eax49; X86-NOBMI-NEXT: negl %eax50; X86-NOBMI-NEXT: xorl %ecx, %eax51; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax52; X86-NOBMI-NEXT: retl53;54; X86-BMI-LABEL: fold_and_xor_neg_v2_32:55; X86-BMI: # %bb.0:56; X86-BMI-NEXT: blsmskl {{[0-9]+}}(%esp), %eax57; X86-BMI-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax58; X86-BMI-NEXT: retl59;60; X64-NOBMI-LABEL: fold_and_xor_neg_v2_32:61; X64-NOBMI: # %bb.0:62; X64-NOBMI-NEXT: movl %edi, %eax63; X64-NOBMI-NEXT: negl %eax64; X64-NOBMI-NEXT: xorl %edi, %eax65; X64-NOBMI-NEXT: andl %esi, %eax66; X64-NOBMI-NEXT: retq67;68; X64-BMI-LABEL: fold_and_xor_neg_v2_32:69; X64-BMI: # %bb.0:70; X64-BMI-NEXT: blsmskl %edi, %eax71; X64-BMI-NEXT: andnl %esi, %eax, %eax72; X64-BMI-NEXT: retq73 %neg = sub i32 0, %x74 %xor = xor i32 %x, %neg75 %and = and i32 %y, %xor76 ret i32 %and77}78 79define i32 @fold_and_xor_neg_v3_32(i32 %x, i32 %y) nounwind {80; X86-NOBMI-LABEL: fold_and_xor_neg_v3_32:81; X86-NOBMI: # %bb.0:82; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx83; X86-NOBMI-NEXT: movl %ecx, %eax84; X86-NOBMI-NEXT: negl %eax85; X86-NOBMI-NEXT: xorl %ecx, %eax86; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax87; X86-NOBMI-NEXT: retl88;89; X86-BMI-LABEL: fold_and_xor_neg_v3_32:90; X86-BMI: # %bb.0:91; X86-BMI-NEXT: blsmskl {{[0-9]+}}(%esp), %eax92; X86-BMI-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax93; X86-BMI-NEXT: retl94;95; X64-NOBMI-LABEL: fold_and_xor_neg_v3_32:96; X64-NOBMI: # %bb.0:97; X64-NOBMI-NEXT: movl %edi, %eax98; X64-NOBMI-NEXT: negl %eax99; X64-NOBMI-NEXT: xorl %edi, %eax100; X64-NOBMI-NEXT: andl %esi, %eax101; X64-NOBMI-NEXT: retq102;103; X64-BMI-LABEL: fold_and_xor_neg_v3_32:104; X64-BMI: # %bb.0:105; X64-BMI-NEXT: blsmskl %edi, %eax106; X64-BMI-NEXT: andnl %esi, %eax, %eax107; X64-BMI-NEXT: retq108 %neg = sub i32 0, %x109 %xor = xor i32 %neg, %x110 %and = and i32 %xor, %y111 ret i32 %and112}113 114define i32 @fold_and_xor_neg_v4_32(i32 %x, i32 %y) nounwind {115; X86-NOBMI-LABEL: fold_and_xor_neg_v4_32:116; X86-NOBMI: # %bb.0:117; X86-NOBMI-NEXT: movl {{[0-9]+}}(%esp), %ecx118; X86-NOBMI-NEXT: movl %ecx, %eax119; X86-NOBMI-NEXT: negl %eax120; X86-NOBMI-NEXT: xorl %ecx, %eax121; X86-NOBMI-NEXT: andl {{[0-9]+}}(%esp), %eax122; X86-NOBMI-NEXT: retl123;124; X86-BMI-LABEL: fold_and_xor_neg_v4_32:125; X86-BMI: # %bb.0:126; X86-BMI-NEXT: blsmskl {{[0-9]+}}(%esp), %eax127; X86-BMI-NEXT: andnl {{[0-9]+}}(%esp), %eax, %eax128; X86-BMI-NEXT: retl129;130; X64-NOBMI-LABEL: fold_and_xor_neg_v4_32:131; X64-NOBMI: # %bb.0:132; X64-NOBMI-NEXT: movl %edi, %eax133; X64-NOBMI-NEXT: negl %eax134; X64-NOBMI-NEXT: xorl %edi, %eax135; X64-NOBMI-NEXT: andl %esi, %eax136; X64-NOBMI-NEXT: retq137;138; X64-BMI-LABEL: fold_and_xor_neg_v4_32:139; X64-BMI: # %bb.0:140; X64-BMI-NEXT: blsmskl %edi, %eax141; X64-BMI-NEXT: andnl %esi, %eax, %eax142; X64-BMI-NEXT: retq143 %neg = sub i32 0, %x144 %xor = xor i32 %neg, %x145 %and = and i32 %y, %xor146 ret i32 %and147}148 149define i64 @fold_and_xor_neg_v1_64(i64 %x, i64 %y) nounwind {150; X86-LABEL: fold_and_xor_neg_v1_64:151; X86: # %bb.0:152; X86-NEXT: pushl %esi153; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx154; X86-NEXT: movl {{[0-9]+}}(%esp), %esi155; X86-NEXT: xorl %edx, %edx156; X86-NEXT: movl %ecx, %eax157; X86-NEXT: negl %eax158; X86-NEXT: sbbl %esi, %edx159; X86-NEXT: xorl %esi, %edx160; X86-NEXT: xorl %ecx, %eax161; X86-NEXT: andl {{[0-9]+}}(%esp), %edx162; X86-NEXT: andl {{[0-9]+}}(%esp), %eax163; X86-NEXT: popl %esi164; X86-NEXT: retl165;166; X64-NOBMI-LABEL: fold_and_xor_neg_v1_64:167; X64-NOBMI: # %bb.0:168; X64-NOBMI-NEXT: movq %rdi, %rax169; X64-NOBMI-NEXT: negq %rax170; X64-NOBMI-NEXT: xorq %rdi, %rax171; X64-NOBMI-NEXT: andq %rsi, %rax172; X64-NOBMI-NEXT: retq173;174; X64-BMI-LABEL: fold_and_xor_neg_v1_64:175; X64-BMI: # %bb.0:176; X64-BMI-NEXT: blsmskq %rdi, %rax177; X64-BMI-NEXT: andnq %rsi, %rax, %rax178; X64-BMI-NEXT: retq179 %neg = sub i64 0, %x180 %xor = xor i64 %x, %neg181 %and = and i64 %xor, %y182 ret i64 %and183}184 185; Negative test186define i16 @fold_and_xor_neg_v1_16_negative(i16 %x, i16 %y) nounwind {187; X86-LABEL: fold_and_xor_neg_v1_16_negative:188; X86: # %bb.0:189; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx190; X86-NEXT: movl %ecx, %eax191; X86-NEXT: negl %eax192; X86-NEXT: xorl %ecx, %eax193; X86-NEXT: andw {{[0-9]+}}(%esp), %ax194; X86-NEXT: # kill: def $ax killed $ax killed $eax195; X86-NEXT: retl196;197; X64-LABEL: fold_and_xor_neg_v1_16_negative:198; X64: # %bb.0:199; X64-NEXT: movl %edi, %eax200; X64-NEXT: negl %eax201; X64-NEXT: xorl %edi, %eax202; X64-NEXT: andl %esi, %eax203; X64-NEXT: # kill: def $ax killed $ax killed $eax204; X64-NEXT: retq205 %neg = sub i16 0, %x206 %xor = xor i16 %x, %neg207 %and = and i16 %xor, %y208 ret i16 %and209}210 211; Negative test212define <4 x i32> @fold_and_xor_neg_v1_v4x32_negative(<4 x i32> %x, <4 x i32> %y) nounwind {213; X86-LABEL: fold_and_xor_neg_v1_v4x32_negative:214; X86: # %bb.0:215; X86-NEXT: pxor %xmm2, %xmm2216; X86-NEXT: psubd %xmm0, %xmm2217; X86-NEXT: pxor %xmm2, %xmm0218; X86-NEXT: pand %xmm1, %xmm0219; X86-NEXT: retl220;221; X64-LABEL: fold_and_xor_neg_v1_v4x32_negative:222; X64: # %bb.0:223; X64-NEXT: pxor %xmm2, %xmm2224; X64-NEXT: psubd %xmm0, %xmm2225; X64-NEXT: pxor %xmm2, %xmm0226; X64-NEXT: pand %xmm1, %xmm0227; X64-NEXT: retq228 %neg = sub <4 x i32> zeroinitializer, %x229 %xor = xor <4 x i32> %x, %neg230 %and = and <4 x i32> %xor, %y231 ret <4 x i32> %and232}233 234; Negative test235define i32 @fold_and_xor_neg_v1_32_two_uses_xor_negative(i32 %x, i32 %y) nounwind {236; X86-LABEL: fold_and_xor_neg_v1_32_two_uses_xor_negative:237; X86: # %bb.0:238; X86-NEXT: pushl %esi239; X86-NEXT: movl {{[0-9]+}}(%esp), %eax240; X86-NEXT: movl %eax, %ecx241; X86-NEXT: negl %ecx242; X86-NEXT: xorl %eax, %ecx243; X86-NEXT: movl {{[0-9]+}}(%esp), %esi244; X86-NEXT: andl %ecx, %esi245; X86-NEXT: pushl %ecx246; X86-NEXT: calll use@PLT247; X86-NEXT: addl $4, %esp248; X86-NEXT: movl %esi, %eax249; X86-NEXT: popl %esi250; X86-NEXT: retl251;252; X64-LABEL: fold_and_xor_neg_v1_32_two_uses_xor_negative:253; X64: # %bb.0:254; X64-NEXT: pushq %rbx255; X64-NEXT: movl %esi, %ebx256; X64-NEXT: movl %edi, %eax257; X64-NEXT: negl %eax258; X64-NEXT: xorl %eax, %edi259; X64-NEXT: andl %edi, %ebx260; X64-NEXT: callq use@PLT261; X64-NEXT: movl %ebx, %eax262; X64-NEXT: popq %rbx263; X64-NEXT: retq264 %neg = sub i32 0, %x265 %xor = xor i32 %x, %neg266 %and = and i32 %xor, %y267 call void @use(i32 %xor)268 ret i32 %and269}270 271; Negative test272define i32 @fold_and_xor_neg_v1_32_two_uses_sub_negative(i32 %x, i32 %y) nounwind {273; X86-LABEL: fold_and_xor_neg_v1_32_two_uses_sub_negative:274; X86: # %bb.0:275; X86-NEXT: pushl %esi276; X86-NEXT: movl {{[0-9]+}}(%esp), %esi277; X86-NEXT: movl %esi, %eax278; X86-NEXT: negl %eax279; X86-NEXT: xorl %eax, %esi280; X86-NEXT: andl {{[0-9]+}}(%esp), %esi281; X86-NEXT: pushl %eax282; X86-NEXT: calll use@PLT283; X86-NEXT: addl $4, %esp284; X86-NEXT: movl %esi, %eax285; X86-NEXT: popl %esi286; X86-NEXT: retl287;288; X64-LABEL: fold_and_xor_neg_v1_32_two_uses_sub_negative:289; X64: # %bb.0:290; X64-NEXT: pushq %rbx291; X64-NEXT: movl %edi, %ebx292; X64-NEXT: negl %edi293; X64-NEXT: xorl %edi, %ebx294; X64-NEXT: andl %esi, %ebx295; X64-NEXT: callq use@PLT296; X64-NEXT: movl %ebx, %eax297; X64-NEXT: popq %rbx298; X64-NEXT: retq299 %neg = sub i32 0, %x300 %xor = xor i32 %x, %neg301 %and = and i32 %xor, %y302 call void @use(i32 %neg)303 ret i32 %and304}305 306; Negative test307define i32 @fold_and_xor_neg_v1_32_no_blsmsk_negative(i32 %x, i32 %y, i32 %z) nounwind {308; X86-LABEL: fold_and_xor_neg_v1_32_no_blsmsk_negative:309; X86: # %bb.0:310; X86-NEXT: xorl %eax, %eax311; X86-NEXT: subl {{[0-9]+}}(%esp), %eax312; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax313; X86-NEXT: andl {{[0-9]+}}(%esp), %eax314; X86-NEXT: retl315;316; X64-LABEL: fold_and_xor_neg_v1_32_no_blsmsk_negative:317; X64: # %bb.0:318; X64-NEXT: movl %edx, %eax319; X64-NEXT: negl %eax320; X64-NEXT: xorl %edi, %eax321; X64-NEXT: andl %esi, %eax322; X64-NEXT: retq323 %neg = sub i32 0, %z324 %xor = xor i32 %x, %neg325 %and = and i32 %xor, %y326 ret i32 %and327}328