forked from OSchip/llvm-project
[X86] Add some missing blsr patterns
The add+and sequence followed by a branch can happen e.g. when looping over the set bits of an integer: ``` while (x != 0) { func(x & ~x); x &= x - 1; } ``` Reviewed By: ctopper Differential Revision: https://reviews.llvm.org/D57296 llvm-svn: 352306
This commit is contained in:
parent
23b04798ad
commit
a0f743b77a
|
@ -2387,6 +2387,11 @@ def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
|
|||
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 @@ let Predicates = [HasBMI] in {
|
|||
(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<bits<8> opc, string mnemonic, RegisterClass RC,
|
||||
|
|
|
@ -1059,9 +1059,7 @@ define i32 @blsr32_branch(i32 %x) {
|
|||
; 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 @@ define i32 @blsr32_branch(i32 %x) {
|
|||
; 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 @@ define i64 @blsr64_branch(i64 %x) {
|
|||
; 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
|
||||
|
|
Loading…
Reference in New Issue