[llvm] d4b24b4 - [DAGCombiner] Add fold for `~x & x` -> `0`
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 6 18:31:26 PST 2023
Author: Noah Goldstein
Date: 2023-03-06T20:30:20-06:00
New Revision: d4b24b4a55822a78ab9435979ecf470e1dc1aef2
URL: https://github.com/llvm/llvm-project/commit/d4b24b4a55822a78ab9435979ecf470e1dc1aef2
DIFF: https://github.com/llvm/llvm-project/commit/d4b24b4a55822a78ab9435979ecf470e1dc1aef2.diff
LOG: [DAGCombiner] Add fold for `~x & x` -> `0`
This is generally done by the InstCombine, but can be emitted as an
intermediate step and is cheap to handle.
Differential Revision: https://reviews.llvm.org/D145143
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/combine-and.ll
llvm/test/CodeGen/X86/fold-masked-merge.ll
llvm/test/CodeGen/X86/setcc-combine.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 54c088bae8f83..bbec05c6706ce 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2582,6 +2582,12 @@ static bool isADDLike(SDValue V, const SelectionDAG &DAG) {
return false;
}
+static bool
+areBitwiseNotOfEachother(SDValue Op0, SDValue Op1) {
+ return (isBitwiseNot(Op0) && Op0.getOperand(0) == Op1) ||
+ (isBitwiseNot(Op1) && Op1.getOperand(0) == Op0);
+}
+
/// Try to fold a node that behaves like an ADD (note that N isn't necessarily
/// an ISD::ADD here, it could for example be an ISD::OR if we know that there
/// are no common bits set in the operands).
@@ -6625,6 +6631,10 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
!DAG.isConstantIntBuildVectorOrConstantInt(N1))
return DAG.getNode(ISD::AND, SDLoc(N), VT, N1, N0);
+ if (areBitwiseNotOfEachother(N0, N1))
+ return DAG.getConstant(APInt::getZero(VT.getScalarSizeInBits()), SDLoc(N),
+ VT);
+
// fold vector ops
if (VT.isVector()) {
if (SDValue FoldedVOp = SimplifyVBinOp(N, SDLoc(N)))
diff --git a/llvm/test/CodeGen/X86/combine-and.ll b/llvm/test/CodeGen/X86/combine-and.ll
index 6a7dd075e85ee..da52c627ef786 100644
--- a/llvm/test/CodeGen/X86/combine-and.ll
+++ b/llvm/test/CodeGen/X86/combine-and.ll
@@ -1180,12 +1180,12 @@ define <4 x i32> @neg_scalar_broadcast_two_uses(i32 %a0, <4 x i32> %a1, ptr %a2)
define <2 x i64> @andnp_xx(<2 x i64> %v0) nounwind {
; SSE-LABEL: andnp_xx:
; SSE: # %bb.0:
-; SSE-NEXT: andnps %xmm0, %xmm0
+; SSE-NEXT: xorps %xmm0, %xmm0
; SSE-NEXT: retq
;
; AVX-LABEL: andnp_xx:
; AVX: # %bb.0:
-; AVX-NEXT: vandnps %xmm0, %xmm0, %xmm0
+; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0
; AVX-NEXT: retq
%x = xor <2 x i64> %v0, <i64 -1, i64 -1>
%y = and <2 x i64> %v0, %x
@@ -1195,12 +1195,12 @@ define <2 x i64> @andnp_xx(<2 x i64> %v0) nounwind {
define <2 x i64> @andnp_xx_2(<2 x i64> %v0) nounwind {
; SSE-LABEL: andnp_xx_2:
; SSE: # %bb.0:
-; SSE-NEXT: andnps %xmm0, %xmm0
+; SSE-NEXT: xorps %xmm0, %xmm0
; SSE-NEXT: retq
;
; AVX-LABEL: andnp_xx_2:
; AVX: # %bb.0:
-; AVX-NEXT: vandnps %xmm0, %xmm0, %xmm0
+; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0
; AVX-NEXT: retq
%x = xor <2 x i64> %v0, <i64 -1, i64 -1>
%y = and <2 x i64> %x, %v0
@@ -1210,9 +1210,7 @@ define <2 x i64> @andnp_xx_2(<2 x i64> %v0) nounwind {
define i64 @andn_xx(i64 %v0) nounwind {
; CHECK-LABEL: andn_xx:
; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: notq %rax
-; CHECK-NEXT: andq %rdi, %rax
+; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retq
%x = xor i64 %v0, -1
%y = and i64 %v0, %x
@@ -1222,9 +1220,7 @@ define i64 @andn_xx(i64 %v0) nounwind {
define i64 @andn_xx_2(i64 %v0) nounwind {
; CHECK-LABEL: andn_xx_2:
; CHECK: # %bb.0:
-; CHECK-NEXT: movq %rdi, %rax
-; CHECK-NEXT: notq %rax
-; CHECK-NEXT: andq %rdi, %rax
+; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: retq
%x = xor i64 %v0, -1
%y = and i64 %x, %v0
diff --git a/llvm/test/CodeGen/X86/fold-masked-merge.ll b/llvm/test/CodeGen/X86/fold-masked-merge.ll
index d2c00df281610..135494ac25f8c 100644
--- a/llvm/test/CodeGen/X86/fold-masked-merge.ll
+++ b/llvm/test/CodeGen/X86/fold-masked-merge.ll
@@ -187,21 +187,11 @@ define i32 @not_a_masked_merge3(i32 %a0, i32 %a1, i32 %a2) {
; not a masked merge: `not` operand must not be on same `and`.
define i32 @not_a_masked_merge4(i32 %a0, i32 %a1, i32 %a2) {
-; NOBMI-LABEL: not_a_masked_merge4:
-; NOBMI: # %bb.0:
-; NOBMI-NEXT: andl %esi, %edi
-; NOBMI-NEXT: movl %edx, %eax
-; NOBMI-NEXT: notl %eax
-; NOBMI-NEXT: andl %edx, %eax
-; NOBMI-NEXT: orl %edi, %eax
-; NOBMI-NEXT: retq
-;
-; BMI-LABEL: not_a_masked_merge4:
-; BMI: # %bb.0:
-; BMI-NEXT: andl %esi, %edi
-; BMI-NEXT: andnl %edx, %edx, %eax
-; BMI-NEXT: orl %edi, %eax
-; BMI-NEXT: retq
+; CHECK-LABEL: not_a_masked_merge4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: andl %esi, %eax
+; CHECK-NEXT: retq
%and0 = and i32 %a0, %a1
%not = xor i32 %a2, -1
%and1 = and i32 %not, %a2
diff --git a/llvm/test/CodeGen/X86/setcc-combine.ll b/llvm/test/CodeGen/X86/setcc-combine.ll
index d225d420987b3..c2ee78989ba16 100644
--- a/llvm/test/CodeGen/X86/setcc-combine.ll
+++ b/llvm/test/CodeGen/X86/setcc-combine.ll
@@ -244,14 +244,9 @@ define void @test_i1_uge(ptr%A2) {
; CHECK-LABEL: test_i1_uge:
; CHECK: # %bb.0:
; CHECK-NEXT: movzbl (%rdi), %eax
-; CHECK-NEXT: movl %eax, %ecx
-; CHECK-NEXT: xorb $1, %cl
-; CHECK-NEXT: andb %cl, %al
-; CHECK-NEXT: movzbl %al, %eax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: negq %rax
-; CHECK-NEXT: andb $1, %cl
-; CHECK-NEXT: movb %cl, (%rdi,%rax)
+; CHECK-NEXT: notb %al
+; CHECK-NEXT: andb $1, %al
+; CHECK-NEXT: movb %al, (%rdi)
; CHECK-NEXT: retq
%L5 = load i1, ptr %A2
%C3 = icmp ne i1 %L5, true
More information about the llvm-commits
mailing list