[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