[llvm] [X86] Select ANDN for i8 operands (PR #205050)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 22 01:02:29 PDT 2026


https://github.com/mygitljf created https://github.com/llvm/llvm-project/pull/205050

Added selection support so BMI ANDN can be used for i8 integer operands by widening through the available 32-bit instruction form and keeping the low byte result.
I also updated the affected X86 CodeGen checks and added direct coverage for the i8 case. 
Fixes #204985

>From 2a558b4336aab669c831afce177e01003854fb5c Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Mon, 22 Jun 2026 15:59:24 +0000
Subject: [PATCH] [X86] Select ANDN for i8 operands

---
 llvm/lib/Target/X86/X86InstrArithmetic.td     |   8 +
 llvm/test/CodeGen/X86/andnot-patterns.ll      | 113 +++--
 llvm/test/CodeGen/X86/andnot-sink-not.ll      | 414 ++++++++++--------
 .../test/CodeGen/X86/avx512-mask-bit-manip.ll |  12 +-
 llvm/test/CodeGen/X86/bmi.ll                  |  34 +-
 llvm/test/CodeGen/X86/pr108731.ll             |  33 +-
 llvm/test/CodeGen/X86/setcc-logic.ll          |  19 +-
 7 files changed, 385 insertions(+), 248 deletions(-)

diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index c91600525d1eb..2276c736f0190 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -1394,6 +1394,14 @@ defm ANDN64 : AndN<Xi64, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode
 }
 
 multiclass Andn_Pats<string suffix> {
+  // ANDN has only GR32/GR64 forms; widen i8 inputs to i32 and extract the low
+  // byte. Upper bits are ignored by the result extraction.
+  def : Pat<(and (not GR8:$src1), GR8:$src2),
+            (EXTRACT_SUBREG
+              (!cast<Instruction>(ANDN32rr#suffix)
+                (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src1, sub_8bit),
+                (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit)),
+              sub_8bit)>;
   def : Pat<(and (not GR32:$src1), GR32:$src2),
             (!cast<Instruction>(ANDN32rr#suffix) GR32:$src1, GR32:$src2)>;
   def : Pat<(and (not GR64:$src1), GR64:$src2),
diff --git a/llvm/test/CodeGen/X86/andnot-patterns.ll b/llvm/test/CodeGen/X86/andnot-patterns.ll
index fc573fbd4fc99..df6e6ffbb6394 100644
--- a/llvm/test/CodeGen/X86/andnot-patterns.ll
+++ b/llvm/test/CodeGen/X86/andnot-patterns.ll
@@ -174,16 +174,25 @@ define i8 @andnot_rotl_i8(i8 %a0, i8 %a1, i8 %a2) nounwind {
 ; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
 ; X86-NEXT:    retl
 ;
-; X64-LABEL: andnot_rotl_i8:
-; X64:       # %bb.0:
-; X64-NEXT:    movl %edx, %ecx
-; X64-NEXT:    movl %esi, %eax
-; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; X64-NEXT:    rolb %cl, %al
-; X64-NEXT:    notb %al
-; X64-NEXT:    andb %dil, %al
-; X64-NEXT:    # kill: def $al killed $al killed $eax
-; X64-NEXT:    retq
+; X64-NOBMI-LABEL: andnot_rotl_i8:
+; X64-NOBMI:       # %bb.0:
+; X64-NOBMI-NEXT:    movl %edx, %ecx
+; X64-NOBMI-NEXT:    movl %esi, %eax
+; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI-NEXT:    rolb %cl, %al
+; X64-NOBMI-NEXT:    notb %al
+; X64-NOBMI-NEXT:    andb %dil, %al
+; X64-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
+; X64-NOBMI-NEXT:    retq
+;
+; X64-BMI-LABEL: andnot_rotl_i8:
+; X64-BMI:       # %bb.0:
+; X64-BMI-NEXT:    movl %edx, %ecx
+; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
+; X64-BMI-NEXT:    rolb %cl, %sil
+; X64-BMI-NEXT:    andnl %edi, %esi, %eax
+; X64-BMI-NEXT:    # kill: def $al killed $al killed $eax
+; X64-BMI-NEXT:    retq
   %not = xor i8 %a1, -1
   %rot = tail call i8 @llvm.fshl.i8(i8 %not, i8 %not, i8 %a2)
   %and = and i8 %rot, %a0
@@ -415,16 +424,25 @@ define i8 @andnot_rotr_i8(i8 %a0, i8 %a1, i8 %a2) nounwind {
 ; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
 ; X86-NEXT:    retl
 ;
-; X64-LABEL: andnot_rotr_i8:
-; X64:       # %bb.0:
-; X64-NEXT:    movl %edx, %ecx
-; X64-NEXT:    movl %esi, %eax
-; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
-; X64-NEXT:    rorb %cl, %al
-; X64-NEXT:    notb %al
-; X64-NEXT:    andb %dil, %al
-; X64-NEXT:    # kill: def $al killed $al killed $eax
-; X64-NEXT:    retq
+; X64-NOBMI-LABEL: andnot_rotr_i8:
+; X64-NOBMI:       # %bb.0:
+; X64-NOBMI-NEXT:    movl %edx, %ecx
+; X64-NOBMI-NEXT:    movl %esi, %eax
+; X64-NOBMI-NEXT:    # kill: def $cl killed $cl killed $ecx
+; X64-NOBMI-NEXT:    rorb %cl, %al
+; X64-NOBMI-NEXT:    notb %al
+; X64-NOBMI-NEXT:    andb %dil, %al
+; X64-NOBMI-NEXT:    # kill: def $al killed $al killed $eax
+; X64-NOBMI-NEXT:    retq
+;
+; X64-BMI-LABEL: andnot_rotr_i8:
+; X64-BMI:       # %bb.0:
+; X64-BMI-NEXT:    movl %edx, %ecx
+; X64-BMI-NEXT:    # kill: def $cl killed $cl killed $ecx
+; X64-BMI-NEXT:    rorb %cl, %sil
+; X64-BMI-NEXT:    andnl %edi, %esi, %eax
+; X64-BMI-NEXT:    # kill: def $al killed $al killed $eax
+; X64-BMI-NEXT:    retq
   %not = xor i8 %a1, -1
   %rot = tail call i8 @llvm.fshr.i8(i8 %not, i8 %not, i8 %a2)
   %and = and i8 %rot, %a0
@@ -1058,24 +1076,43 @@ define i8 @andnot_bitreverse_i8(i8 %a0, i8 %a1) nounwind {
 ; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
 ; X86-NEXT:    retl
 ;
-; X64-LABEL: andnot_bitreverse_i8:
-; X64:       # %bb.0:
-; X64-NEXT:    rolb $4, %sil
-; X64-NEXT:    movl %esi, %eax
-; X64-NEXT:    andb $51, %al
-; X64-NEXT:    shlb $2, %al
-; X64-NEXT:    shrb $2, %sil
-; X64-NEXT:    andb $51, %sil
-; X64-NEXT:    orb %sil, %al
-; X64-NEXT:    movl %eax, %ecx
-; X64-NEXT:    andb $85, %cl
-; X64-NEXT:    addb %cl, %cl
-; X64-NEXT:    shrb %al
-; X64-NEXT:    andb $85, %al
-; X64-NEXT:    orb %cl, %al
-; X64-NEXT:    notb %al
-; X64-NEXT:    andb %dil, %al
-; X64-NEXT:    retq
+; X64-NOBMI-LABEL: andnot_bitreverse_i8:
+; X64-NOBMI:       # %bb.0:
+; X64-NOBMI-NEXT:    rolb $4, %sil
+; X64-NOBMI-NEXT:    movl %esi, %eax
+; X64-NOBMI-NEXT:    andb $51, %al
+; X64-NOBMI-NEXT:    shlb $2, %al
+; X64-NOBMI-NEXT:    shrb $2, %sil
+; X64-NOBMI-NEXT:    andb $51, %sil
+; X64-NOBMI-NEXT:    orb %sil, %al
+; X64-NOBMI-NEXT:    movl %eax, %ecx
+; X64-NOBMI-NEXT:    andb $85, %cl
+; X64-NOBMI-NEXT:    addb %cl, %cl
+; X64-NOBMI-NEXT:    shrb %al
+; X64-NOBMI-NEXT:    andb $85, %al
+; X64-NOBMI-NEXT:    orb %cl, %al
+; X64-NOBMI-NEXT:    notb %al
+; X64-NOBMI-NEXT:    andb %dil, %al
+; X64-NOBMI-NEXT:    retq
+;
+; X64-BMI-LABEL: andnot_bitreverse_i8:
+; X64-BMI:       # %bb.0:
+; X64-BMI-NEXT:    rolb $4, %sil
+; X64-BMI-NEXT:    movl %esi, %eax
+; X64-BMI-NEXT:    andb $51, %al
+; X64-BMI-NEXT:    shlb $2, %al
+; X64-BMI-NEXT:    shrb $2, %sil
+; X64-BMI-NEXT:    andb $51, %sil
+; X64-BMI-NEXT:    orb %al, %sil
+; X64-BMI-NEXT:    movl %esi, %eax
+; X64-BMI-NEXT:    andb $85, %al
+; X64-BMI-NEXT:    addb %al, %al
+; X64-BMI-NEXT:    shrb %sil
+; X64-BMI-NEXT:    andb $85, %sil
+; X64-BMI-NEXT:    orb %al, %sil
+; X64-BMI-NEXT:    andnl %edi, %esi, %eax
+; X64-BMI-NEXT:    # kill: def $al killed $al killed $eax
+; X64-BMI-NEXT:    retq
   %not = xor i8 %a1, -1
   %bitrev = tail call i8 @llvm.bitreverse.i8(i8 %not)
   %and = and i8 %bitrev, %a0
diff --git a/llvm/test/CodeGen/X86/andnot-sink-not.ll b/llvm/test/CodeGen/X86/andnot-sink-not.ll
index fefbdc84699f4..ad9c161cc79e1 100644
--- a/llvm/test/CodeGen/X86/andnot-sink-not.ll
+++ b/llvm/test/CodeGen/X86/andnot-sink-not.ll
@@ -621,66 +621,81 @@ define <8 x i8> @and_sink_not_v8i8(<8 x i8> %x, <8 x i8> %m, i1 zeroext %cond) n
 ;
 ; X86-BMI-LABEL: and_sink_not_v8i8:
 ; X86-BMI:       # %bb.0:
+; X86-BMI-NEXT:    pushl %ebp
 ; X86-BMI-NEXT:    pushl %ebx
+; X86-BMI-NEXT:    pushl %edi
 ; X86-BMI-NEXT:    pushl %esi
-; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ah
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %al
+; X86-BMI-NEXT:    subl $12, %esp
+; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %ebp
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %edi
 ; X86-BMI-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
 ; X86-BMI-NEXT:    je .LBB8_2
 ; X86-BMI-NEXT:  # %bb.1: # %mask
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
-; X86-BMI-NEXT:    notb %cl
-; X86-BMI-NEXT:    andb %dh, %cl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
-; X86-BMI-NEXT:    notb %dh
-; X86-BMI-NEXT:    andb %ch, %dh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %dl, %ch
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
-; X86-BMI-NEXT:    notb %dl
-; X86-BMI-NEXT:    andb %bh, %dl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bh
-; X86-BMI-NEXT:    notb %bh
-; X86-BMI-NEXT:    andb %bl, %bh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bl
-; X86-BMI-NEXT:    notb %bl
-; X86-BMI-NEXT:    andb {{[0-9]+}}(%esp), %bl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %al
-; X86-BMI-NEXT:    notb %al
-; X86-BMI-NEXT:    andb %ah, %al
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ah
-; X86-BMI-NEXT:    notb %ah
-; X86-BMI-NEXT:    andb {{[0-9]+}}(%esp), %ah
-; X86-BMI-NEXT:    movb %ah, (%esi)
-; X86-BMI-NEXT:    movb %al, 1(%esi)
-; X86-BMI-NEXT:    movb %bl, 2(%esi)
-; X86-BMI-NEXT:    movb %bh, 3(%esi)
-; X86-BMI-NEXT:    movb %dl, 4(%esi)
-; X86-BMI-NEXT:    movb %ch, 5(%esi)
-; X86-BMI-NEXT:    movb %dh, 6(%esi)
-; X86-BMI-NEXT:    movb %cl, 7(%esi)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ebx, %ecx, %ecx
+; X86-BMI-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %ecx
+; X86-BMI-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ebp, %ecx, %ecx
+; X86-BMI-NEXT:    movl %ecx, (%esp) # 4-byte Spill
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %edi, %ecx, %ebp
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %esi, %ecx, %edi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ecx, %ebx, %ebx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ecx, %edx, %edx
+; X86-BMI-NEXT:    movb %dl, (%eax)
+; X86-BMI-NEXT:    movb %bl, 1(%eax)
+; X86-BMI-NEXT:    movl %esi, %ecx
+; X86-BMI-NEXT:    movb %cl, 2(%eax)
+; X86-BMI-NEXT:    movl %edi, %ecx
+; X86-BMI-NEXT:    movb %cl, 3(%eax)
+; X86-BMI-NEXT:    movl %ebp, %ecx
+; X86-BMI-NEXT:    movb %cl, 4(%eax)
+; X86-BMI-NEXT:    movl (%esp), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 5(%eax)
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 6(%eax)
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 7(%eax)
 ; X86-BMI-NEXT:    jmp .LBB8_3
 ; X86-BMI-NEXT:  .LBB8_2: # %identity
-; X86-BMI-NEXT:    movb %al, (%esi)
-; X86-BMI-NEXT:    movb %ah, 1(%esi)
-; X86-BMI-NEXT:    movb %cl, 2(%esi)
-; X86-BMI-NEXT:    movb %bl, 3(%esi)
-; X86-BMI-NEXT:    movb %bh, 4(%esi)
-; X86-BMI-NEXT:    movb %dl, 5(%esi)
-; X86-BMI-NEXT:    movb %ch, 6(%esi)
-; X86-BMI-NEXT:    movb %dh, 7(%esi)
+; X86-BMI-NEXT:    movb %cl, (%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movb %cl, 1(%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movb %cl, 2(%eax)
+; X86-BMI-NEXT:    movl %esi, %ecx
+; X86-BMI-NEXT:    movb %cl, 3(%eax)
+; X86-BMI-NEXT:    movl %edi, %ecx
+; X86-BMI-NEXT:    movb %cl, 4(%eax)
+; X86-BMI-NEXT:    movl %ebp, %ecx
+; X86-BMI-NEXT:    movb %cl, 5(%eax)
+; X86-BMI-NEXT:    movb %dl, 6(%eax)
+; X86-BMI-NEXT:    movb %bl, 7(%eax)
 ; X86-BMI-NEXT:  .LBB8_3: # %identity
-; X86-BMI-NEXT:    movl %esi, %eax
+; X86-BMI-NEXT:    addl $12, %esp
 ; X86-BMI-NEXT:    popl %esi
+; X86-BMI-NEXT:    popl %edi
 ; X86-BMI-NEXT:    popl %ebx
+; X86-BMI-NEXT:    popl %ebp
 ; X86-BMI-NEXT:    retl $4
 ;
 ; X64-NOAVX2-LABEL: and_sink_not_v8i8:
@@ -869,74 +884,81 @@ define <8 x i8> @and_sink_not_v8i8_swapped(<8 x i8> %x, <8 x i8> %m, i1 zeroext
 ;
 ; X86-BMI-LABEL: and_sink_not_v8i8_swapped:
 ; X86-BMI:       # %bb.0:
+; X86-BMI-NEXT:    pushl %ebp
 ; X86-BMI-NEXT:    pushl %ebx
+; X86-BMI-NEXT:    pushl %edi
 ; X86-BMI-NEXT:    pushl %esi
-; X86-BMI-NEXT:    pushl %eax
-; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
+; X86-BMI-NEXT:    subl $12, %esp
+; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
 ; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %ebp
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %edi
 ; X86-BMI-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
 ; X86-BMI-NEXT:    je .LBB9_2
 ; X86-BMI-NEXT:  # %bb.1: # %mask
-; X86-BMI-NEXT:    movb %ch, %dh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %dh
-; X86-BMI-NEXT:    movb %dh, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ah
-; X86-BMI-NEXT:    andb %ch, %ah
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %al
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %bl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %bh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %cl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %dl
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
-; X86-BMI-NEXT:    andb %ch, %dh
-; X86-BMI-NEXT:    movb %dh, (%esi)
-; X86-BMI-NEXT:    movb %dl, 1(%esi)
-; X86-BMI-NEXT:    movb %cl, 2(%esi)
-; X86-BMI-NEXT:    movb %bh, 3(%esi)
-; X86-BMI-NEXT:    movb %bl, 4(%esi)
-; X86-BMI-NEXT:    movb %al, 5(%esi)
-; X86-BMI-NEXT:    movb %ah, 6(%esi)
-; X86-BMI-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload
-; X86-BMI-NEXT:    movb %cl, 7(%esi)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ebx, %ecx, %ecx
+; X86-BMI-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %ecx
+; X86-BMI-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ebp, %ecx, %ecx
+; X86-BMI-NEXT:    movl %ecx, (%esp) # 4-byte Spill
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %edi, %ecx, %ebp
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %esi, %ecx, %edi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ecx, %ebx, %ebx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ecx, %edx, %edx
+; X86-BMI-NEXT:    movb %dl, (%eax)
+; X86-BMI-NEXT:    movb %bl, 1(%eax)
+; X86-BMI-NEXT:    movl %esi, %ecx
+; X86-BMI-NEXT:    movb %cl, 2(%eax)
+; X86-BMI-NEXT:    movl %edi, %ecx
+; X86-BMI-NEXT:    movb %cl, 3(%eax)
+; X86-BMI-NEXT:    movl %ebp, %ecx
+; X86-BMI-NEXT:    movb %cl, 4(%eax)
+; X86-BMI-NEXT:    movl (%esp), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 5(%eax)
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 6(%eax)
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 7(%eax)
 ; X86-BMI-NEXT:    jmp .LBB9_3
 ; X86-BMI-NEXT:  .LBB9_2: # %identity
-; X86-BMI-NEXT:    movb %dh, (%esi)
-; X86-BMI-NEXT:    movb %dl, 1(%esi)
-; X86-BMI-NEXT:    movb %cl, 2(%esi)
-; X86-BMI-NEXT:    movb %bh, 3(%esi)
-; X86-BMI-NEXT:    movb %bl, 4(%esi)
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
-; X86-BMI-NEXT:    movb %cl, 5(%esi)
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
-; X86-BMI-NEXT:    movb %cl, 6(%esi)
-; X86-BMI-NEXT:    movb %ch, 7(%esi)
+; X86-BMI-NEXT:    movb %cl, (%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movb %cl, 1(%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movb %cl, 2(%eax)
+; X86-BMI-NEXT:    movl %esi, %ecx
+; X86-BMI-NEXT:    movb %cl, 3(%eax)
+; X86-BMI-NEXT:    movl %edi, %ecx
+; X86-BMI-NEXT:    movb %cl, 4(%eax)
+; X86-BMI-NEXT:    movl %ebp, %ecx
+; X86-BMI-NEXT:    movb %cl, 5(%eax)
+; X86-BMI-NEXT:    movb %dl, 6(%eax)
+; X86-BMI-NEXT:    movb %bl, 7(%eax)
 ; X86-BMI-NEXT:  .LBB9_3: # %identity
-; X86-BMI-NEXT:    movl %esi, %eax
-; X86-BMI-NEXT:    addl $4, %esp
+; X86-BMI-NEXT:    addl $12, %esp
 ; X86-BMI-NEXT:    popl %esi
+; X86-BMI-NEXT:    popl %edi
 ; X86-BMI-NEXT:    popl %ebx
+; X86-BMI-NEXT:    popl %ebp
 ; X86-BMI-NEXT:    retl $4
 ;
 ; X64-NOAVX2-LABEL: and_sink_not_v8i8_swapped:
@@ -1995,58 +2017,75 @@ define <8 x i8> @and_sink_not_splat_v8i8(<8 x i8> %x, i8 %m, i1 zeroext %cond) n
 ;
 ; X86-BMI-LABEL: and_sink_not_splat_v8i8:
 ; X86-BMI:       # %bb.0:
+; X86-BMI-NEXT:    pushl %ebp
 ; X86-BMI-NEXT:    pushl %ebx
-; X86-BMI-NEXT:    pushl %eax
+; X86-BMI-NEXT:    pushl %edi
+; X86-BMI-NEXT:    pushl %esi
+; X86-BMI-NEXT:    subl $12, %esp
 ; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
 ; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bh
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %cl
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movl %edx, %edi
 ; X86-BMI-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movl %edx, %ebp
 ; X86-BMI-NEXT:    je .LBB14_2
 ; X86-BMI-NEXT:  # %bb.1: # %mask
-; X86-BMI-NEXT:    movb %dl, %ch
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
-; X86-BMI-NEXT:    notb %dl
-; X86-BMI-NEXT:    andb %dl, %ch
-; X86-BMI-NEXT:    movb %ch, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    andb %dl, %ch
-; X86-BMI-NEXT:    movb %ch, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    andb %dl, %ch
-; X86-BMI-NEXT:    andb %dl, %dh
-; X86-BMI-NEXT:    andb %dl, %bl
-; X86-BMI-NEXT:    andb %dl, %bh
-; X86-BMI-NEXT:    andb %dl, %cl
-; X86-BMI-NEXT:    andb {{[0-9]+}}(%esp), %dl
-; X86-BMI-NEXT:    movb %dl, 1(%eax)
+; X86-BMI-NEXT:    movl %ecx, %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ebx, %ecx, %ebx
+; X86-BMI-NEXT:    movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    andnl %esi, %ecx, %esi
+; X86-BMI-NEXT:    movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    andnl %edx, %ecx, %edx
+; X86-BMI-NEXT:    movl %edx, (%esp) # 4-byte Spill
+; X86-BMI-NEXT:    andnl %edi, %ecx, %edi
+; X86-BMI-NEXT:    andnl %ebp, %ecx, %ebp
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
+; X86-BMI-NEXT:    andnl %ebx, %ecx, %ecx
 ; X86-BMI-NEXT:    movb %cl, (%eax)
-; X86-BMI-NEXT:    movb %bh, 2(%eax)
-; X86-BMI-NEXT:    movb %bl, 3(%eax)
-; X86-BMI-NEXT:    movb %dh, 4(%eax)
-; X86-BMI-NEXT:    movb %ch, 5(%eax)
-; X86-BMI-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload
+; X86-BMI-NEXT:    movb %dl, 1(%eax)
+; X86-BMI-NEXT:    movl %esi, %ecx
+; X86-BMI-NEXT:    movb %cl, 2(%eax)
+; X86-BMI-NEXT:    movl %ebp, %ecx
+; X86-BMI-NEXT:    movb %cl, 3(%eax)
+; X86-BMI-NEXT:    movl %edi, %ecx
+; X86-BMI-NEXT:    movb %cl, 4(%eax)
+; X86-BMI-NEXT:    movl (%esp), %ecx # 4-byte Reload
+; X86-BMI-NEXT:    movb %cl, 5(%eax)
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
 ; X86-BMI-NEXT:    movb %cl, 6(%eax)
-; X86-BMI-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
 ; X86-BMI-NEXT:    movb %cl, 7(%eax)
 ; X86-BMI-NEXT:    jmp .LBB14_3
 ; X86-BMI-NEXT:  .LBB14_2: # %identity
-; X86-BMI-NEXT:    movb %cl, (%eax)
-; X86-BMI-NEXT:    movb %ch, 1(%eax)
-; X86-BMI-NEXT:    movb %bh, 2(%eax)
-; X86-BMI-NEXT:    movb %bl, 3(%eax)
-; X86-BMI-NEXT:    movb %dh, 4(%eax)
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movb %dl, (%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movb %dl, 1(%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movb %dl, 2(%eax)
+; X86-BMI-NEXT:    movl %ebp, %edx
+; X86-BMI-NEXT:    movb %dl, 3(%eax)
+; X86-BMI-NEXT:    movl %edi, %edx
+; X86-BMI-NEXT:    movb %dl, 4(%eax)
 ; X86-BMI-NEXT:    movb %cl, 5(%eax)
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %esi, %ecx
 ; X86-BMI-NEXT:    movb %cl, 6(%eax)
-; X86-BMI-NEXT:    movb %dl, 7(%eax)
+; X86-BMI-NEXT:    movb %bl, 7(%eax)
 ; X86-BMI-NEXT:  .LBB14_3: # %identity
-; X86-BMI-NEXT:    addl $4, %esp
+; X86-BMI-NEXT:    addl $12, %esp
+; X86-BMI-NEXT:    popl %esi
+; X86-BMI-NEXT:    popl %edi
 ; X86-BMI-NEXT:    popl %ebx
+; X86-BMI-NEXT:    popl %ebp
 ; X86-BMI-NEXT:    retl $4
 ;
 ; X64-NOAVX2-LABEL: and_sink_not_splat_v8i8:
@@ -2222,60 +2261,75 @@ define <8 x i8> @and_sink_not_splat_v8i8_swapped(<8 x i8> %x, i8 %m, i1 zeroext
 ;
 ; X86-BMI-LABEL: and_sink_not_splat_v8i8_swapped:
 ; X86-BMI:       # %bb.0:
+; X86-BMI-NEXT:    pushl %ebp
 ; X86-BMI-NEXT:    pushl %ebx
-; X86-BMI-NEXT:    pushl %eax
+; X86-BMI-NEXT:    pushl %edi
+; X86-BMI-NEXT:    pushl %esi
+; X86-BMI-NEXT:    subl $12, %esp
 ; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
 ; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %bh
 ; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dl
+; X86-BMI-NEXT:    movl %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movl %edx, %edi
 ; X86-BMI-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movl %edx, %ebp
 ; X86-BMI-NEXT:    je .LBB15_2
 ; X86-BMI-NEXT:  # %bb.1: # %mask
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %ch
-; X86-BMI-NEXT:    notb %ch
-; X86-BMI-NEXT:    andb %ch, %dh
-; X86-BMI-NEXT:    movb %dh, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
-; X86-BMI-NEXT:    movb %dh, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
-; X86-BMI-NEXT:    andb %ch, %dh
-; X86-BMI-NEXT:    movb %dh, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Spill
-; X86-BMI-NEXT:    andb %ch, {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill
-; X86-BMI-NEXT:    movb {{[0-9]+}}(%esp), %dh
-; X86-BMI-NEXT:    andb %ch, %dh
-; X86-BMI-NEXT:    andb %ch, %bl
-; X86-BMI-NEXT:    andb %ch, %bh
-; X86-BMI-NEXT:    andb %ch, %dl
-; X86-BMI-NEXT:    andb %ch, %cl
-; X86-BMI-NEXT:    movb %cl, 1(%eax)
-; X86-BMI-NEXT:    movb %dl, (%eax)
-; X86-BMI-NEXT:    movb %bh, 2(%eax)
-; X86-BMI-NEXT:    movb %bl, 3(%eax)
-; X86-BMI-NEXT:    movb %dh, 4(%eax)
-; X86-BMI-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload
+; X86-BMI-NEXT:    movl %ecx, %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    andnl %ebx, %ecx, %ebx
+; X86-BMI-NEXT:    movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    andnl %esi, %ecx, %esi
+; X86-BMI-NEXT:    movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; X86-BMI-NEXT:    andnl %edx, %ecx, %edx
+; X86-BMI-NEXT:    movl %edx, (%esp) # 4-byte Spill
+; X86-BMI-NEXT:    andnl %edi, %ecx, %edi
+; X86-BMI-NEXT:    andnl %ebp, %ecx, %ebp
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %esi
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %edx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ebx
+; X86-BMI-NEXT:    andnl %ebx, %ecx, %ecx
+; X86-BMI-NEXT:    movb %cl, (%eax)
+; X86-BMI-NEXT:    movb %dl, 1(%eax)
+; X86-BMI-NEXT:    movl %esi, %ecx
+; X86-BMI-NEXT:    movb %cl, 2(%eax)
+; X86-BMI-NEXT:    movl %ebp, %ecx
+; X86-BMI-NEXT:    movb %cl, 3(%eax)
+; X86-BMI-NEXT:    movl %edi, %ecx
+; X86-BMI-NEXT:    movb %cl, 4(%eax)
+; X86-BMI-NEXT:    movl (%esp), %ecx # 4-byte Reload
 ; X86-BMI-NEXT:    movb %cl, 5(%eax)
-; X86-BMI-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
 ; X86-BMI-NEXT:    movb %cl, 6(%eax)
-; X86-BMI-NEXT:    movzbl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 1-byte Folded Reload
+; X86-BMI-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
 ; X86-BMI-NEXT:    movb %cl, 7(%eax)
 ; X86-BMI-NEXT:    jmp .LBB15_3
 ; X86-BMI-NEXT:  .LBB15_2: # %identity
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
 ; X86-BMI-NEXT:    movb %dl, (%eax)
-; X86-BMI-NEXT:    movb %cl, 1(%eax)
-; X86-BMI-NEXT:    movb %bh, 2(%eax)
-; X86-BMI-NEXT:    movb %bl, 3(%eax)
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; X86-BMI-NEXT:    movb %cl, 4(%eax)
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movb %dl, 1(%eax)
+; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    movb %dl, 2(%eax)
+; X86-BMI-NEXT:    movl %ebp, %edx
+; X86-BMI-NEXT:    movb %dl, 3(%eax)
+; X86-BMI-NEXT:    movl %edi, %edx
+; X86-BMI-NEXT:    movb %dl, 4(%eax)
 ; X86-BMI-NEXT:    movb %cl, 5(%eax)
-; X86-BMI-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X86-BMI-NEXT:    movl %esi, %ecx
 ; X86-BMI-NEXT:    movb %cl, 6(%eax)
-; X86-BMI-NEXT:    movb %dh, 7(%eax)
+; X86-BMI-NEXT:    movb %bl, 7(%eax)
 ; X86-BMI-NEXT:  .LBB15_3: # %identity
-; X86-BMI-NEXT:    addl $4, %esp
+; X86-BMI-NEXT:    addl $12, %esp
+; X86-BMI-NEXT:    popl %esi
+; X86-BMI-NEXT:    popl %edi
 ; X86-BMI-NEXT:    popl %ebx
+; X86-BMI-NEXT:    popl %ebp
 ; X86-BMI-NEXT:    retl $4
 ;
 ; X64-NOAVX2-LABEL: and_sink_not_splat_v8i8_swapped:
diff --git a/llvm/test/CodeGen/X86/avx512-mask-bit-manip.ll b/llvm/test/CodeGen/X86/avx512-mask-bit-manip.ll
index 0474c9fc8eb34..cb91cb9c207f2 100644
--- a/llvm/test/CodeGen/X86/avx512-mask-bit-manip.ll
+++ b/llvm/test/CodeGen/X86/avx512-mask-bit-manip.ll
@@ -429,10 +429,8 @@ define <8 x i64> @blcic_v8i64(<8 x i64> %a0, <8 x i64> %a1) {
 ; AVX512:       # %bb.0:
 ; AVX512-NEXT:    vpcmpnltuq %zmm1, %zmm0, %k0
 ; AVX512-NEXT:    kmovd %k0, %eax
-; AVX512-NEXT:    movl %eax, %ecx
-; AVX512-NEXT:    notb %cl
-; AVX512-NEXT:    incb %al
-; AVX512-NEXT:    andb %cl, %al
+; AVX512-NEXT:    leal 1(%rax), %ecx
+; AVX512-NEXT:    andnl %ecx, %eax, %eax
 ; AVX512-NEXT:    kmovd %eax, %k1
 ; AVX512-NEXT:    vpaddq %zmm1, %zmm0, %zmm1
 ; AVX512-NEXT:    vmovdqa64 %zmm0, %zmm1 {%k1}
@@ -443,10 +441,8 @@ define <8 x i64> @blcic_v8i64(<8 x i64> %a0, <8 x i64> %a1) {
 ; AVX512F:       # %bb.0:
 ; AVX512F-NEXT:    vpcmpnltuq %zmm1, %zmm0, %k0
 ; AVX512F-NEXT:    kmovw %k0, %eax
-; AVX512F-NEXT:    movl %eax, %ecx
-; AVX512F-NEXT:    notb %cl
-; AVX512F-NEXT:    addb $1, %al
-; AVX512F-NEXT:    andb %cl, %al
+; AVX512F-NEXT:    leal 1(%rax), %ecx
+; AVX512F-NEXT:    andnl %ecx, %eax, %eax
 ; AVX512F-NEXT:    kmovw %eax, %k1
 ; AVX512F-NEXT:    vpaddq %zmm1, %zmm0, %zmm1
 ; AVX512F-NEXT:    vmovdqa64 %zmm0, %zmm1 {%k1}
diff --git a/llvm/test/CodeGen/X86/bmi.ll b/llvm/test/CodeGen/X86/bmi.ll
index bcf1a3eaeb8c2..e5a43b9efa2ef 100644
--- a/llvm/test/CodeGen/X86/bmi.ll
+++ b/llvm/test/CodeGen/X86/bmi.ll
@@ -381,7 +381,7 @@ define i1 @andn_cmp_swap_ops(i64 %x, i64 %y) {
   ret i1 %cmp
 }
 
-; Use a 'test' (not an 'and') because 'andn' only works for i32/i64.
+; Use a 'test' for the final i8 compare.
 define i1 @andn_cmp_i8(i8 %x, i8 %y) {
 ; X86-LABEL: andn_cmp_i8:
 ; X86:       # %bb.0:
@@ -393,15 +393,15 @@ define i1 @andn_cmp_i8(i8 %x, i8 %y) {
 ;
 ; X64-LABEL: andn_cmp_i8:
 ; X64:       # %bb.0:
-; X64-NEXT:    notb %sil
-; X64-NEXT:    testb %sil, %dil
+; X64-NEXT:    andnl %edi, %esi, %eax
+; X64-NEXT:    testb %al, %al
 ; X64-NEXT:    sete %al
 ; X64-NEXT:    retq
 ;
 ; EGPR-LABEL: andn_cmp_i8:
 ; EGPR:       # %bb.0:
-; EGPR-NEXT:    notb %sil # encoding: [0x40,0xf6,0xd6]
-; EGPR-NEXT:    testb %sil, %dil # encoding: [0x40,0x84,0xf7]
+; EGPR-NEXT:    andnl %edi, %esi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x48,0xf2,0xc7]
+; EGPR-NEXT:    testb %al, %al # encoding: [0x84,0xc0]
 ; EGPR-NEXT:    sete %al # encoding: [0x0f,0x94,0xc0]
 ; EGPR-NEXT:    retq # encoding: [0xc3]
   %noty = xor i8 %y, -1
@@ -2174,3 +2174,27 @@ define i16 @blsi16_trunc(i32 %x) {
   %and = and i16 %t, %neg
   ret i16 %and
 }
+
+define i8 @andn8(i8 %x, i8 %y) {
+; X86-LABEL: andn8:
+; X86:       # %bb.0:
+; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    notb %al
+; X86-NEXT:    andb {{[0-9]+}}(%esp), %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: andn8:
+; X64:       # %bb.0:
+; X64-NEXT:    andnl %esi, %edi, %eax
+; X64-NEXT:    # kill: def $al killed $al killed $eax
+; X64-NEXT:    retq
+;
+; EGPR-LABEL: andn8:
+; EGPR:       # %bb.0:
+; EGPR-NEXT:    andnl %esi, %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x40,0xf2,0xc6]
+; EGPR-NEXT:    # kill: def $al killed $al killed $eax
+; EGPR-NEXT:    retq # encoding: [0xc3]
+  %not = xor i8 %x, 255
+  %and = and i8 %not, %y
+  ret i8 %and
+}
diff --git a/llvm/test/CodeGen/X86/pr108731.ll b/llvm/test/CodeGen/X86/pr108731.ll
index 2983d108eaedd..2994d492501be 100644
--- a/llvm/test/CodeGen/X86/pr108731.ll
+++ b/llvm/test/CodeGen/X86/pr108731.ll
@@ -93,17 +93,28 @@ Entry:
 }
 
 define i8 @test_i8(i8 %w, i8 %x, i8 %y, i8 %z) {
-; CHECK-LABEL: test_i8:
-; CHECK:       # %bb.0: # %Entry
-; CHECK-NEXT:    movl %edx, %eax
-; CHECK-NEXT:    andl %edx, %esi
-; CHECK-NEXT:    notb %sil
-; CHECK-NEXT:    andb %dil, %sil
-; CHECK-NEXT:    notb %cl
-; CHECK-NEXT:    orb %cl, %al
-; CHECK-NEXT:    andb %sil, %al
-; CHECK-NEXT:    # kill: def $al killed $al killed $eax
-; CHECK-NEXT:    retq
+; NOBMI-LABEL: test_i8:
+; NOBMI:       # %bb.0: # %Entry
+; NOBMI-NEXT:    movl %edx, %eax
+; NOBMI-NEXT:    andl %edx, %esi
+; NOBMI-NEXT:    notb %sil
+; NOBMI-NEXT:    andb %dil, %sil
+; NOBMI-NEXT:    notb %cl
+; NOBMI-NEXT:    orb %cl, %al
+; NOBMI-NEXT:    andb %sil, %al
+; NOBMI-NEXT:    # kill: def $al killed $al killed $eax
+; NOBMI-NEXT:    retq
+;
+; BMI-LABEL: test_i8:
+; BMI:       # %bb.0: # %Entry
+; BMI-NEXT:    movl %edx, %eax
+; BMI-NEXT:    andl %edx, %esi
+; BMI-NEXT:    andnl %edi, %esi, %edx
+; BMI-NEXT:    notb %cl
+; BMI-NEXT:    orb %cl, %al
+; BMI-NEXT:    andb %dl, %al
+; BMI-NEXT:    # kill: def $al killed $al killed $eax
+; BMI-NEXT:    retq
 Entry:
   %and1 = and i8 %y, %x
   %xor1 = xor i8 %and1, -1
diff --git a/llvm/test/CodeGen/X86/setcc-logic.ll b/llvm/test/CodeGen/X86/setcc-logic.ll
index c577849b45ee8..f85393860c5bf 100644
--- a/llvm/test/CodeGen/X86/setcc-logic.ll
+++ b/llvm/test/CodeGen/X86/setcc-logic.ll
@@ -703,12 +703,19 @@ define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) {
 }
 
 define i1 @or_cmp_ne_i8(i8 zeroext %x, i8 zeroext %y) {
-; CHECK-LABEL: or_cmp_ne_i8:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    notb %sil
-; CHECK-NEXT:    testb %sil, %dil
-; CHECK-NEXT:    setne %al
-; CHECK-NEXT:    retq
+; NOBMI-LABEL: or_cmp_ne_i8:
+; NOBMI:       # %bb.0:
+; NOBMI-NEXT:    notb %sil
+; NOBMI-NEXT:    testb %sil, %dil
+; NOBMI-NEXT:    setne %al
+; NOBMI-NEXT:    retq
+;
+; BMI-LABEL: or_cmp_ne_i8:
+; BMI:       # %bb.0:
+; BMI-NEXT:    andnl %edi, %esi, %eax
+; BMI-NEXT:    testb %al, %al
+; BMI-NEXT:    setne %al
+; BMI-NEXT:    retq
   %o = or i8 %x, %y
   %c = icmp ne i8 %y, %o
   ret i1 %c



More information about the llvm-commits mailing list