[llvm] 466503d - X86: Add pattern for optimized BLSIC IR form (#209814)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 14:07:17 PDT 2026


Author: Logan
Date: 2026-07-17T22:07:12+01:00
New Revision: 466503dcf2ae2e43126c1a6d8a5b204883d5b0c1

URL: https://github.com/llvm/llvm-project/commit/466503dcf2ae2e43126c1a6d8a5b204883d5b0c1
DIFF: https://github.com/llvm/llvm-project/commit/466503dcf2ae2e43126c1a6d8a5b204883d5b0c1.diff

LOG: X86: Add pattern for optimized BLSIC IR form (#209814)

Add DAG pattern to recognize the optimized IR form of BLSIC: (xor (and
x, -x), -1)

Fixes #209718 - matches the IR form produced after InstCombine
optimizations

Added tests for both 32-bit and 64-bit BLSIC patterns

Assisted by: Claude Code, helped me understand
pattern-matching/intrinsics, and some file structure. As well as how
testing for LLVM works.

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86InstrTBM.td
    llvm/test/CodeGen/X86/tbm_patterns.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86InstrTBM.td b/llvm/lib/Target/X86/X86InstrTBM.td
index 09200f0c1a9f6..af07c3d90563a 100644
--- a/llvm/lib/Target/X86/X86InstrTBM.td
+++ b/llvm/lib/Target/X86/X86InstrTBM.td
@@ -125,6 +125,11 @@ let Predicates = [HasTBM] in {
   def : Pat<(or GR64:$src, (add GR64:$src, -1)),
             (BLSFILL64rr GR64:$src)>;
 
+  def : Pat<(xor (and GR32:$src, (ineg GR32:$src)), -1),
+            (BLSIC32rr GR32:$src)>;
+  def : Pat<(xor (and GR64:$src, (ineg GR64:$src)), -1),
+            (BLSIC64rr GR64:$src)>;
+
   def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
             (BLSIC32rr GR32:$src)>;
   def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),

diff  --git a/llvm/test/CodeGen/X86/tbm_patterns.ll b/llvm/test/CodeGen/X86/tbm_patterns.ll
index e595803efdfca..291ae23155ad3 100644
--- a/llvm/test/CodeGen/X86/tbm_patterns.ll
+++ b/llvm/test/CodeGen/X86/tbm_patterns.ll
@@ -810,6 +810,17 @@ define i32 @test_x86_tbm_blsic_u32(i32 %a) nounwind {
   ret i32 %t2
 }
 
+define i32 @test_x86_tbm_blsic_u32_neg(i32 %x) nounwind{
+; CHECK-LABEL: test_x86_tbm_blsic_u32_neg:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    blsicl %edi, %eax
+; CHECK-NEXT:    retq
+  %1 = sub i32 0, %x
+  %2 = and i32 %x, %1
+  %3 = xor i32 %2, -1
+  ret i32 %3
+}
+
 define i32 @test_x86_tbm_blsic_u32_z(i32 %a, i32 %b) nounwind {
 ; CHECK-LABEL: test_x86_tbm_blsic_u32_z:
 ; CHECK:       # %bb.0:
@@ -865,6 +876,17 @@ define i64 @test_x86_tbm_blsic_u64(i64 %a) nounwind {
   ret i64 %t2
 }
 
+define i64 @test_x86_tbm_blsic_u64_neg(i64 %x) nounwind{
+; CHECK-LABEL: test_x86_tbm_blsic_u64_neg:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    blsicq %rdi, %rax
+; CHECK-NEXT:    retq
+  %1 = sub i64 0, %x
+  %2 = and i64 %x, %1
+  %3 = xor i64 %2, -1
+  ret i64 %3
+}
+
 define i64 @test_x86_tbm_blsic_u64_z(i64 %a, i64 %b) nounwind {
 ; CHECK-LABEL: test_x86_tbm_blsic_u64_z:
 ; CHECK:       # %bb.0:
@@ -1169,10 +1191,10 @@ define i32 @blcic32_branch(i32 %x) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    blcicl %edi, %ebx
-; CHECK-NEXT:    jne .LBB89_2
+; CHECK-NEXT:    jne .LBB91_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    callq bar at PLT
-; CHECK-NEXT:  .LBB89_2:
+; CHECK-NEXT:  .LBB91_2:
 ; CHECK-NEXT:    movl %ebx, %eax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    retq
@@ -1192,10 +1214,10 @@ define i64 @blcic64_branch(i64 %x) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    blcicq %rdi, %rbx
-; CHECK-NEXT:    jne .LBB90_2
+; CHECK-NEXT:    jne .LBB92_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    callq bar at PLT
-; CHECK-NEXT:  .LBB90_2:
+; CHECK-NEXT:  .LBB92_2:
 ; CHECK-NEXT:    movq %rbx, %rax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    retq
@@ -1215,10 +1237,10 @@ define i32 @tzmsk32_branch(i32 %x) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    tzmskl %edi, %ebx
-; CHECK-NEXT:    jne .LBB91_2
+; CHECK-NEXT:    jne .LBB93_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    callq bar at PLT
-; CHECK-NEXT:  .LBB91_2:
+; CHECK-NEXT:  .LBB93_2:
 ; CHECK-NEXT:    movl %ebx, %eax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    retq
@@ -1238,10 +1260,10 @@ define i64 @tzmsk64_branch(i64 %x) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    tzmskq %rdi, %rbx
-; CHECK-NEXT:    jne .LBB92_2
+; CHECK-NEXT:    jne .LBB94_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    callq bar at PLT
-; CHECK-NEXT:  .LBB92_2:
+; CHECK-NEXT:  .LBB94_2:
 ; CHECK-NEXT:    movq %rbx, %rax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    retq
@@ -1261,10 +1283,10 @@ define i32 @blcfill32_branch(i32 %x) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    blcfilll %edi, %ebx
-; CHECK-NEXT:    jne .LBB93_2
+; CHECK-NEXT:    jne .LBB95_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    callq bar at PLT
-; CHECK-NEXT:  .LBB93_2:
+; CHECK-NEXT:  .LBB95_2:
 ; CHECK-NEXT:    movl %ebx, %eax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    retq
@@ -1283,10 +1305,10 @@ define i64 @blcfill64_branch(i64 %x) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    pushq %rbx
 ; CHECK-NEXT:    blcfillq %rdi, %rbx
-; CHECK-NEXT:    jne .LBB94_2
+; CHECK-NEXT:    jne .LBB96_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    callq bar at PLT
-; CHECK-NEXT:  .LBB94_2:
+; CHECK-NEXT:  .LBB96_2:
 ; CHECK-NEXT:    movq %rbx, %rax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    retq


        


More information about the llvm-commits mailing list