[llvm] r352306 - [X86] Add some missing blsr patterns

Gabor Buella via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 26 22:15:39 PST 2019


Author: gbuella
Date: Sat Jan 26 22:15:39 2019
New Revision: 352306

URL: http://llvm.org/viewvc/llvm-project?rev=352306&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/test/CodeGen/X86/bmi.ll

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=352306&r1=352305&r2=352306&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Sat Jan 26 22:15:39 2019
@@ -2387,6 +2387,11 @@ def xor_flag_nocf : PatFrag<(ops node:$l
   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,

Modified: llvm/trunk/test/CodeGen/X86/bmi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bmi.ll?rev=352306&r1=352305&r2=352306&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/bmi.ll (original)
+++ llvm/trunk/test/CodeGen/X86/bmi.ll Sat Jan 26 22:15:39 2019
@@ -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




More information about the llvm-commits mailing list