Skip to content

Commit

Permalink
[DAG] visitXOR - fold XOR(A,B) -> OR(A,B) iff A and B have no common …
Browse files Browse the repository at this point in the history
…bits

Alive2: https://alive2.llvm.org/ce/z/7wvfns

Part of Issue #58624
  • Loading branch information
RKSimon committed Oct 28, 2022
1 parent fcfc31f commit d47f056
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 70 deletions.
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8618,6 +8618,11 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
if (SDValue RXOR = reassociateOps(ISD::XOR, DL, N0, N1, N->getFlags()))
return RXOR;

// fold (a^b) -> (a|b) iff a and b share no bits.
if ((!LegalOperations || TLI.isOperationLegal(ISD::OR, VT)) &&
DAG.haveNoCommonBitsSet(N0, N1))
return DAG.getNode(ISD::OR, DL, VT, N0, N1);

// look for 'add-like' folds:
// XOR(N0,MIN_SIGNED_VALUE) == ADD(N0,MIN_SIGNED_VALUE)
if ((!LegalOperations || TLI.isOperationLegal(ISD::ADD, VT)) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,7 @@ define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
; CHECK-LABEL: in_constant_mone_vary:
; CHECK: // %bb.0:
; CHECK-NEXT: bic w8, w2, w1
; CHECK-NEXT: eor w0, w8, w1
; CHECK-NEXT: orr w0, w2, w1
; CHECK-NEXT: ret
%n0 = xor i32 -1, %y ; %x
%n1 = and i32 %n0, %mask
Expand All @@ -477,9 +476,7 @@ define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
; CHECK-LABEL: in_constant_mone_vary_invmask:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn w8, w1
; CHECK-NEXT: bic w8, w8, w2
; CHECK-NEXT: eor w0, w8, w1
; CHECK-NEXT: orn w0, w1, w2
; CHECK-NEXT: ret
%notmask = xor i32 %mask, -1
%n0 = xor i32 -1, %y ; %x
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ define <4 x i32> @out_constant_mone_vary(<4 x i32> %x, <4 x i32> %y, <4 x i32> %
define <4 x i32> @in_constant_mone_vary(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
; CHECK-LABEL: in_constant_mone_vary:
; CHECK: // %bb.0:
; CHECK-NEXT: bic v0.16b, v2.16b, v1.16b
; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
; CHECK-NEXT: orr v0.16b, v2.16b, v1.16b
; CHECK-NEXT: ret
%n0 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %y ; %x
%n1 = and <4 x i32> %n0, %mask
Expand All @@ -153,9 +152,7 @@ define <4 x i32> @out_constant_mone_vary_invmask(<4 x i32> %x, <4 x i32> %y, <4
define <4 x i32> @in_constant_mone_vary_invmask(<4 x i32> %x, <4 x i32> %y, <4 x i32> %mask) {
; CHECK-LABEL: in_constant_mone_vary_invmask:
; CHECK: // %bb.0:
; CHECK-NEXT: mvn v0.16b, v1.16b
; CHECK-NEXT: bic v0.16b, v0.16b, v2.16b
; CHECK-NEXT: eor v0.16b, v0.16b, v1.16b
; CHECK-NEXT: orn v0.16b, v1.16b, v2.16b
; CHECK-NEXT: ret
%notmask = xor <4 x i32> %mask, <i32 -1, i32 -1, i32 -1, i32 -1>
%n0 = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %y ; %x
Expand Down
24 changes: 6 additions & 18 deletions llvm/test/CodeGen/RISCV/unfold-masked-merge-scalar-variablemask.ll
Original file line number Diff line number Diff line change
Expand Up @@ -759,18 +759,10 @@ define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
}

define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
; CHECK-I-LABEL: in_constant_mone_vary:
; CHECK-I: # %bb.0:
; CHECK-I-NEXT: not a0, a1
; CHECK-I-NEXT: and a0, a0, a2
; CHECK-I-NEXT: xor a0, a0, a1
; CHECK-I-NEXT: ret
;
; CHECK-ZBB-LABEL: in_constant_mone_vary:
; CHECK-ZBB: # %bb.0:
; CHECK-ZBB-NEXT: andn a0, a2, a1
; CHECK-ZBB-NEXT: xor a0, a0, a1
; CHECK-ZBB-NEXT: ret
; CHECK-LABEL: in_constant_mone_vary:
; CHECK: # %bb.0:
; CHECK-NEXT: or a0, a2, a1
; CHECK-NEXT: ret
%n0 = xor i32 -1, %y ; %x
%n1 = and i32 %n0, %mask
%r = xor i32 %n1, %y
Expand Down Expand Up @@ -803,16 +795,12 @@ define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
; CHECK-I-LABEL: in_constant_mone_vary_invmask:
; CHECK-I: # %bb.0:
; CHECK-I-NEXT: not a0, a2
; CHECK-I-NEXT: not a2, a1
; CHECK-I-NEXT: and a0, a2, a0
; CHECK-I-NEXT: xor a0, a0, a1
; CHECK-I-NEXT: or a0, a0, a1
; CHECK-I-NEXT: ret
;
; CHECK-ZBB-LABEL: in_constant_mone_vary_invmask:
; CHECK-ZBB: # %bb.0:
; CHECK-ZBB-NEXT: not a0, a1
; CHECK-ZBB-NEXT: andn a0, a0, a2
; CHECK-ZBB-NEXT: xor a0, a0, a1
; CHECK-ZBB-NEXT: orn a0, a1, a2
; CHECK-ZBB-NEXT: ret
%notmask = xor i32 %mask, -1
%n0 = xor i32 -1, %y ; %x
Expand Down
20 changes: 8 additions & 12 deletions llvm/test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll
Original file line number Diff line number Diff line change
Expand Up @@ -733,15 +733,13 @@ define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) {
; CHECK-NOBMI-LABEL: in_constant_mone_vary:
; CHECK-NOBMI: # %bb.0:
; CHECK-NOBMI-NEXT: movl %esi, %eax
; CHECK-NOBMI-NEXT: notl %eax
; CHECK-NOBMI-NEXT: andl %edx, %eax
; CHECK-NOBMI-NEXT: xorl %esi, %eax
; CHECK-NOBMI-NEXT: orl %edx, %eax
; CHECK-NOBMI-NEXT: retq
;
; CHECK-BMI-LABEL: in_constant_mone_vary:
; CHECK-BMI: # %bb.0:
; CHECK-BMI-NEXT: andnl %edx, %esi, %eax
; CHECK-BMI-NEXT: xorl %esi, %eax
; CHECK-BMI-NEXT: movl %esi, %eax
; CHECK-BMI-NEXT: orl %edx, %eax
; CHECK-BMI-NEXT: retq
%n0 = xor i32 -1, %y ; %x
%n1 = and i32 %n0, %mask
Expand Down Expand Up @@ -775,18 +773,16 @@ define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) {
; CHECK-NOBMI-LABEL: in_constant_mone_vary_invmask:
; CHECK-NOBMI: # %bb.0:
; CHECK-NOBMI-NEXT: notl %edx
; CHECK-NOBMI-NEXT: movl %esi, %eax
; CHECK-NOBMI-NEXT: movl %edx, %eax
; CHECK-NOBMI-NEXT: notl %eax
; CHECK-NOBMI-NEXT: andl %edx, %eax
; CHECK-NOBMI-NEXT: xorl %esi, %eax
; CHECK-NOBMI-NEXT: orl %esi, %eax
; CHECK-NOBMI-NEXT: retq
;
; CHECK-BMI-LABEL: in_constant_mone_vary_invmask:
; CHECK-BMI: # %bb.0:
; CHECK-BMI-NEXT: notl %edx
; CHECK-BMI-NEXT: andnl %edx, %esi, %eax
; CHECK-BMI-NEXT: xorl %esi, %eax
; CHECK-BMI-NEXT: movl %edx, %eax
; CHECK-BMI-NEXT: notl %eax
; CHECK-BMI-NEXT: orl %esi, %eax
; CHECK-BMI-NEXT: retq
%notmask = xor i32 %mask, -1
%n0 = xor i32 -1, %y ; %x
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,26 +336,21 @@ define <4 x i32> @in_constant_mone_vary(ptr%px, ptr%py, ptr%pmask) {
; CHECK-SSE1-LABEL: in_constant_mone_vary:
; CHECK-SSE1: # %bb.0:
; CHECK-SSE1-NEXT: movq %rdi, %rax
; CHECK-SSE1-NEXT: movaps (%rdx), %xmm0
; CHECK-SSE1-NEXT: movaps %xmm0, %xmm1
; CHECK-SSE1-NEXT: andnps (%rcx), %xmm1
; CHECK-SSE1-NEXT: xorps %xmm0, %xmm1
; CHECK-SSE1-NEXT: movaps %xmm1, (%rdi)
; CHECK-SSE1-NEXT: movaps (%rcx), %xmm0
; CHECK-SSE1-NEXT: orps (%rdx), %xmm0
; CHECK-SSE1-NEXT: movaps %xmm0, (%rdi)
; CHECK-SSE1-NEXT: retq
;
; CHECK-SSE2-LABEL: in_constant_mone_vary:
; CHECK-SSE2: # %bb.0:
; CHECK-SSE2-NEXT: movaps (%rsi), %xmm1
; CHECK-SSE2-NEXT: movaps %xmm1, %xmm0
; CHECK-SSE2-NEXT: andnps (%rdx), %xmm0
; CHECK-SSE2-NEXT: xorps %xmm1, %xmm0
; CHECK-SSE2-NEXT: movaps (%rdx), %xmm0
; CHECK-SSE2-NEXT: orps (%rsi), %xmm0
; CHECK-SSE2-NEXT: retq
;
; CHECK-XOP-LABEL: in_constant_mone_vary:
; CHECK-XOP: # %bb.0:
; CHECK-XOP-NEXT: vmovaps (%rsi), %xmm0
; CHECK-XOP-NEXT: vandnps (%rdx), %xmm0, %xmm1
; CHECK-XOP-NEXT: vxorps %xmm0, %xmm1, %xmm0
; CHECK-XOP-NEXT: vmovaps (%rdx), %xmm0
; CHECK-XOP-NEXT: vorps (%rsi), %xmm0, %xmm0
; CHECK-XOP-NEXT: retq
%x = load <4 x i32>, ptr%px, align 16
%y = load <4 x i32>, ptr%py, align 16
Expand Down Expand Up @@ -411,32 +406,24 @@ define <4 x i32> @in_constant_mone_vary_invmask(ptr%px, ptr%py, ptr%pmask) {
; CHECK-SSE1-LABEL: in_constant_mone_vary_invmask:
; CHECK-SSE1: # %bb.0:
; CHECK-SSE1-NEXT: movq %rdi, %rax
; CHECK-SSE1-NEXT: movaps (%rdx), %xmm0
; CHECK-SSE1-NEXT: movaps (%rcx), %xmm1
; CHECK-SSE1-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
; CHECK-SSE1-NEXT: movaps %xmm0, %xmm2
; CHECK-SSE1-NEXT: andnps %xmm1, %xmm2
; CHECK-SSE1-NEXT: xorps %xmm0, %xmm2
; CHECK-SSE1-NEXT: movaps %xmm2, (%rdi)
; CHECK-SSE1-NEXT: movaps (%rcx), %xmm0
; CHECK-SSE1-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
; CHECK-SSE1-NEXT: orps (%rdx), %xmm0
; CHECK-SSE1-NEXT: movaps %xmm0, (%rdi)
; CHECK-SSE1-NEXT: retq
;
; CHECK-SSE2-LABEL: in_constant_mone_vary_invmask:
; CHECK-SSE2: # %bb.0:
; CHECK-SSE2-NEXT: movdqa (%rsi), %xmm1
; CHECK-SSE2-NEXT: pcmpeqd %xmm2, %xmm2
; CHECK-SSE2-NEXT: pxor (%rdx), %xmm2
; CHECK-SSE2-NEXT: movdqa %xmm1, %xmm0
; CHECK-SSE2-NEXT: pandn %xmm2, %xmm0
; CHECK-SSE2-NEXT: pxor %xmm1, %xmm0
; CHECK-SSE2-NEXT: pcmpeqd %xmm0, %xmm0
; CHECK-SSE2-NEXT: pxor (%rdx), %xmm0
; CHECK-SSE2-NEXT: por (%rsi), %xmm0
; CHECK-SSE2-NEXT: retq
;
; CHECK-XOP-LABEL: in_constant_mone_vary_invmask:
; CHECK-XOP: # %bb.0:
; CHECK-XOP-NEXT: vmovdqa (%rsi), %xmm0
; CHECK-XOP-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
; CHECK-XOP-NEXT: vpxor (%rdx), %xmm1, %xmm1
; CHECK-XOP-NEXT: vpandn %xmm1, %xmm0, %xmm1
; CHECK-XOP-NEXT: vpxor %xmm0, %xmm1, %xmm0
; CHECK-XOP-NEXT: vpcmpeqd %xmm0, %xmm0, %xmm0
; CHECK-XOP-NEXT: vpxor (%rdx), %xmm0, %xmm0
; CHECK-XOP-NEXT: vpor (%rsi), %xmm0, %xmm0
; CHECK-XOP-NEXT: retq
%x = load <4 x i32>, ptr%px, align 16
%y = load <4 x i32>, ptr%py, align 16
Expand Down

0 comments on commit d47f056

Please sign in to comment.