brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.6 KiB · e5696de Raw
866 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov,+sse2,+bmi | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov,+sse2,+bmi,+bmi2 | FileCheck %s --check-prefixes=X864; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=X645; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi,+bmi2 | FileCheck %s --check-prefixes=X646 7; PR1315878define i32 @and_select_neg_to_blsi1(i1 %a0, i32 inreg %a1) nounwind {9; X86-LABEL: and_select_neg_to_blsi1:10; X86:       # %bb.0:11; X86-NEXT:    blsil %eax, %ecx12; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)13; X86-NEXT:    cmovnel %ecx, %eax14; X86-NEXT:    retl15;16; X64-LABEL: and_select_neg_to_blsi1:17; X64:       # %bb.0:18; X64-NEXT:    blsil %esi, %eax19; X64-NEXT:    testb $1, %dil20; X64-NEXT:    cmovel %esi, %eax21; X64-NEXT:    retq22  %sub = sub i32 0, %a123  %bls = select i1 %a0, i32 %sub, i32 -124  %ret = and i32 %a1, %bls25  ret i32 %ret26}27 28; PR13158729define i32 @and_select_neg_to_blsi2(i1 %a0, i32 inreg %a1) nounwind {30; X86-LABEL: and_select_neg_to_blsi2:31; X86:       # %bb.0:32; X86-NEXT:    blsil %eax, %ecx33; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)34; X86-NEXT:    cmovnel %ecx, %eax35; X86-NEXT:    retl36;37; X64-LABEL: and_select_neg_to_blsi2:38; X64:       # %bb.0:39; X64-NEXT:    blsil %esi, %eax40; X64-NEXT:    testb $1, %dil41; X64-NEXT:    cmovel %esi, %eax42; X64-NEXT:    retq43  %sub = sub i32 0, %a144  %bls = select i1 %a0, i32 %sub, i32 -145  %ret = and i32 %bls, %a146  ret i32 %ret47}48 49; PR13158750define i32 @and_select_neg_to_blsi3(i1 %a0, i32 inreg %a1) nounwind {51; X86-LABEL: and_select_neg_to_blsi3:52; X86:       # %bb.0:53; X86-NEXT:    blsil %eax, %ecx54; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)55; X86-NEXT:    cmovel %ecx, %eax56; X86-NEXT:    retl57;58; X64-LABEL: and_select_neg_to_blsi3:59; X64:       # %bb.0:60; X64-NEXT:    blsil %esi, %eax61; X64-NEXT:    testb $1, %dil62; X64-NEXT:    cmovnel %esi, %eax63; X64-NEXT:    retq64  %sub = sub i32 0, %a165  %bls = select i1 %a0, i32 -1, i32 %sub66  %ret = and i32 %a1, %bls67  ret i32 %ret68}69 70; PR13158771define i64 @and_select_neg_to_blsi_i64(i1 %a0, i64 %a1) nounwind {72; X86-LABEL: and_select_neg_to_blsi_i64:73; X86:       # %bb.0:74; X86-NEXT:    pushl %esi75; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx76; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi77; X86-NEXT:    xorl %edx, %edx78; X86-NEXT:    movl %ecx, %eax79; X86-NEXT:    negl %eax80; X86-NEXT:    sbbl %esi, %edx81; X86-NEXT:    andl %esi, %edx82; X86-NEXT:    andl %ecx, %eax83; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)84; X86-NEXT:    cmovel %esi, %edx85; X86-NEXT:    cmovel %ecx, %eax86; X86-NEXT:    popl %esi87; X86-NEXT:    retl88;89; X64-LABEL: and_select_neg_to_blsi_i64:90; X64:       # %bb.0:91; X64-NEXT:    blsiq %rsi, %rax92; X64-NEXT:    testb $1, %dil93; X64-NEXT:    cmoveq %rsi, %rax94; X64-NEXT:    retq95  %sub = sub i64 0, %a196  %bls = select i1 %a0, i64 %sub, i64 -197  %ret = and i64 %a1, %bls98  ret i64 %ret99}100 101; The transformation also applies to the following test although we do not emit a BLSI instruction102; here because the negation instruction is used more than once.103define i32 @and_neg_select_pos_i32(i1 %a0, i32 inreg %a1) nounwind {104; X86-LABEL: and_neg_select_pos_i32:105; X86:       # %bb.0:106; X86-NEXT:    movl %eax, %ecx107; X86-NEXT:    negl %ecx108; X86-NEXT:    andl %ecx, %eax109; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)110; X86-NEXT:    cmovel %ecx, %eax111; X86-NEXT:    retl112;113; X64-LABEL: and_neg_select_pos_i32:114; X64:       # %bb.0:115; X64-NEXT:    movl %esi, %eax116; X64-NEXT:    negl %eax117; X64-NEXT:    andl %eax, %esi118; X64-NEXT:    testb $1, %dil119; X64-NEXT:    cmovnel %esi, %eax120; X64-NEXT:    retq121  %sub = sub i32 0, %a1122  %bls = select i1 %a0, i32 %a1, i32 -1123  %ret = and i32 %sub, %bls124  ret i32 %ret125}126 127; Negative test128define i16 @and_select_neg_i16(i1 %a0, i16 %a1) nounwind {129; X86-LABEL: and_select_neg_i16:130; X86:       # %bb.0:131; X86-NEXT:    pushl %esi132; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx133; X86-NEXT:    andb $1, %cl134; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx135; X86-NEXT:    movl %edx, %esi136; X86-NEXT:    negl %esi137; X86-NEXT:    xorl %eax, %eax138; X86-NEXT:    cmpb $1, %cl139; X86-NEXT:    sbbl %eax, %eax140; X86-NEXT:    orl %esi, %eax141; X86-NEXT:    andl %edx, %eax142; X86-NEXT:    # kill: def $ax killed $ax killed $eax143; X86-NEXT:    popl %esi144; X86-NEXT:    retl145;146; X64-LABEL: and_select_neg_i16:147; X64:       # %bb.0:148; X64-NEXT:    andb $1, %dil149; X64-NEXT:    movl %esi, %ecx150; X64-NEXT:    negl %ecx151; X64-NEXT:    xorl %eax, %eax152; X64-NEXT:    cmpb $1, %dil153; X64-NEXT:    sbbl %eax, %eax154; X64-NEXT:    orl %ecx, %eax155; X64-NEXT:    andl %esi, %eax156; X64-NEXT:    # kill: def $ax killed $ax killed $eax157; X64-NEXT:    retq158  %sub = sub i16 0, %a1159  %bls = select i1 %a0, i16 %sub, i16 -1160  %ret = and i16 %a1, %bls161  ret i16 %ret162}163 164; Negative test165define <4 x i32> @and_select_neg_v4xi32(i1 %a0, <4 x i32> %a1) nounwind {166; X86-LABEL: and_select_neg_v4xi32:167; X86:       # %bb.0:168; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)169; X86-NEXT:    jne .LBB6_1170; X86-NEXT:  # %bb.2:171; X86-NEXT:    pcmpeqd %xmm1, %xmm1172; X86-NEXT:    pand %xmm1, %xmm0173; X86-NEXT:    retl174; X86-NEXT:  .LBB6_1:175; X86-NEXT:    pxor %xmm1, %xmm1176; X86-NEXT:    psubd %xmm0, %xmm1177; X86-NEXT:    pand %xmm1, %xmm0178; X86-NEXT:    retl179;180; X64-LABEL: and_select_neg_v4xi32:181; X64:       # %bb.0:182; X64-NEXT:    testb $1, %dil183; X64-NEXT:    jne .LBB6_1184; X64-NEXT:  # %bb.2:185; X64-NEXT:    pcmpeqd %xmm1, %xmm1186; X64-NEXT:    pand %xmm1, %xmm0187; X64-NEXT:    retq188; X64-NEXT:  .LBB6_1:189; X64-NEXT:    pxor %xmm1, %xmm1190; X64-NEXT:    psubd %xmm0, %xmm1191; X64-NEXT:    pand %xmm1, %xmm0192; X64-NEXT:    retq193  %sub = sub <4 x i32> zeroinitializer, %a1194  %bls = select i1 %a0, <4 x i32> %sub, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>195  %ret = and <4 x i32> %a1, %bls196  ret <4 x i32> %ret197}198 199; Negative test200define i32 @and_select_no_neg(i1 %a0, i32 inreg %a1) nounwind {201; X86-LABEL: and_select_no_neg:202; X86:       # %bb.0:203; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx204; X86-NEXT:    andb $1, %cl205; X86-NEXT:    xorl %edx, %edx206; X86-NEXT:    cmpb $1, %cl207; X86-NEXT:    sbbl %edx, %edx208; X86-NEXT:    orl %eax, %edx209; X86-NEXT:    andl %edx, %eax210; X86-NEXT:    retl211;212; X64-LABEL: and_select_no_neg:213; X64:       # %bb.0:214; X64-NEXT:    andb $1, %dil215; X64-NEXT:    xorl %eax, %eax216; X64-NEXT:    cmpb $1, %dil217; X64-NEXT:    sbbl %eax, %eax218; X64-NEXT:    orl %esi, %eax219; X64-NEXT:    andl %esi, %eax220; X64-NEXT:    retq221  %sub = sub i32 %a1, 0222  %bls = select i1 %a0, i32 %sub, i32 -1223  %ret = and i32 %a1, %bls224  ret i32 %ret225}226 227; Negative test228define i32 @and_select_neg_wrong_const(i1 %a0, i32 inreg %a1) nounwind {229; X86-LABEL: and_select_neg_wrong_const:230; X86:       # %bb.0:231; X86-NEXT:    movl %eax, %ecx232; X86-NEXT:    negl %ecx233; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)234; X86-NEXT:    movl $1, %edx235; X86-NEXT:    cmovnel %ecx, %edx236; X86-NEXT:    andl %edx, %eax237; X86-NEXT:    retl238;239; X64-LABEL: and_select_neg_wrong_const:240; X64:       # %bb.0:241; X64-NEXT:    movl %esi, %ecx242; X64-NEXT:    negl %ecx243; X64-NEXT:    testb $1, %dil244; X64-NEXT:    movl $1, %eax245; X64-NEXT:    cmovnel %ecx, %eax246; X64-NEXT:    andl %esi, %eax247; X64-NEXT:    retq248  %sub = sub i32 0, %a1249  %bls = select i1 %a0, i32 %sub, i32 1250  %ret = and i32 %a1, %bls251  ret i32 %ret252}253 254; Negative test255define i32 @and_select_neg_different_op(i1 %a0, i32 inreg %a1, i32 inreg %a2) nounwind {256; X86-LABEL: and_select_neg_different_op:257; X86:       # %bb.0:258; X86-NEXT:    pushl %esi259; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx260; X86-NEXT:    andb $1, %cl261; X86-NEXT:    negl %edx262; X86-NEXT:    xorl %esi, %esi263; X86-NEXT:    cmpb $1, %cl264; X86-NEXT:    sbbl %esi, %esi265; X86-NEXT:    orl %edx, %esi266; X86-NEXT:    andl %esi, %eax267; X86-NEXT:    popl %esi268; X86-NEXT:    retl269;270; X64-LABEL: and_select_neg_different_op:271; X64:       # %bb.0:272; X64-NEXT:    andb $1, %dil273; X64-NEXT:    negl %edx274; X64-NEXT:    xorl %eax, %eax275; X64-NEXT:    cmpb $1, %dil276; X64-NEXT:    sbbl %eax, %eax277; X64-NEXT:    orl %edx, %eax278; X64-NEXT:    andl %esi, %eax279; X64-NEXT:    retq280  %sub = sub i32 0, %a2281  %bls = select i1 %a0, i32 %sub, i32 -1282  %ret = and i32 %a1, %bls283  ret i32 %ret284}285 286; PR133848287define i32 @and_select_sub_1_to_blsr1(i1 %a0, i32 inreg %a1) nounwind {288; X86-LABEL: and_select_sub_1_to_blsr1:289; X86:       # %bb.0:290; X86-NEXT:    blsrl %eax, %ecx291; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)292; X86-NEXT:    cmovnel %ecx, %eax293; X86-NEXT:    retl294;295; X64-LABEL: and_select_sub_1_to_blsr1:296; X64:       # %bb.0:297; X64-NEXT:    blsrl %esi, %eax298; X64-NEXT:    testb $1, %dil299; X64-NEXT:    cmovel %esi, %eax300; X64-NEXT:    retq301  %sub = add i32 %a1, -1302  %bls = select i1 %a0, i32 %sub, i32 -1303  %ret = and i32 %a1, %bls304  ret i32 %ret305}306 307; PR133848308define i32 @and_select_sub_1_to_blsr2(i1 %a0, i32 inreg %a1) nounwind {309; X86-LABEL: and_select_sub_1_to_blsr2:310; X86:       # %bb.0:311; X86-NEXT:    blsrl %eax, %ecx312; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)313; X86-NEXT:    cmovnel %ecx, %eax314; X86-NEXT:    retl315;316; X64-LABEL: and_select_sub_1_to_blsr2:317; X64:       # %bb.0:318; X64-NEXT:    blsrl %esi, %eax319; X64-NEXT:    testb $1, %dil320; X64-NEXT:    cmovel %esi, %eax321; X64-NEXT:    retq322  %sub = add i32 %a1, -1323  %bls = select i1 %a0, i32 %sub, i32 -1324  %ret = and i32 %bls, %a1325  ret i32 %ret326}327 328; PR133848329define i32 @and_select_sub_1_to_blsr3(i1 %a0, i32 inreg %a1) nounwind {330; X86-LABEL: and_select_sub_1_to_blsr3:331; X86:       # %bb.0:332; X86-NEXT:    blsrl %eax, %ecx333; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)334; X86-NEXT:    cmovel %ecx, %eax335; X86-NEXT:    retl336;337; X64-LABEL: and_select_sub_1_to_blsr3:338; X64:       # %bb.0:339; X64-NEXT:    blsrl %esi, %eax340; X64-NEXT:    testb $1, %dil341; X64-NEXT:    cmovnel %esi, %eax342; X64-NEXT:    retq343  %sub = add i32 %a1, -1344  %bls = select i1 %a0, i32 -1, i32 %sub345  %ret = and i32 %a1, %bls346  ret i32 %ret347}348 349; PR133848350define i32 @and_select_sub_1_to_blsr4(i1 %a0, i32 inreg %a1) nounwind {351; X86-LABEL: and_select_sub_1_to_blsr4:352; X86:       # %bb.0:353; X86-NEXT:    blsrl %eax, %ecx354; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)355; X86-NEXT:    cmovnel %ecx, %eax356; X86-NEXT:    retl357;358; X64-LABEL: and_select_sub_1_to_blsr4:359; X64:       # %bb.0:360; X64-NEXT:    blsrl %esi, %eax361; X64-NEXT:    testb $1, %dil362; X64-NEXT:    cmovel %esi, %eax363; X64-NEXT:    retq364  %sub = sub i32 %a1, 1365  %bls = select i1 %a0, i32 %sub, i32 -1366  %ret = and i32 %a1, %bls367  ret i32 %ret368}369 370; The transformation also applies to the following test although we do not emit a BLSR instruction371; here because the subtraction instruction is used more than once.372define i32 @and_sub_1_select_orig(i1 %a0, i32 inreg %a1) nounwind {373; X86-LABEL: and_sub_1_select_orig:374; X86:       # %bb.0:375; X86-NEXT:    leal -1(%eax), %ecx376; X86-NEXT:    andl %ecx, %eax377; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)378; X86-NEXT:    cmovel %ecx, %eax379; X86-NEXT:    retl380;381; X64-LABEL: and_sub_1_select_orig:382; X64:       # %bb.0:383; X64-NEXT:    # kill: def $esi killed $esi def $rsi384; X64-NEXT:    leal -1(%rsi), %eax385; X64-NEXT:    andl %eax, %esi386; X64-NEXT:    testb $1, %dil387; X64-NEXT:    cmovnel %esi, %eax388; X64-NEXT:    retq389  %sub = add i32 %a1, -1390  %bls = select i1 %a0, i32 %a1, i32 -1391  %ret = and i32 %sub, %bls392  ret i32 %ret393}394 395; PR133848396define i64 @and_select_sub_1_to_blsr_i64(i1 %a0, i64 %a1) nounwind {397; X86-LABEL: and_select_sub_1_to_blsr_i64:398; X86:       # %bb.0:399; X86-NEXT:    pushl %esi400; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx401; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi402; X86-NEXT:    movl %ecx, %eax403; X86-NEXT:    addl $-1, %eax404; X86-NEXT:    movl %esi, %edx405; X86-NEXT:    adcl $-1, %edx406; X86-NEXT:    andl %esi, %edx407; X86-NEXT:    andl %ecx, %eax408; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)409; X86-NEXT:    cmovel %ecx, %eax410; X86-NEXT:    cmovel %esi, %edx411; X86-NEXT:    popl %esi412; X86-NEXT:    retl413;414; X64-LABEL: and_select_sub_1_to_blsr_i64:415; X64:       # %bb.0:416; X64-NEXT:    blsrq %rsi, %rax417; X64-NEXT:    testb $1, %dil418; X64-NEXT:    cmoveq %rsi, %rax419; X64-NEXT:    retq420  %sub = add i64 %a1, -1421  %bls = select i1 %a0, i64 %sub, i64 -1422  %ret = and i64 %a1, %bls423  ret i64 %ret424}425 426; Negative test427define i16 @and_select_sub_1_i16(i1 %a0, i16 %a1) nounwind {428; X86-LABEL: and_select_sub_1_i16:429; X86:       # %bb.0:430; X86-NEXT:    pushl %esi431; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx432; X86-NEXT:    andb $1, %cl433; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx434; X86-NEXT:    leal -1(%edx), %esi435; X86-NEXT:    xorl %eax, %eax436; X86-NEXT:    cmpb $1, %cl437; X86-NEXT:    sbbl %eax, %eax438; X86-NEXT:    orl %esi, %eax439; X86-NEXT:    andl %edx, %eax440; X86-NEXT:    # kill: def $ax killed $ax killed $eax441; X86-NEXT:    popl %esi442; X86-NEXT:    retl443;444; X64-LABEL: and_select_sub_1_i16:445; X64:       # %bb.0:446; X64-NEXT:    # kill: def $esi killed $esi def $rsi447; X64-NEXT:    andb $1, %dil448; X64-NEXT:    leal -1(%rsi), %ecx449; X64-NEXT:    xorl %eax, %eax450; X64-NEXT:    cmpb $1, %dil451; X64-NEXT:    sbbl %eax, %eax452; X64-NEXT:    orl %ecx, %eax453; X64-NEXT:    andl %esi, %eax454; X64-NEXT:    # kill: def $ax killed $ax killed $eax455; X64-NEXT:    retq456  %sub = add i16 %a1, -1457  %bls = select i1 %a0, i16 %sub, i16 -1458  %ret = and i16 %a1, %bls459  ret i16 %ret460}461 462; Negative test463define <4 x i32> @and_select_sub_1_v4xi32(i1 %a0, <4 x i32> %a1) nounwind {464; X86-LABEL: and_select_sub_1_v4xi32:465; X86:       # %bb.0:466; X86-NEXT:    pcmpeqd %xmm1, %xmm1467; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)468; X86-NEXT:    je .LBB17_2469; X86-NEXT:  # %bb.1:470; X86-NEXT:    paddd %xmm0, %xmm1471; X86-NEXT:  .LBB17_2:472; X86-NEXT:    pand %xmm1, %xmm0473; X86-NEXT:    retl474;475; X64-LABEL: and_select_sub_1_v4xi32:476; X64:       # %bb.0:477; X64-NEXT:    pcmpeqd %xmm1, %xmm1478; X64-NEXT:    testb $1, %dil479; X64-NEXT:    je .LBB17_2480; X64-NEXT:  # %bb.1:481; X64-NEXT:    paddd %xmm0, %xmm1482; X64-NEXT:  .LBB17_2:483; X64-NEXT:    pand %xmm1, %xmm0484; X64-NEXT:    retq485  %sub = add <4 x i32> %a1, <i32 -1, i32 -1, i32 -1, i32 -1>486  %bls = select i1 %a0, <4 x i32> %sub, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>487  %ret = and <4 x i32> %a1, %bls488  ret <4 x i32> %ret489}490 491; Negative test492define i32 @and_select_no_sub_1(i1 %a0, i32 inreg %a1) nounwind {493; X86-LABEL: and_select_no_sub_1:494; X86:       # %bb.0:495; X86-NEXT:    pushl %esi496; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx497; X86-NEXT:    andb $1, %cl498; X86-NEXT:    leal -2(%eax), %edx499; X86-NEXT:    xorl %esi, %esi500; X86-NEXT:    cmpb $1, %cl501; X86-NEXT:    sbbl %esi, %esi502; X86-NEXT:    orl %edx, %esi503; X86-NEXT:    andl %esi, %eax504; X86-NEXT:    popl %esi505; X86-NEXT:    retl506;507; X64-LABEL: and_select_no_sub_1:508; X64:       # %bb.0:509; X64-NEXT:    # kill: def $esi killed $esi def $rsi510; X64-NEXT:    andb $1, %dil511; X64-NEXT:    leal -2(%rsi), %ecx512; X64-NEXT:    xorl %eax, %eax513; X64-NEXT:    cmpb $1, %dil514; X64-NEXT:    sbbl %eax, %eax515; X64-NEXT:    orl %ecx, %eax516; X64-NEXT:    andl %esi, %eax517; X64-NEXT:    retq518  %sub = add i32 %a1, -2519  %bls = select i1 %a0, i32 %sub, i32 -1520  %ret = and i32 %a1, %bls521  ret i32 %ret522}523 524; Negative test525define i32 @and_select_sub_1_wrong_const(i1 %a0, i32 inreg %a1) nounwind {526; X86-LABEL: and_select_sub_1_wrong_const:527; X86:       # %bb.0:528; X86-NEXT:    leal -1(%eax), %ecx529; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)530; X86-NEXT:    movl $1, %edx531; X86-NEXT:    cmovnel %ecx, %edx532; X86-NEXT:    andl %edx, %eax533; X86-NEXT:    retl534;535; X64-LABEL: and_select_sub_1_wrong_const:536; X64:       # %bb.0:537; X64-NEXT:    # kill: def $esi killed $esi def $rsi538; X64-NEXT:    leal -1(%rsi), %ecx539; X64-NEXT:    testb $1, %dil540; X64-NEXT:    movl $1, %eax541; X64-NEXT:    cmovnel %ecx, %eax542; X64-NEXT:    andl %esi, %eax543; X64-NEXT:    retq544  %sub = add i32 %a1, -1545  %bls = select i1 %a0, i32 %sub, i32 1546  %ret = and i32 %a1, %bls547  ret i32 %ret548}549 550; Negative test551define i32 @and_select_sub_1_different_op(i1 %a0, i32 inreg %a1, i32 inreg %a2) nounwind {552; X86-LABEL: and_select_sub_1_different_op:553; X86:       # %bb.0:554; X86-NEXT:    pushl %esi555; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx556; X86-NEXT:    andb $1, %cl557; X86-NEXT:    decl %edx558; X86-NEXT:    xorl %esi, %esi559; X86-NEXT:    cmpb $1, %cl560; X86-NEXT:    sbbl %esi, %esi561; X86-NEXT:    orl %edx, %esi562; X86-NEXT:    andl %esi, %eax563; X86-NEXT:    popl %esi564; X86-NEXT:    retl565;566; X64-LABEL: and_select_sub_1_different_op:567; X64:       # %bb.0:568; X64-NEXT:    # kill: def $edx killed $edx def $rdx569; X64-NEXT:    andb $1, %dil570; X64-NEXT:    leal -1(%rdx), %ecx571; X64-NEXT:    xorl %eax, %eax572; X64-NEXT:    cmpb $1, %dil573; X64-NEXT:    sbbl %eax, %eax574; X64-NEXT:    orl %ecx, %eax575; X64-NEXT:    andl %esi, %eax576; X64-NEXT:    retq577  %sub = add i32 %a2, -1578  %bls = select i1 %a0, i32 %sub, i32 -1579  %ret = and i32 %a1, %bls580  ret i32 %ret581}582 583define i32 @xor_select_sub_1_to_blsmsk1(i1 %a0, i32 inreg %a1) nounwind {584; X86-LABEL: xor_select_sub_1_to_blsmsk1:585; X86:       # %bb.0:586; X86-NEXT:    blsmskl %eax, %ecx587; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)588; X86-NEXT:    cmovnel %ecx, %eax589; X86-NEXT:    retl590;591; X64-LABEL: xor_select_sub_1_to_blsmsk1:592; X64:       # %bb.0:593; X64-NEXT:    blsmskl %esi, %eax594; X64-NEXT:    testb $1, %dil595; X64-NEXT:    cmovel %esi, %eax596; X64-NEXT:    retq597  %sub = add i32 %a1, -1598  %bls = select i1 %a0, i32 %sub, i32 0599  %ret = xor i32 %a1, %bls600  ret i32 %ret601}602 603define i32 @xor_select_sub_1_to_blsmsk2(i1 %a0, i32 inreg %a1) nounwind {604; X86-LABEL: xor_select_sub_1_to_blsmsk2:605; X86:       # %bb.0:606; X86-NEXT:    blsmskl %eax, %ecx607; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)608; X86-NEXT:    cmovnel %ecx, %eax609; X86-NEXT:    retl610;611; X64-LABEL: xor_select_sub_1_to_blsmsk2:612; X64:       # %bb.0:613; X64-NEXT:    blsmskl %esi, %eax614; X64-NEXT:    testb $1, %dil615; X64-NEXT:    cmovel %esi, %eax616; X64-NEXT:    retq617  %sub = add i32 %a1, -1618  %bls = select i1 %a0, i32 %sub, i32 0619  %ret = xor i32 %bls, %a1620  ret i32 %ret621}622 623define i32 @xor_select_sub_1_to_blsmsk3(i1 %a0, i32 inreg %a1) nounwind {624; X86-LABEL: xor_select_sub_1_to_blsmsk3:625; X86:       # %bb.0:626; X86-NEXT:    blsmskl %eax, %ecx627; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)628; X86-NEXT:    cmovel %ecx, %eax629; X86-NEXT:    retl630;631; X64-LABEL: xor_select_sub_1_to_blsmsk3:632; X64:       # %bb.0:633; X64-NEXT:    blsmskl %esi, %eax634; X64-NEXT:    testb $1, %dil635; X64-NEXT:    cmovnel %esi, %eax636; X64-NEXT:    retq637  %sub = add i32 %a1, -1638  %bls = select i1 %a0, i32 0, i32 %sub639  %ret = xor i32 %a1, %bls640  ret i32 %ret641}642 643define i32 @xor_select_sub_1_to_blsmsk4(i1 %a0, i32 inreg %a1) nounwind {644; X86-LABEL: xor_select_sub_1_to_blsmsk4:645; X86:       # %bb.0:646; X86-NEXT:    blsmskl %eax, %ecx647; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)648; X86-NEXT:    cmovnel %ecx, %eax649; X86-NEXT:    retl650;651; X64-LABEL: xor_select_sub_1_to_blsmsk4:652; X64:       # %bb.0:653; X64-NEXT:    blsmskl %esi, %eax654; X64-NEXT:    testb $1, %dil655; X64-NEXT:    cmovel %esi, %eax656; X64-NEXT:    retq657  %sub = sub i32 %a1, 1658  %bls = select i1 %a0, i32 %sub, i32 0659  %ret = xor i32 %a1, %bls660  ret i32 %ret661}662 663; The transformation also applies to the following test although we do not emit a BLSMSK instruction664; here because the subtraction instruction is used more than once.665define i32 @xor_sub_1_select_orig(i1 %a0, i32 inreg %a1) nounwind {666; X86-LABEL: xor_sub_1_select_orig:667; X86:       # %bb.0:668; X86-NEXT:    leal -1(%eax), %ecx669; X86-NEXT:    xorl %ecx, %eax670; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)671; X86-NEXT:    cmovel %ecx, %eax672; X86-NEXT:    retl673;674; X64-LABEL: xor_sub_1_select_orig:675; X64:       # %bb.0:676; X64-NEXT:    # kill: def $esi killed $esi def $rsi677; X64-NEXT:    leal -1(%rsi), %eax678; X64-NEXT:    xorl %eax, %esi679; X64-NEXT:    testb $1, %dil680; X64-NEXT:    cmovnel %esi, %eax681; X64-NEXT:    retq682  %sub = add i32 %a1, -1683  %bls = select i1 %a0, i32 %a1, i32 0684  %ret = xor i32 %sub, %bls685  ret i32 %ret686}687 688define i64 @xor_select_sub_1_to_blsmsk_i64(i1 %a0, i64 %a1) nounwind {689; X86-LABEL: xor_select_sub_1_to_blsmsk_i64:690; X86:       # %bb.0:691; X86-NEXT:    pushl %esi692; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx693; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi694; X86-NEXT:    movl %ecx, %eax695; X86-NEXT:    addl $-1, %eax696; X86-NEXT:    movl %esi, %edx697; X86-NEXT:    adcl $-1, %edx698; X86-NEXT:    xorl %esi, %edx699; X86-NEXT:    xorl %ecx, %eax700; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)701; X86-NEXT:    cmovel %ecx, %eax702; X86-NEXT:    cmovel %esi, %edx703; X86-NEXT:    popl %esi704; X86-NEXT:    retl705;706; X64-LABEL: xor_select_sub_1_to_blsmsk_i64:707; X64:       # %bb.0:708; X64-NEXT:    blsmskq %rsi, %rax709; X64-NEXT:    testb $1, %dil710; X64-NEXT:    cmoveq %rsi, %rax711; X64-NEXT:    retq712  %sub = add i64 %a1, -1713  %bls = select i1 %a0, i64 %sub, i64 0714  %ret = xor i64 %a1, %bls715  ret i64 %ret716}717 718; Negative test719define i16 @xor_select_sub_1_i16(i1 %a0, i16 %a1) nounwind {720; X86-LABEL: xor_select_sub_1_i16:721; X86:       # %bb.0:722; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx723; X86-NEXT:    leal -1(%ecx), %edx724; X86-NEXT:    xorl %eax, %eax725; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)726; X86-NEXT:    cmovnel %edx, %eax727; X86-NEXT:    xorl %ecx, %eax728; X86-NEXT:    # kill: def $ax killed $ax killed $eax729; X86-NEXT:    retl730;731; X64-LABEL: xor_select_sub_1_i16:732; X64:       # %bb.0:733; X64-NEXT:    # kill: def $esi killed $esi def $rsi734; X64-NEXT:    leal -1(%rsi), %ecx735; X64-NEXT:    xorl %eax, %eax736; X64-NEXT:    testb $1, %dil737; X64-NEXT:    cmovnel %ecx, %eax738; X64-NEXT:    xorl %esi, %eax739; X64-NEXT:    # kill: def $ax killed $ax killed $eax740; X64-NEXT:    retq741  %sub = add i16 %a1, -1742  %bls = select i1 %a0, i16 %sub, i16 0743  %ret = xor i16 %a1, %bls744  ret i16 %ret745}746 747; Negative test748define <4 x i32> @xor_select_sub_1_v4xi32(i1 %a0, <4 x i32> %a1) nounwind {749; X86-LABEL: xor_select_sub_1_v4xi32:750; X86:       # %bb.0:751; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)752; X86-NEXT:    jne .LBB28_1753; X86-NEXT:  # %bb.2:754; X86-NEXT:    xorps %xmm1, %xmm1755; X86-NEXT:    xorps %xmm1, %xmm0756; X86-NEXT:    retl757; X86-NEXT:  .LBB28_1:758; X86-NEXT:    pcmpeqd %xmm1, %xmm1759; X86-NEXT:    paddd %xmm0, %xmm1760; X86-NEXT:    pxor %xmm1, %xmm0761; X86-NEXT:    retl762;763; X64-LABEL: xor_select_sub_1_v4xi32:764; X64:       # %bb.0:765; X64-NEXT:    testb $1, %dil766; X64-NEXT:    jne .LBB28_1767; X64-NEXT:  # %bb.2:768; X64-NEXT:    xorps %xmm1, %xmm1769; X64-NEXT:    xorps %xmm1, %xmm0770; X64-NEXT:    retq771; X64-NEXT:  .LBB28_1:772; X64-NEXT:    pcmpeqd %xmm1, %xmm1773; X64-NEXT:    paddd %xmm0, %xmm1774; X64-NEXT:    pxor %xmm1, %xmm0775; X64-NEXT:    retq776  %sub = add <4 x i32> %a1, <i32 -1, i32 -1, i32 -1, i32 -1>777  %bls = select i1 %a0, <4 x i32> %sub, <4 x i32> zeroinitializer778  %ret = xor <4 x i32> %a1, %bls779  ret <4 x i32> %ret780}781 782; Negative test783define i32 @xor_select_no_sub_1(i1 %a0, i32 inreg %a1) nounwind {784; X86-LABEL: xor_select_no_sub_1:785; X86:       # %bb.0:786; X86-NEXT:    leal 1(%eax), %ecx787; X86-NEXT:    xorl %edx, %edx788; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)789; X86-NEXT:    cmovnel %ecx, %edx790; X86-NEXT:    xorl %edx, %eax791; X86-NEXT:    retl792;793; X64-LABEL: xor_select_no_sub_1:794; X64:       # %bb.0:795; X64-NEXT:    # kill: def $esi killed $esi def $rsi796; X64-NEXT:    leal 1(%rsi), %ecx797; X64-NEXT:    xorl %eax, %eax798; X64-NEXT:    testb $1, %dil799; X64-NEXT:    cmovnel %ecx, %eax800; X64-NEXT:    xorl %esi, %eax801; X64-NEXT:    retq802  %sub = add i32 %a1, 1803  %bls = select i1 %a0, i32 %sub, i32 0804  %ret = xor i32 %a1, %bls805  ret i32 %ret806}807 808; Negative test809define i32 @xor_select_sub_1_wrong_const(i1 %a0, i32 inreg %a1) nounwind {810; X86-LABEL: xor_select_sub_1_wrong_const:811; X86:       # %bb.0:812; X86-NEXT:    pushl %esi813; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx814; X86-NEXT:    andb $1, %cl815; X86-NEXT:    leal -1(%eax), %edx816; X86-NEXT:    xorl %esi, %esi817; X86-NEXT:    cmpb $1, %cl818; X86-NEXT:    sbbl %esi, %esi819; X86-NEXT:    orl %edx, %esi820; X86-NEXT:    xorl %esi, %eax821; X86-NEXT:    popl %esi822; X86-NEXT:    retl823;824; X64-LABEL: xor_select_sub_1_wrong_const:825; X64:       # %bb.0:826; X64-NEXT:    # kill: def $esi killed $esi def $rsi827; X64-NEXT:    andb $1, %dil828; X64-NEXT:    leal -1(%rsi), %ecx829; X64-NEXT:    xorl %eax, %eax830; X64-NEXT:    cmpb $1, %dil831; X64-NEXT:    sbbl %eax, %eax832; X64-NEXT:    orl %ecx, %eax833; X64-NEXT:    xorl %esi, %eax834; X64-NEXT:    retq835  %sub = add i32 %a1, -1836  %bls = select i1 %a0, i32 %sub, i32 -1837  %ret = xor i32 %a1, %bls838  ret i32 %ret839}840 841; Negative test842define i32 @xor_select_sub_1_different_op(i1 %a0, i32 inreg %a1, i32 inreg %a2) nounwind {843; X86-LABEL: xor_select_sub_1_different_op:844; X86:       # %bb.0:845; X86-NEXT:    leal -1(%edx), %ecx846; X86-NEXT:    xorl %edx, %edx847; X86-NEXT:    testb $1, {{[0-9]+}}(%esp)848; X86-NEXT:    cmovnel %ecx, %edx849; X86-NEXT:    xorl %edx, %eax850; X86-NEXT:    retl851;852; X64-LABEL: xor_select_sub_1_different_op:853; X64:       # %bb.0:854; X64-NEXT:    # kill: def $edx killed $edx def $rdx855; X64-NEXT:    leal -1(%rdx), %ecx856; X64-NEXT:    xorl %eax, %eax857; X64-NEXT:    testb $1, %dil858; X64-NEXT:    cmovnel %ecx, %eax859; X64-NEXT:    xorl %esi, %eax860; X64-NEXT:    retq861  %sub = add i32 %a2, -1862  %bls = select i1 %a0, i32 %sub, i32 0863  %ret = xor i32 %a1, %bls864  ret i32 %ret865}866