[llvm] [X86] Remove redundant and-not pattern code in X86 (PR #157687)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 7 09:35:51 PST 2026
https://github.com/SiliconA-Z updated https://github.com/llvm/llvm-project/pull/157687
>From 2bfd9169ec4fc0a96c3b97e841a4c808ca9aff31 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Tue, 9 Sep 2025 11:08:21 -0400
Subject: [PATCH] [X86] Remove redundant code in X86
These transforms are now handled in DAGCombine, so enable hasAndNotCompare for the same cases for X86, and remove the platform-specific code that does the same thing.
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 62 ++++---------------------
llvm/test/CodeGen/X86/avx512-cmp.ll | 4 +-
llvm/test/CodeGen/X86/known-pow2.ll | 60 ++++++++++++------------
llvm/test/CodeGen/X86/setcc-logic.ll | 8 ++--
4 files changed, 46 insertions(+), 88 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1ebfd5defdc40..c88078673b411 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3638,29 +3638,23 @@ bool X86TargetLowering::isMaskAndCmp0FoldingBeneficial(
}
bool X86TargetLowering::hasAndNotCompare(SDValue Y) const {
- EVT VT = Y.getValueType();
-
- if (VT.isVector())
- return false;
-
- if (!Subtarget.hasBMI())
- return false;
-
- // There are only 32-bit and 64-bit forms for 'andn'.
- if (VT != MVT::i32 && VT != MVT::i64)
- return false;
-
- return !isa<ConstantSDNode>(Y) || cast<ConstantSDNode>(Y)->isOpaque();
+ return Y.getValueType().isScalarInteger();
}
bool X86TargetLowering::hasAndNot(SDValue Y) const {
EVT VT = Y.getValueType();
- if (!VT.isVector())
- return hasAndNotCompare(Y);
+ if (!VT.isVector()) {
+ if (!Subtarget.hasBMI())
+ return false;
- // Vector.
+ // There are only 32-bit and 64-bit forms for 'andn'.
+ if (VT != MVT::i32 && VT != MVT::i64)
+ return false;
+ return !isa<ConstantSDNode>(Y) || cast<ConstantSDNode>(Y)->isOpaque();
+ }
+ // Vector.
if (!Subtarget.hasSSE1() || VT.getSizeInBits() < 128)
return false;
@@ -57726,42 +57720,6 @@ static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG,
}
if ((CC == ISD::SETNE || CC == ISD::SETEQ) && OpVT.isScalarInteger()) {
- // cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0)
- // cmpne(or(X,Y),X) --> cmpne(and(~X,Y),0)
- auto MatchOrCmpEq = [&](SDValue N0, SDValue N1) {
- if (N0.getOpcode() == ISD::OR && N0->hasOneUse()) {
- if (N0.getOperand(0) == N1)
- return DAG.getNode(ISD::AND, DL, OpVT, DAG.getNOT(DL, N1, OpVT),
- N0.getOperand(1));
- if (N0.getOperand(1) == N1)
- return DAG.getNode(ISD::AND, DL, OpVT, DAG.getNOT(DL, N1, OpVT),
- N0.getOperand(0));
- }
- return SDValue();
- };
- if (SDValue AndN = MatchOrCmpEq(LHS, RHS))
- return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC);
- if (SDValue AndN = MatchOrCmpEq(RHS, LHS))
- return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC);
-
- // cmpeq(and(X,Y),Y) --> cmpeq(and(~X,Y),0)
- // cmpne(and(X,Y),Y) --> cmpne(and(~X,Y),0)
- auto MatchAndCmpEq = [&](SDValue N0, SDValue N1) {
- if (N0.getOpcode() == ISD::AND && N0->hasOneUse()) {
- if (N0.getOperand(0) == N1)
- return DAG.getNode(ISD::AND, DL, OpVT, N1,
- DAG.getNOT(DL, N0.getOperand(1), OpVT));
- if (N0.getOperand(1) == N1)
- return DAG.getNode(ISD::AND, DL, OpVT, N1,
- DAG.getNOT(DL, N0.getOperand(0), OpVT));
- }
- return SDValue();
- };
- if (SDValue AndN = MatchAndCmpEq(LHS, RHS))
- return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC);
- if (SDValue AndN = MatchAndCmpEq(RHS, LHS))
- return DAG.getSetCC(DL, VT, AndN, DAG.getConstant(0, DL, OpVT), CC);
-
// If we're performing a bit test on a larger than legal type, attempt
// to (aligned) shift down the value to the bottom 32-bits and then
// perform the bittest on the i32 value.
diff --git a/llvm/test/CodeGen/X86/avx512-cmp.ll b/llvm/test/CodeGen/X86/avx512-cmp.ll
index 56d6d136fdb61..ac099b5c6718e 100644
--- a/llvm/test/CodeGen/X86/avx512-cmp.ll
+++ b/llvm/test/CodeGen/X86/avx512-cmp.ll
@@ -155,10 +155,10 @@ B:
define i32 @test10(i64 %b, i64 %c, i1 %d) {
; ALL-LABEL: test10:
; ALL: ## %bb.0:
+; ALL-NEXT: xorb $1, %dl
; ALL-NEXT: cmpq %rsi, %rdi
; ALL-NEXT: sete %al
-; ALL-NEXT: notb %dl
-; ALL-NEXT: testb %al, %dl
+; ALL-NEXT: testb %dl, %al
; ALL-NEXT: je LBB8_1
; ALL-NEXT: ## %bb.2: ## %if.end.i
; ALL-NEXT: movl $6, %eax
diff --git a/llvm/test/CodeGen/X86/known-pow2.ll b/llvm/test/CodeGen/X86/known-pow2.ll
index a9b28458e9518..c4156ab81939c 100644
--- a/llvm/test/CodeGen/X86/known-pow2.ll
+++ b/llvm/test/CodeGen/X86/known-pow2.ll
@@ -165,8 +165,8 @@ define i1 @pow2_srl_fail0(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_srl_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
-; CHECK-NEXT: andb $30, %cl
; CHECK-NEXT: notl %edi
+; CHECK-NEXT: andb $30, %cl
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %edi
; CHECK-NEXT: testl $1048576, %edi # imm = 0x100000
@@ -183,8 +183,8 @@ define i1 @pow2_srl_fail1(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_srl_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
-; CHECK-NEXT: andb $7, %cl
; CHECK-NEXT: notl %edi
+; CHECK-NEXT: andb $7, %cl
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %edi
; CHECK-NEXT: testl $1048577, %edi # imm = 0x100001
@@ -217,12 +217,12 @@ define i1 @pow2_rotl_fail0(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_rotl_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $1048576, %eax # imm = 0x100000
; CHECK-NEXT: movl $512, %edx # imm = 0x200
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shldl %cl, %eax, %edx
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %edx
+; CHECK-NEXT: testl %edx, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%d = call i32 @llvm.fshl.i32(i32 512, i32 1048576, i32 %y)
@@ -235,11 +235,11 @@ define i1 @pow2_rotl_fail1(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_rotl_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $511, %eax # imm = 0x1FF
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: roll %cl, %eax
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %eax
+; CHECK-NEXT: testl %eax, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%d = call i32 @llvm.fshl.i32(i32 511, i32 511, i32 %y)
@@ -268,12 +268,12 @@ define i1 @pow2_rotr_fail0(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_rotr_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $512, %eax # imm = 0x200
; CHECK-NEXT: movl $1048576, %edx # imm = 0x100000
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shrdl %cl, %eax, %edx
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %edx
+; CHECK-NEXT: testl %edx, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%d = call i32 @llvm.fshr.i32(i32 512, i32 1048576, i32 %y)
@@ -286,11 +286,11 @@ define i1 @pow2_rotr_fail1(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_rotr_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $511, %eax # imm = 0x1FF
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: rorl %cl, %eax
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %eax
+; CHECK-NEXT: testl %eax, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%d = call i32 @llvm.fshr.i32(i32 511, i32 511, i32 %y)
@@ -323,14 +323,14 @@ define i1 @pow2_umin_fail0(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_umin_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $4, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
; CHECK-NEXT: cmpl $262144, %eax # imm = 0x40000
; CHECK-NEXT: movl $262144, %ecx # imm = 0x40000
; CHECK-NEXT: cmovbl %eax, %ecx
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %ecx
+; CHECK-NEXT: testl %ecx, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 4, %y
@@ -344,14 +344,14 @@ define i1 @pow2_umin_fail1(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_umin_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
; CHECK-NEXT: cmpl $12345, %eax # imm = 0x3039
; CHECK-NEXT: movl $12345, %ecx # imm = 0x3039
; CHECK-NEXT: cmovbl %eax, %ecx
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %ecx
+; CHECK-NEXT: testl %ecx, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 1, %y
@@ -388,6 +388,7 @@ define i1 @pow2_umax_fail0(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: pow2_umax_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
@@ -396,8 +397,7 @@ define i1 @pow2_umax_fail0(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: shrl %cl, %esi
; CHECK-NEXT: cmpl %esi, %eax
; CHECK-NEXT: cmoval %eax, %esi
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %esi
+; CHECK-NEXT: testl %esi, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 1, %y
@@ -412,6 +412,7 @@ define i1 @pow2_umax_fail1(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: pow2_umax_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $4, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
@@ -420,8 +421,7 @@ define i1 @pow2_umax_fail1(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: shrl %cl, %esi
; CHECK-NEXT: cmpl %esi, %eax
; CHECK-NEXT: cmoval %eax, %esi
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %esi
+; CHECK-NEXT: testl %esi, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 4, %y
@@ -456,14 +456,14 @@ define i1 @pow2_smin_fail0(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_smin_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $4, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
; CHECK-NEXT: cmpl $262144, %eax # imm = 0x40000
; CHECK-NEXT: movl $262144, %ecx # imm = 0x40000
; CHECK-NEXT: cmovll %eax, %ecx
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %ecx
+; CHECK-NEXT: testl %ecx, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 4, %y
@@ -477,14 +477,14 @@ define i1 @pow2_smin_fail1(i32 %x, i32 %y) {
; CHECK-LABEL: pow2_smin_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
; CHECK-NEXT: cmpl $12345, %eax # imm = 0x3039
; CHECK-NEXT: movl $12345, %ecx # imm = 0x3039
; CHECK-NEXT: cmovll %eax, %ecx
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %ecx
+; CHECK-NEXT: testl %ecx, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 1, %y
@@ -521,6 +521,7 @@ define i1 @pow2_smax_fail0(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: pow2_smax_fail0:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $1, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
@@ -529,8 +530,7 @@ define i1 @pow2_smax_fail0(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: shrl %cl, %esi
; CHECK-NEXT: cmpl %esi, %eax
; CHECK-NEXT: cmovgl %eax, %esi
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %esi
+; CHECK-NEXT: testl %esi, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 1, %y
@@ -545,6 +545,7 @@ define i1 @pow2_smax_fail1(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: pow2_smax_fail1:
; CHECK: # %bb.0:
; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: notl %edi
; CHECK-NEXT: movl $4, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
@@ -553,8 +554,7 @@ define i1 @pow2_smax_fail1(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: shrl %cl, %esi
; CHECK-NEXT: cmpl %esi, %eax
; CHECK-NEXT: cmovgl %eax, %esi
-; CHECK-NEXT: notl %edi
-; CHECK-NEXT: testl %edi, %esi
+; CHECK-NEXT: testl %esi, %edi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 4, %y
@@ -594,6 +594,7 @@ define i1 @pow2_select_fail0(i1 %c, i32 %x, i32 %y, i32 %z) {
; CHECK: # %bb.0:
; CHECK-NEXT: movl %ecx, %eax
; CHECK-NEXT: movl %edx, %ecx
+; CHECK-NEXT: notl %esi
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %edx
@@ -602,8 +603,7 @@ define i1 @pow2_select_fail0(i1 %c, i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: shrl %cl, %r8d
; CHECK-NEXT: testb $1, %dil
; CHECK-NEXT: cmovnel %edx, %r8d
-; CHECK-NEXT: notl %esi
-; CHECK-NEXT: testl %esi, %r8d
+; CHECK-NEXT: testl %r8d, %esi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 1, %y
@@ -619,6 +619,7 @@ define i1 @pow2_select_fail2(i1 %c, i32 %x, i32 %y, i32 %z) {
; CHECK: # %bb.0:
; CHECK-NEXT: movl %ecx, %eax
; CHECK-NEXT: movl %edx, %ecx
+; CHECK-NEXT: notl %esi
; CHECK-NEXT: movl $4, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %edx
@@ -627,8 +628,7 @@ define i1 @pow2_select_fail2(i1 %c, i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: shrl %cl, %r8d
; CHECK-NEXT: testb $1, %dil
; CHECK-NEXT: cmovnel %edx, %r8d
-; CHECK-NEXT: notl %esi
-; CHECK-NEXT: testl %esi, %r8d
+; CHECK-NEXT: testl %r8d, %esi
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
%yy = shl i32 4, %y
diff --git a/llvm/test/CodeGen/X86/setcc-logic.ll b/llvm/test/CodeGen/X86/setcc-logic.ll
index c98aae7fbf405..83ab90805cb60 100644
--- a/llvm/test/CodeGen/X86/setcc-logic.ll
+++ b/llvm/test/CodeGen/X86/setcc-logic.ll
@@ -629,7 +629,7 @@ define i1 @or_cmp_eq_i64(i64 %x, i64 %y) {
; NOBMI-LABEL: or_cmp_eq_i64:
; NOBMI: # %bb.0:
; NOBMI-NEXT: notq %rdi
-; NOBMI-NEXT: testq %rsi, %rdi
+; NOBMI-NEXT: testq %rdi, %rsi
; NOBMI-NEXT: sete %al
; NOBMI-NEXT: retq
;
@@ -647,7 +647,7 @@ define i1 @or_cmp_ne_i32(i32 %x, i32 %y) {
; NOBMI-LABEL: or_cmp_ne_i32:
; NOBMI: # %bb.0:
; NOBMI-NEXT: notl %esi
-; NOBMI-NEXT: testl %edi, %esi
+; NOBMI-NEXT: testl %esi, %edi
; NOBMI-NEXT: setne %al
; NOBMI-NEXT: retq
;
@@ -665,7 +665,7 @@ define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) {
; NOBMI-LABEL: or_cmp_eq_i16:
; NOBMI: # %bb.0:
; NOBMI-NEXT: notl %edi
-; NOBMI-NEXT: testl %esi, %edi
+; NOBMI-NEXT: testl %edi, %esi
; NOBMI-NEXT: sete %al
; NOBMI-NEXT: retq
;
@@ -683,7 +683,7 @@ 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 %dil, %sil
+; CHECK-NEXT: testb %sil, %dil
; CHECK-NEXT: setne %al
; CHECK-NEXT: retq
%o = or i8 %x, %y
More information about the llvm-commits
mailing list