[llvm] [X86]: Reassoc demorgan rule for ANDN (PR #163789)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 16 13:17:18 PDT 2025


https://github.com/kper updated https://github.com/llvm/llvm-project/pull/163789

>From ee35653e45cdfec53652118e9c93f0f12e597fbb Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 16 Oct 2025 13:53:37 +0000
Subject: [PATCH 1/6] [X86]: Reassoc demorgan rule for ANDN

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 28 ++++++
 llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll | 98 +++++++++++++++++++
 2 files changed, 126 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a0b64ff370b10..e2632d114ce0b 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -51651,6 +51651,31 @@ static SDValue combineAndXorSubWithBMI(SDNode *And, const SDLoc &DL,
   return AndN;
 }
 
+// fold (not (or A, B)) -> nand(A, not(B)) if BMI
+static SDValue
+combineReassocDemorganWithNANDWithBMI(SDNode *Xor, const SDLoc &DL,
+                                      SelectionDAG &DAG,
+                                      const X86Subtarget &Subtarget) {
+  using namespace llvm::SDPatternMatch;
+
+  EVT VT = Xor->getValueType(0);
+  // Make sure this node is a candidate for BMI instructions.
+  if (!Subtarget.hasBMI() || (VT != MVT::i32 && VT != MVT::i64))
+    return SDValue();
+
+  SDValue A;
+  SDValue B;
+  APInt Cst;
+  if (!(sd_match(Xor, m_Xor(m_Or(m_Value(A), m_Value(B)), m_ConstInt(Cst))) &&
+        Cst.isAllOnes()))
+    return SDValue();
+
+  auto Opcode =
+      Subtarget.is64Bit() && VT == MVT::i64 ? X86::ANDN64rr : X86::ANDN32rr;
+  auto AndN = DAG.getMachineNode(Opcode, DL, VT, A, DAG.getNOT(DL, B, VT));
+  return SDValue(AndN, 0);
+}
+
 static SDValue combineX86SubCmpForFlags(SDNode *N, SDValue Flag,
                                         SelectionDAG &DAG,
                                         TargetLowering::DAGCombinerInfo &DCI,
@@ -55150,6 +55175,9 @@ static SDValue combineXor(SDNode *N, SelectionDAG &DAG,
   if (SDValue R = combineBMILogicOp(N, DAG, Subtarget))
     return R;
 
+  if (SDValue R = combineReassocDemorganWithNANDWithBMI(N, DL, DAG, Subtarget))
+    return R;
+
   return combineFneg(N, DAG, DCI, Subtarget);
 }
 
diff --git a/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll b/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll
new file mode 100644
index 0000000000000..ea81d08cd2e6d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll
@@ -0,0 +1,98 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64
+
+define i32 @reassoc_demorgan_i32(i32 %a, i32 %b) nounwind {
+; X86-LABEL: reassoc_demorgan_i32:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    notl %ecx
+; X86-NEXT:    andnl %ecx, %eax, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: reassoc_demorgan_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    notl %edi
+; X64-NEXT:    andnl %edi, %esi, %eax
+; X64-NEXT:    retq
+  %temp = or i32 %b, %a
+  %res = xor i32 %temp, -1
+  ret i32 %res
+}
+
+define i32 @reassoc_demorgan_three_arguments_i32(i32 %a, i32 %b, i32 %c) nounwind {
+; X86-LABEL: reassoc_demorgan_three_arguments_i32:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    orl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    notl %eax
+; X86-NEXT:    andnl %eax, %ecx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: reassoc_demorgan_three_arguments_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    orl %esi, %edi
+; X64-NEXT:    notl %edx
+; X64-NEXT:    andnl %edx, %edi, %eax
+; X64-NEXT:    retq
+  %and.demorgan = or i32 %b, %a
+  %and3.demorgan = or i32 %and.demorgan, %c
+  %and3 = xor i32 %and3.demorgan, -1
+  ret i32 %and3
+}
+
+define i64 @reassoc_demorgan_i64(i64 %a, i64 %b) nounwind {
+; X86-LABEL: reassoc_demorgan_i64:
+; X86:       # %bb.0:
+; X86-NEXT:    pushl %esi
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    notl %edx
+; X86-NEXT:    andnl %edx, %eax, %eax
+; X86-NEXT:    notl %esi
+; X86-NEXT:    andnl %esi, %ecx, %edx
+; X86-NEXT:    popl %esi
+; X86-NEXT:    retl
+;
+; X64-LABEL: reassoc_demorgan_i64:
+; X64:       # %bb.0:
+; X64-NEXT:    notq %rdi
+; X64-NEXT:    andnq %rdi, %rsi, %rax
+; X64-NEXT:    retq
+  %temp = or i64 %b, %a
+  %res = xor i64 %temp, -1
+  ret i64 %res
+}
+
+define i64 @reassoc_demorgan_three_arguments_i64(i64 %a, i64 %b, i64 %c) nounwind {
+; X86-LABEL: reassoc_demorgan_three_arguments_i64:
+; X86:       # %bb.0:
+; X86-NEXT:    pushl %esi
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    orl {{[0-9]+}}(%esp), %esi
+; X86-NEXT:    orl {{[0-9]+}}(%esp), %edx
+; X86-NEXT:    notl %eax
+; X86-NEXT:    andnl %eax, %edx, %eax
+; X86-NEXT:    notl %ecx
+; X86-NEXT:    andnl %ecx, %esi, %edx
+; X86-NEXT:    popl %esi
+; X86-NEXT:    retl
+;
+; X64-LABEL: reassoc_demorgan_three_arguments_i64:
+; X64:       # %bb.0:
+; X64-NEXT:    orq %rsi, %rdi
+; X64-NEXT:    notq %rdx
+; X64-NEXT:    andnq %rdx, %rdi, %rax
+; X64-NEXT:    retq
+  %and.demorgan = or i64 %b, %a
+  %and3.demorgan = or i64 %and.demorgan, %c
+  %and3 = xor i64 %and3.demorgan, -1
+  ret i64 %and3
+}

>From deda3383ab0015a23d521f37d44a5714def2346c Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 16 Oct 2025 18:24:40 +0000
Subject: [PATCH 2/6] [X86]: Removed obsolete code

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 28 -------------------------
 1 file changed, 28 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e2632d114ce0b..a0b64ff370b10 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -51651,31 +51651,6 @@ static SDValue combineAndXorSubWithBMI(SDNode *And, const SDLoc &DL,
   return AndN;
 }
 
-// fold (not (or A, B)) -> nand(A, not(B)) if BMI
-static SDValue
-combineReassocDemorganWithNANDWithBMI(SDNode *Xor, const SDLoc &DL,
-                                      SelectionDAG &DAG,
-                                      const X86Subtarget &Subtarget) {
-  using namespace llvm::SDPatternMatch;
-
-  EVT VT = Xor->getValueType(0);
-  // Make sure this node is a candidate for BMI instructions.
-  if (!Subtarget.hasBMI() || (VT != MVT::i32 && VT != MVT::i64))
-    return SDValue();
-
-  SDValue A;
-  SDValue B;
-  APInt Cst;
-  if (!(sd_match(Xor, m_Xor(m_Or(m_Value(A), m_Value(B)), m_ConstInt(Cst))) &&
-        Cst.isAllOnes()))
-    return SDValue();
-
-  auto Opcode =
-      Subtarget.is64Bit() && VT == MVT::i64 ? X86::ANDN64rr : X86::ANDN32rr;
-  auto AndN = DAG.getMachineNode(Opcode, DL, VT, A, DAG.getNOT(DL, B, VT));
-  return SDValue(AndN, 0);
-}
-
 static SDValue combineX86SubCmpForFlags(SDNode *N, SDValue Flag,
                                         SelectionDAG &DAG,
                                         TargetLowering::DAGCombinerInfo &DCI,
@@ -55175,9 +55150,6 @@ static SDValue combineXor(SDNode *N, SelectionDAG &DAG,
   if (SDValue R = combineBMILogicOp(N, DAG, Subtarget))
     return R;
 
-  if (SDValue R = combineReassocDemorganWithNANDWithBMI(N, DL, DAG, Subtarget))
-    return R;
-
   return combineFneg(N, DAG, DCI, Subtarget);
 }
 

>From cdb57ef348cbd3ac3bd6b361fd6a3b4ddb9ff8fb Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 16 Oct 2025 18:25:21 +0000
Subject: [PATCH 3/6] [DAG]: Reassoc demorgan rule for ANDN

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c97300d64d455..0629b75989233 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10197,6 +10197,22 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
     }
   }
 
+  // fold (not (or A, B)) -> and(not(A), not(B))
+  if (TLI.hasAndNot(SDValue(N, 0))) {
+    // If we have AndNot then it is profitable to apply demorgan to make use
+    // of the machine instruction.
+    SDValue A;
+    SDValue B;
+    APInt Cst;
+    if (sd_match(N, m_Xor(m_Or(m_Value(A), m_Value(B)), m_ConstInt(Cst))) &&
+        Cst.isAllOnes()) {
+      return DAG.getNode(
+          ISD::AND, DL, VT,
+          DAG.getNode(ISD::XOR, DL, VT, A, DAG.getConstant(-1, DL, VT)),
+          DAG.getNode(ISD::XOR, DL, VT, B, DAG.getConstant(-1, DL, VT)));
+    }
+  }
+
   return SDValue();
 }
 

>From 9e4103d5d49bbc92b1fdfad30e5e52f51f9c70e2 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 16 Oct 2025 18:35:14 +0000
Subject: [PATCH 4/6] [DAG]: Fixed type

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 0629b75989233..5b77dc423b66b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -10206,10 +10206,11 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
     APInt Cst;
     if (sd_match(N, m_Xor(m_Or(m_Value(A), m_Value(B)), m_ConstInt(Cst))) &&
         Cst.isAllOnes()) {
+      auto Ty = N->getValueType(0);
       return DAG.getNode(
           ISD::AND, DL, VT,
-          DAG.getNode(ISD::XOR, DL, VT, A, DAG.getConstant(-1, DL, VT)),
-          DAG.getNode(ISD::XOR, DL, VT, B, DAG.getConstant(-1, DL, VT)));
+          DAG.getNode(ISD::XOR, DL, VT, A, DAG.getConstant(Cst, DL, Ty)),
+          DAG.getNode(ISD::XOR, DL, VT, B, DAG.getConstant(Cst, DL, Ty)));
     }
   }
 

>From cf6ee582057a42e9ec8f5b81355c2bee8a8067cb Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 16 Oct 2025 18:45:46 +0000
Subject: [PATCH 5/6] [X86]: Updated tests

---
 llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll | 210 ++++++++++++------
 1 file changed, 143 insertions(+), 67 deletions(-)

diff --git a/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll b/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll
index ea81d08cd2e6d..7f3a376b24b2a 100644
--- a/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll
+++ b/llvm/test/CodeGen/X86/bmi-reassoc-demorgan.ll
@@ -1,42 +1,75 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86
-; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X86-WITH-BMI
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefix=X64-WITH-BMI
+; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86-WITHOUT-BMI
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64-WITHOUT-BMI
 
 define i32 @reassoc_demorgan_i32(i32 %a, i32 %b) nounwind {
-; X86-LABEL: reassoc_demorgan_i32:
-; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    notl %ecx
-; X86-NEXT:    andnl %ecx, %eax, %eax
-; X86-NEXT:    retl
+; X86-WITH-BMI-LABEL: reassoc_demorgan_i32:
+; X86-WITH-BMI:       # %bb.0:
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-WITH-BMI-NEXT:    notl %ecx
+; X86-WITH-BMI-NEXT:    andnl %ecx, %eax, %eax
+; X86-WITH-BMI-NEXT:    retl
 ;
-; X64-LABEL: reassoc_demorgan_i32:
-; X64:       # %bb.0:
-; X64-NEXT:    notl %edi
-; X64-NEXT:    andnl %edi, %esi, %eax
-; X64-NEXT:    retq
+; X64-WITH-BMI-LABEL: reassoc_demorgan_i32:
+; X64-WITH-BMI:       # %bb.0:
+; X64-WITH-BMI-NEXT:    notl %edi
+; X64-WITH-BMI-NEXT:    andnl %edi, %esi, %eax
+; X64-WITH-BMI-NEXT:    retq
+;
+; X86-WITHOUT-BMI-LABEL: reassoc_demorgan_i32:
+; X86-WITHOUT-BMI:       # %bb.0:
+; X86-WITHOUT-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    notl %eax
+; X86-WITHOUT-BMI-NEXT:    retl
+;
+; X64-WITHOUT-BMI-LABEL: reassoc_demorgan_i32:
+; X64-WITHOUT-BMI:       # %bb.0:
+; X64-WITHOUT-BMI-NEXT:    movl %edi, %eax
+; X64-WITHOUT-BMI-NEXT:    orl %esi, %eax
+; X64-WITHOUT-BMI-NEXT:    notl %eax
+; X64-WITHOUT-BMI-NEXT:    retq
   %temp = or i32 %b, %a
   %res = xor i32 %temp, -1
   ret i32 %res
 }
 
 define i32 @reassoc_demorgan_three_arguments_i32(i32 %a, i32 %b, i32 %c) nounwind {
-; X86-LABEL: reassoc_demorgan_three_arguments_i32:
-; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    orl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    notl %eax
-; X86-NEXT:    andnl %eax, %ecx, %eax
-; X86-NEXT:    retl
+; X86-WITH-BMI-LABEL: reassoc_demorgan_three_arguments_i32:
+; X86-WITH-BMI:       # %bb.0:
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-WITH-BMI-NEXT:    notl %edx
+; X86-WITH-BMI-NEXT:    andnl %edx, %ecx, %ecx
+; X86-WITH-BMI-NEXT:    andnl %ecx, %eax, %eax
+; X86-WITH-BMI-NEXT:    retl
+;
+; X64-WITH-BMI-LABEL: reassoc_demorgan_three_arguments_i32:
+; X64-WITH-BMI:       # %bb.0:
+; X64-WITH-BMI-NEXT:    notl %edi
+; X64-WITH-BMI-NEXT:    andnl %edi, %esi, %eax
+; X64-WITH-BMI-NEXT:    andnl %eax, %edx, %eax
+; X64-WITH-BMI-NEXT:    retq
+;
+; X86-WITHOUT-BMI-LABEL: reassoc_demorgan_three_arguments_i32:
+; X86-WITHOUT-BMI:       # %bb.0:
+; X86-WITHOUT-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    notl %eax
+; X86-WITHOUT-BMI-NEXT:    retl
 ;
-; X64-LABEL: reassoc_demorgan_three_arguments_i32:
-; X64:       # %bb.0:
-; X64-NEXT:    orl %esi, %edi
-; X64-NEXT:    notl %edx
-; X64-NEXT:    andnl %edx, %edi, %eax
-; X64-NEXT:    retq
+; X64-WITHOUT-BMI-LABEL: reassoc_demorgan_three_arguments_i32:
+; X64-WITHOUT-BMI:       # %bb.0:
+; X64-WITHOUT-BMI-NEXT:    movl %edi, %eax
+; X64-WITHOUT-BMI-NEXT:    orl %esi, %eax
+; X64-WITHOUT-BMI-NEXT:    orl %edx, %eax
+; X64-WITHOUT-BMI-NEXT:    notl %eax
+; X64-WITHOUT-BMI-NEXT:    retq
   %and.demorgan = or i32 %b, %a
   %and3.demorgan = or i32 %and.demorgan, %c
   %and3 = xor i32 %and3.demorgan, -1
@@ -44,53 +77,96 @@ define i32 @reassoc_demorgan_three_arguments_i32(i32 %a, i32 %b, i32 %c) nounwin
 }
 
 define i64 @reassoc_demorgan_i64(i64 %a, i64 %b) nounwind {
-; X86-LABEL: reassoc_demorgan_i64:
-; X86:       # %bb.0:
-; X86-NEXT:    pushl %esi
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT:    notl %edx
-; X86-NEXT:    andnl %edx, %eax, %eax
-; X86-NEXT:    notl %esi
-; X86-NEXT:    andnl %esi, %ecx, %edx
-; X86-NEXT:    popl %esi
-; X86-NEXT:    retl
+; X86-WITH-BMI-LABEL: reassoc_demorgan_i64:
+; X86-WITH-BMI:       # %bb.0:
+; X86-WITH-BMI-NEXT:    pushl %esi
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-WITH-BMI-NEXT:    notl %edx
+; X86-WITH-BMI-NEXT:    andnl %edx, %eax, %eax
+; X86-WITH-BMI-NEXT:    notl %esi
+; X86-WITH-BMI-NEXT:    andnl %esi, %ecx, %edx
+; X86-WITH-BMI-NEXT:    popl %esi
+; X86-WITH-BMI-NEXT:    retl
 ;
-; X64-LABEL: reassoc_demorgan_i64:
-; X64:       # %bb.0:
-; X64-NEXT:    notq %rdi
-; X64-NEXT:    andnq %rdi, %rsi, %rax
-; X64-NEXT:    retq
+; X64-WITH-BMI-LABEL: reassoc_demorgan_i64:
+; X64-WITH-BMI:       # %bb.0:
+; X64-WITH-BMI-NEXT:    notq %rdi
+; X64-WITH-BMI-NEXT:    andnq %rdi, %rsi, %rax
+; X64-WITH-BMI-NEXT:    retq
+;
+; X86-WITHOUT-BMI-LABEL: reassoc_demorgan_i64:
+; X86-WITHOUT-BMI:       # %bb.0:
+; X86-WITHOUT-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %edx
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    notl %eax
+; X86-WITHOUT-BMI-NEXT:    notl %edx
+; X86-WITHOUT-BMI-NEXT:    retl
+;
+; X64-WITHOUT-BMI-LABEL: reassoc_demorgan_i64:
+; X64-WITHOUT-BMI:       # %bb.0:
+; X64-WITHOUT-BMI-NEXT:    movq %rdi, %rax
+; X64-WITHOUT-BMI-NEXT:    orq %rsi, %rax
+; X64-WITHOUT-BMI-NEXT:    notq %rax
+; X64-WITHOUT-BMI-NEXT:    retq
   %temp = or i64 %b, %a
   %res = xor i64 %temp, -1
   ret i64 %res
 }
 
 define i64 @reassoc_demorgan_three_arguments_i64(i64 %a, i64 %b, i64 %c) nounwind {
-; X86-LABEL: reassoc_demorgan_three_arguments_i64:
-; X86:       # %bb.0:
-; X86-NEXT:    pushl %esi
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT:    orl {{[0-9]+}}(%esp), %esi
-; X86-NEXT:    orl {{[0-9]+}}(%esp), %edx
-; X86-NEXT:    notl %eax
-; X86-NEXT:    andnl %eax, %edx, %eax
-; X86-NEXT:    notl %ecx
-; X86-NEXT:    andnl %ecx, %esi, %edx
-; X86-NEXT:    popl %esi
-; X86-NEXT:    retl
+; X86-WITH-BMI-LABEL: reassoc_demorgan_three_arguments_i64:
+; X86-WITH-BMI:       # %bb.0:
+; X86-WITH-BMI-NEXT:    pushl %ebx
+; X86-WITH-BMI-NEXT:    pushl %edi
+; X86-WITH-BMI-NEXT:    pushl %esi
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; X86-WITH-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ebx
+; X86-WITH-BMI-NEXT:    notl %edi
+; X86-WITH-BMI-NEXT:    andnl %edi, %edx, %edx
+; X86-WITH-BMI-NEXT:    andnl %edx, %eax, %eax
+; X86-WITH-BMI-NEXT:    notl %ebx
+; X86-WITH-BMI-NEXT:    andnl %ebx, %esi, %edx
+; X86-WITH-BMI-NEXT:    andnl %edx, %ecx, %edx
+; X86-WITH-BMI-NEXT:    popl %esi
+; X86-WITH-BMI-NEXT:    popl %edi
+; X86-WITH-BMI-NEXT:    popl %ebx
+; X86-WITH-BMI-NEXT:    retl
+;
+; X64-WITH-BMI-LABEL: reassoc_demorgan_three_arguments_i64:
+; X64-WITH-BMI:       # %bb.0:
+; X64-WITH-BMI-NEXT:    notq %rdi
+; X64-WITH-BMI-NEXT:    andnq %rdi, %rsi, %rax
+; X64-WITH-BMI-NEXT:    andnq %rax, %rdx, %rax
+; X64-WITH-BMI-NEXT:    retq
+;
+; X86-WITHOUT-BMI-LABEL: reassoc_demorgan_three_arguments_i64:
+; X86-WITHOUT-BMI:       # %bb.0:
+; X86-WITHOUT-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %edx
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %edx
+; X86-WITHOUT-BMI-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X86-WITHOUT-BMI-NEXT:    notl %eax
+; X86-WITHOUT-BMI-NEXT:    notl %edx
+; X86-WITHOUT-BMI-NEXT:    retl
 ;
-; X64-LABEL: reassoc_demorgan_three_arguments_i64:
-; X64:       # %bb.0:
-; X64-NEXT:    orq %rsi, %rdi
-; X64-NEXT:    notq %rdx
-; X64-NEXT:    andnq %rdx, %rdi, %rax
-; X64-NEXT:    retq
+; X64-WITHOUT-BMI-LABEL: reassoc_demorgan_three_arguments_i64:
+; X64-WITHOUT-BMI:       # %bb.0:
+; X64-WITHOUT-BMI-NEXT:    movq %rdi, %rax
+; X64-WITHOUT-BMI-NEXT:    orq %rsi, %rax
+; X64-WITHOUT-BMI-NEXT:    orq %rdx, %rax
+; X64-WITHOUT-BMI-NEXT:    notq %rax
+; X64-WITHOUT-BMI-NEXT:    retq
   %and.demorgan = or i64 %b, %a
   %and3.demorgan = or i64 %and.demorgan, %c
   %and3 = xor i64 %and3.demorgan, -1

>From cef0067d84a41aad176352f02d9585dd71355a71 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per at protonmail.com>
Date: Thu, 16 Oct 2025 20:16:46 +0000
Subject: [PATCH 6/6] [DAG]: Updated tests

---
 llvm/test/CodeGen/X86/andnot-patterns.ll | 184 ++++++++++++++---------
 1 file changed, 116 insertions(+), 68 deletions(-)

diff --git a/llvm/test/CodeGen/X86/andnot-patterns.ll b/llvm/test/CodeGen/X86/andnot-patterns.ll
index fc573fbd4fc99..0701d7046fc35 100644
--- a/llvm/test/CodeGen/X86/andnot-patterns.ll
+++ b/llvm/test/CodeGen/X86/andnot-patterns.ll
@@ -761,6 +761,7 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
 ;
 ; X86-BMI-LABEL: andnot_bitreverse_i64:
 ; X86-BMI:       # %bb.0:
+; X86-BMI-NEXT:    pushl %esi
 ; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-BMI-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-BMI-NEXT:    bswapl %eax
@@ -774,13 +775,16 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
 ; X86-BMI-NEXT:    andl $858993459, %edx # imm = 0x33333333
 ; X86-BMI-NEXT:    shrl $2, %eax
 ; X86-BMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
-; X86-BMI-NEXT:    leal (%eax,%edx,4), %eax
-; X86-BMI-NEXT:    movl %eax, %edx
-; X86-BMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
+; X86-BMI-NEXT:    leal (%eax,%edx,4), %esi
+; X86-BMI-NEXT:    andl $1431655765, %esi # imm = 0x55555555
+; X86-BMI-NEXT:    addl %esi, %esi
+; X86-BMI-NEXT:    shll $2, %edx
+; X86-BMI-NEXT:    notl %edx
+; X86-BMI-NEXT:    andnl %edx, %eax, %eax
 ; X86-BMI-NEXT:    shrl %eax
-; X86-BMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
-; X86-BMI-NEXT:    leal (%eax,%edx,2), %eax
-; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
+; X86-BMI-NEXT:    orl $-1431655766, %eax # imm = 0xAAAAAAAA
+; X86-BMI-NEXT:    andnl %eax, %esi, %eax
+; X86-BMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
 ; X86-BMI-NEXT:    bswapl %ecx
 ; X86-BMI-NEXT:    movl %ecx, %edx
 ; X86-BMI-NEXT:    andl $252645135, %edx # imm = 0xF0F0F0F
@@ -792,13 +796,17 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
 ; X86-BMI-NEXT:    andl $858993459, %edx # imm = 0x33333333
 ; X86-BMI-NEXT:    shrl $2, %ecx
 ; X86-BMI-NEXT:    andl $858993459, %ecx # imm = 0x33333333
-; X86-BMI-NEXT:    leal (%ecx,%edx,4), %ecx
-; X86-BMI-NEXT:    movl %ecx, %edx
-; X86-BMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
+; X86-BMI-NEXT:    leal (%ecx,%edx,4), %esi
+; X86-BMI-NEXT:    andl $1431655765, %esi # imm = 0x55555555
+; X86-BMI-NEXT:    addl %esi, %esi
+; X86-BMI-NEXT:    shll $2, %edx
+; X86-BMI-NEXT:    notl %edx
+; X86-BMI-NEXT:    andnl %edx, %ecx, %ecx
 ; X86-BMI-NEXT:    shrl %ecx
-; X86-BMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
-; X86-BMI-NEXT:    leal (%ecx,%edx,2), %ecx
-; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %ecx, %edx
+; X86-BMI-NEXT:    orl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; X86-BMI-NEXT:    andnl %ecx, %esi, %edx
+; X86-BMI-NEXT:    andl {{[0-9]+}}(%esp), %edx
+; X86-BMI-NEXT:    popl %esi
 ; X86-BMI-NEXT:    retl
 ;
 ; X64-NOBMI-LABEL: andnot_bitreverse_i64:
@@ -837,19 +845,23 @@ define i64 @andnot_bitreverse_i64(i64 %a0, i64 %a1) nounwind {
 ; X64-BMI-NEXT:    andq %rcx, %rsi
 ; X64-BMI-NEXT:    shlq $4, %rsi
 ; X64-BMI-NEXT:    orq %rax, %rsi
-; X64-BMI-NEXT:    movabsq $3689348814741910323, %rax # imm = 0x3333333333333333
-; X64-BMI-NEXT:    movq %rsi, %rcx
-; X64-BMI-NEXT:    andq %rax, %rcx
-; X64-BMI-NEXT:    shrq $2, %rsi
-; X64-BMI-NEXT:    andq %rax, %rsi
-; X64-BMI-NEXT:    leaq (%rsi,%rcx,4), %rax
-; X64-BMI-NEXT:    movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555
-; X64-BMI-NEXT:    movq %rax, %rdx
-; X64-BMI-NEXT:    andq %rcx, %rdx
-; X64-BMI-NEXT:    shrq %rax
+; X64-BMI-NEXT:    movq %rsi, %rax
+; X64-BMI-NEXT:    shrq $2, %rax
+; X64-BMI-NEXT:    movabsq $3689348814741910323, %rcx # imm = 0x3333333333333333
 ; X64-BMI-NEXT:    andq %rcx, %rax
-; X64-BMI-NEXT:    leaq (%rax,%rdx,2), %rax
-; X64-BMI-NEXT:    andnq %rdi, %rax, %rax
+; X64-BMI-NEXT:    andq %rcx, %rsi
+; X64-BMI-NEXT:    leaq (,%rsi,4), %rcx
+; X64-BMI-NEXT:    notq %rcx
+; X64-BMI-NEXT:    andnq %rcx, %rax, %rcx
+; X64-BMI-NEXT:    shrq %rcx
+; X64-BMI-NEXT:    movabsq $-6148914691236517206, %rdx # imm = 0xAAAAAAAAAAAAAAAA
+; X64-BMI-NEXT:    orq %rcx, %rdx
+; X64-BMI-NEXT:    leaq (%rax,%rsi,4), %rax
+; X64-BMI-NEXT:    movabsq $6148914691236517205, %rcx # imm = 0x5555555555555555
+; X64-BMI-NEXT:    andq %rax, %rcx
+; X64-BMI-NEXT:    addq %rcx, %rcx
+; X64-BMI-NEXT:    andnq %rdx, %rcx, %rax
+; X64-BMI-NEXT:    andq %rdi, %rax
 ; X64-BMI-NEXT:    retq
   %not = xor i64 %a1, -1
   %bitrev = tail call i64 @llvm.bitreverse.i64(i64 %not)
@@ -896,13 +908,16 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
 ; X86-BMI-NEXT:    andl $858993459, %ecx # imm = 0x33333333
 ; X86-BMI-NEXT:    shrl $2, %eax
 ; X86-BMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
-; X86-BMI-NEXT:    leal (%eax,%ecx,4), %eax
-; X86-BMI-NEXT:    movl %eax, %ecx
-; X86-BMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
+; X86-BMI-NEXT:    leal (%eax,%ecx,4), %edx
+; X86-BMI-NEXT:    andl $1431655765, %edx # imm = 0x55555555
+; X86-BMI-NEXT:    addl %edx, %edx
+; X86-BMI-NEXT:    shll $2, %ecx
+; X86-BMI-NEXT:    notl %ecx
+; X86-BMI-NEXT:    andnl %ecx, %eax, %eax
 ; X86-BMI-NEXT:    shrl %eax
-; X86-BMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
-; X86-BMI-NEXT:    leal (%eax,%ecx,2), %eax
-; X86-BMI-NEXT:    andnl {{[0-9]+}}(%esp), %eax, %eax
+; X86-BMI-NEXT:    orl $-1431655766, %eax # imm = 0xAAAAAAAA
+; X86-BMI-NEXT:    andnl %eax, %edx, %eax
+; X86-BMI-NEXT:    andl {{[0-9]+}}(%esp), %eax
 ; X86-BMI-NEXT:    retl
 ;
 ; X64-NOBMI-LABEL: andnot_bitreverse_i32:
@@ -940,16 +955,19 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
 ; X64-BMI-NEXT:    andl $252645135, %esi # imm = 0xF0F0F0F
 ; X64-BMI-NEXT:    orl %eax, %esi
 ; X64-BMI-NEXT:    movl %esi, %eax
+; X64-BMI-NEXT:    shrl $2, %eax
 ; X64-BMI-NEXT:    andl $858993459, %eax # imm = 0x33333333
-; X64-BMI-NEXT:    shrl $2, %esi
 ; X64-BMI-NEXT:    andl $858993459, %esi # imm = 0x33333333
-; X64-BMI-NEXT:    leal (%rsi,%rax,4), %eax
-; X64-BMI-NEXT:    movl %eax, %ecx
-; X64-BMI-NEXT:    andl $1431655765, %ecx # imm = 0x55555555
-; X64-BMI-NEXT:    shrl %eax
+; X64-BMI-NEXT:    leal (,%rsi,4), %ecx
+; X64-BMI-NEXT:    notl %ecx
+; X64-BMI-NEXT:    andnl %ecx, %eax, %ecx
+; X64-BMI-NEXT:    shrl %ecx
+; X64-BMI-NEXT:    orl $-1431655766, %ecx # imm = 0xAAAAAAAA
+; X64-BMI-NEXT:    leal (%rax,%rsi,4), %eax
 ; X64-BMI-NEXT:    andl $1431655765, %eax # imm = 0x55555555
-; X64-BMI-NEXT:    leal (%rax,%rcx,2), %eax
-; X64-BMI-NEXT:    andnl %edi, %eax, %eax
+; X64-BMI-NEXT:    addl %eax, %eax
+; X64-BMI-NEXT:    andnl %ecx, %eax, %eax
+; X64-BMI-NEXT:    andl %edi, %eax
 ; X64-BMI-NEXT:    retq
   %not = xor i32 %a1, -1
   %bitrev = tail call i32 @llvm.bitreverse.i32(i32 %not)
@@ -958,30 +976,57 @@ define i32 @andnot_bitreverse_i32(i32 %a0, i32 %a1) nounwind {
 }
 
 define i16 @andnot_bitreverse_i16(i16 %a0, i16 %a1) nounwind {
-; X86-LABEL: andnot_bitreverse_i16:
-; X86:       # %bb.0:
-; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    rolw $8, %ax
-; X86-NEXT:    movl %eax, %ecx
-; X86-NEXT:    andl $3855, %ecx # imm = 0xF0F
-; X86-NEXT:    shll $4, %ecx
-; X86-NEXT:    shrl $4, %eax
-; X86-NEXT:    andl $3855, %eax # imm = 0xF0F
-; X86-NEXT:    orl %ecx, %eax
-; X86-NEXT:    movl %eax, %ecx
-; X86-NEXT:    andl $13107, %ecx # imm = 0x3333
-; X86-NEXT:    shrl $2, %eax
-; X86-NEXT:    andl $13107, %eax # imm = 0x3333
-; X86-NEXT:    leal (%eax,%ecx,4), %eax
-; X86-NEXT:    movl %eax, %ecx
-; X86-NEXT:    andl $21845, %ecx # imm = 0x5555
-; X86-NEXT:    shrl %eax
-; X86-NEXT:    andl $21845, %eax # imm = 0x5555
-; X86-NEXT:    leal (%eax,%ecx,2), %eax
-; X86-NEXT:    notl %eax
-; X86-NEXT:    andw {{[0-9]+}}(%esp), %ax
-; X86-NEXT:    # kill: def $ax killed $ax killed $eax
-; X86-NEXT:    retl
+; X86-NOBMI-LABEL: andnot_bitreverse_i16:
+; X86-NOBMI:       # %bb.0:
+; X86-NOBMI-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-NOBMI-NEXT:    rolw $8, %ax
+; X86-NOBMI-NEXT:    movl %eax, %ecx
+; X86-NOBMI-NEXT:    andl $3855, %ecx # imm = 0xF0F
+; X86-NOBMI-NEXT:    shll $4, %ecx
+; X86-NOBMI-NEXT:    shrl $4, %eax
+; X86-NOBMI-NEXT:    andl $3855, %eax # imm = 0xF0F
+; X86-NOBMI-NEXT:    orl %ecx, %eax
+; X86-NOBMI-NEXT:    movl %eax, %ecx
+; X86-NOBMI-NEXT:    andl $13107, %ecx # imm = 0x3333
+; X86-NOBMI-NEXT:    shrl $2, %eax
+; X86-NOBMI-NEXT:    andl $13107, %eax # imm = 0x3333
+; X86-NOBMI-NEXT:    leal (%eax,%ecx,4), %eax
+; X86-NOBMI-NEXT:    movl %eax, %ecx
+; X86-NOBMI-NEXT:    andl $21845, %ecx # imm = 0x5555
+; X86-NOBMI-NEXT:    shrl %eax
+; X86-NOBMI-NEXT:    andl $21845, %eax # imm = 0x5555
+; X86-NOBMI-NEXT:    leal (%eax,%ecx,2), %eax
+; X86-NOBMI-NEXT:    notl %eax
+; X86-NOBMI-NEXT:    andw {{[0-9]+}}(%esp), %ax
+; X86-NOBMI-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-NOBMI-NEXT:    retl
+;
+; X86-BMI-LABEL: andnot_bitreverse_i16:
+; X86-BMI:       # %bb.0:
+; X86-BMI-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-BMI-NEXT:    rolw $8, %ax
+; X86-BMI-NEXT:    movl %eax, %ecx
+; X86-BMI-NEXT:    andl $3855, %ecx # imm = 0xF0F
+; X86-BMI-NEXT:    shll $4, %ecx
+; X86-BMI-NEXT:    shrl $4, %eax
+; X86-BMI-NEXT:    andl $3855, %eax # imm = 0xF0F
+; X86-BMI-NEXT:    orl %ecx, %eax
+; X86-BMI-NEXT:    movl %eax, %ecx
+; X86-BMI-NEXT:    andl $13107, %ecx # imm = 0x3333
+; X86-BMI-NEXT:    shrl $2, %eax
+; X86-BMI-NEXT:    andl $13107, %eax # imm = 0x3333
+; X86-BMI-NEXT:    leal (%eax,%ecx,4), %edx
+; X86-BMI-NEXT:    andl $21845, %edx # imm = 0x5555
+; X86-BMI-NEXT:    addl %edx, %edx
+; X86-BMI-NEXT:    shll $2, %ecx
+; X86-BMI-NEXT:    notl %ecx
+; X86-BMI-NEXT:    andnl %ecx, %eax, %eax
+; X86-BMI-NEXT:    shrl %eax
+; X86-BMI-NEXT:    orl $43690, %eax # imm = 0xAAAA
+; X86-BMI-NEXT:    andnl %eax, %edx, %eax
+; X86-BMI-NEXT:    andw {{[0-9]+}}(%esp), %ax
+; X86-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-BMI-NEXT:    retl
 ;
 ; X64-NOBMI-LABEL: andnot_bitreverse_i16:
 ; X64-NOBMI:       # %bb.0:
@@ -1019,16 +1064,19 @@ define i16 @andnot_bitreverse_i16(i16 %a0, i16 %a1) nounwind {
 ; X64-BMI-NEXT:    andl $3855, %esi # imm = 0xF0F
 ; X64-BMI-NEXT:    orl %eax, %esi
 ; X64-BMI-NEXT:    movl %esi, %eax
+; X64-BMI-NEXT:    shrl $2, %eax
 ; X64-BMI-NEXT:    andl $13107, %eax # imm = 0x3333
-; X64-BMI-NEXT:    shrl $2, %esi
 ; X64-BMI-NEXT:    andl $13107, %esi # imm = 0x3333
-; X64-BMI-NEXT:    leal (%rsi,%rax,4), %eax
-; X64-BMI-NEXT:    movl %eax, %ecx
-; X64-BMI-NEXT:    andl $21845, %ecx # imm = 0x5555
-; X64-BMI-NEXT:    shrl %eax
+; X64-BMI-NEXT:    leal (,%rsi,4), %ecx
+; X64-BMI-NEXT:    notl %ecx
+; X64-BMI-NEXT:    andnl %ecx, %eax, %ecx
+; X64-BMI-NEXT:    shrl %ecx
+; X64-BMI-NEXT:    orl $-21846, %ecx # imm = 0xAAAA
+; X64-BMI-NEXT:    leal (%rax,%rsi,4), %eax
 ; X64-BMI-NEXT:    andl $21845, %eax # imm = 0x5555
-; X64-BMI-NEXT:    leal (%rax,%rcx,2), %eax
-; X64-BMI-NEXT:    andnl %edi, %eax, %eax
+; X64-BMI-NEXT:    addl %eax, %eax
+; X64-BMI-NEXT:    andnl %ecx, %eax, %eax
+; X64-BMI-NEXT:    andl %edi, %eax
 ; X64-BMI-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-BMI-NEXT:    retq
   %not = xor i16 %a1, -1



More information about the llvm-commits mailing list