Index: llvm/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/lib/Target/X86/X86InstrInfo.td +++ llvm/lib/Target/X86/X86InstrInfo.td @@ -2387,6 +2387,11 @@ return hasNoCarryFlagUses(SDValue(N, 1)); }]>; +def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), + (X86and_flag node:$lhs, node:$rhs), [{ + return hasNoCarryFlagUses(SDValue(N, 1)); +}]>; + let Predicates = [HasBMI] in { // FIXME: patterns for the load versions are not implemented def : Pat<(and GR32:$src, (add GR32:$src, -1)), @@ -2405,12 +2410,15 @@ (BLSI64rr GR64:$src)>; // Versions to match flag producing ops. - // X86and_flag nodes are rarely created. Those should use CMP+AND. We do - // TESTrr matching in PostProcessISelDAG to allow BLSR/BLSI to be formed. def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, -1)), (BLSMSK32rr GR32:$src)>; def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, -1)), (BLSMSK64rr GR64:$src)>; + + def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, -1)), + (BLSR32rr GR32:$src)>; + def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, -1)), + (BLSR64rr GR64:$src)>; } multiclass bmi_bextr opc, string mnemonic, RegisterClass RC, Index: llvm/test/CodeGen/X86/bmi.ll =================================================================== --- llvm/test/CodeGen/X86/bmi.ll +++ llvm/test/CodeGen/X86/bmi.ll @@ -1059,9 +1059,7 @@ ; X86-NEXT: pushl %esi ; X86-NEXT: .cfi_def_cfa_offset 8 ; X86-NEXT: .cfi_offset %esi, -8 -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: leal -1(%eax), %esi -; X86-NEXT: andl %eax, %esi +; X86-NEXT: blsrl {{[0-9]+}}(%esp), %esi ; X86-NEXT: jne .LBB46_2 ; X86-NEXT: # %bb.1: ; X86-NEXT: calll bar @@ -1076,9 +1074,7 @@ ; X64-NEXT: pushq %rbx ; X64-NEXT: .cfi_def_cfa_offset 16 ; X64-NEXT: .cfi_offset %rbx, -16 -; X64-NEXT: # kill: def $edi killed $edi def $rdi -; X64-NEXT: leal -1(%rdi), %ebx -; X64-NEXT: andl %edi, %ebx +; X64-NEXT: blsrl %edi, %ebx ; X64-NEXT: jne .LBB46_2 ; X64-NEXT: # %bb.1: ; X64-NEXT: callq bar @@ -1133,8 +1129,7 @@ ; X64-NEXT: pushq %rbx ; X64-NEXT: .cfi_def_cfa_offset 16 ; X64-NEXT: .cfi_offset %rbx, -16 -; X64-NEXT: leaq -1(%rdi), %rbx -; X64-NEXT: andq %rdi, %rbx +; X64-NEXT: blsrq %rdi, %rbx ; X64-NEXT: jne .LBB47_2 ; X64-NEXT: # %bb.1: ; X64-NEXT: callq bar