From 5cfd78fc8510b04bcb68b5b243f198c3f9e961df Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sat, 28 Jan 2017 23:52:09 +0000 Subject: [PATCH] [X86] Fix vector ANDN matching to work correctly when both inputs to the AND are XORs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293403 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 19 +++++++------------ test/CodeGen/X86/vec_logical.ll | 12 ++++-------- test/CodeGen/X86/vsplit-and.ll | 8 ++++---- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 8d4399cbc8b..1d0cefc3214 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -30656,20 +30656,15 @@ static SDValue combineANDXORWithAllOnesIntoANDNP(SDNode *N, SelectionDAG &DAG) { if (VT != MVT::v2i64 && VT != MVT::v4i64 && VT != MVT::v8i64) return SDValue(); - // Canonicalize XOR to the left. - if (N1.getOpcode() == ISD::XOR) - std::swap(N0, N1); - - if (N0.getOpcode() != ISD::XOR) - return SDValue(); + if (N0.getOpcode() == ISD::XOR && + ISD::isBuildVectorAllOnes(N0.getOperand(1).getNode())) + return DAG.getNode(X86ISD::ANDNP, DL, VT, N0.getOperand(0), N1); - SDValue N00 = N0->getOperand(0); - SDValue N01 = N0->getOperand(1); + if (N1.getOpcode() == ISD::XOR && + ISD::isBuildVectorAllOnes(N1.getOperand(1).getNode())) + return DAG.getNode(X86ISD::ANDNP, DL, VT, N1.getOperand(0), N0); - if (!ISD::isBuildVectorAllOnes(N01.getNode())) - return SDValue(); - - return DAG.getNode(X86ISD::ANDNP, DL, VT, N00, N1); + return SDValue(); } // On AVX/AVX2 the type v8i1 is legalized to v8i16, which is an XMM sized diff --git a/test/CodeGen/X86/vec_logical.ll b/test/CodeGen/X86/vec_logical.ll index fb9db449ac9..92ec76009f6 100644 --- a/test/CodeGen/X86/vec_logical.ll +++ b/test/CodeGen/X86/vec_logical.ll @@ -89,18 +89,14 @@ entry: define <2 x i64> @andn_double_xor(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) { ; SSE-LABEL: andn_double_xor: ; SSE: # BB#0: -; SSE-NEXT: pcmpeqd %xmm3, %xmm3 -; SSE-NEXT: pxor %xmm3, %xmm0 -; SSE-NEXT: pxor %xmm2, %xmm1 -; SSE-NEXT: pand %xmm1, %xmm0 +; SSE-NEXT: xorps %xmm2, %xmm1 +; SSE-NEXT: andnps %xmm1, %xmm0 ; SSE-NEXT: retl ; ; AVX-LABEL: andn_double_xor: ; AVX: # BB#0: -; AVX-NEXT: vpcmpeqd %xmm3, %xmm3, %xmm3 -; AVX-NEXT: vpxor %xmm3, %xmm0, %xmm0 -; AVX-NEXT: vpxor %xmm2, %xmm1, %xmm1 -; AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 +; AVX-NEXT: vxorps %xmm2, %xmm1, %xmm1 +; AVX-NEXT: vandnps %xmm1, %xmm0, %xmm0 ; AVX-NEXT: retl %1 = xor <2 x i64> %a, %2 = xor <2 x i64> %b, %c diff --git a/test/CodeGen/X86/vsplit-and.ll b/test/CodeGen/X86/vsplit-and.ll index 05d6c60b88f..e6269822197 100644 --- a/test/CodeGen/X86/vsplit-and.ll +++ b/test/CodeGen/X86/vsplit-and.ll @@ -6,11 +6,11 @@ define void @t0(<2 x i64>* %dst, <2 x i64> %src1, <2 x i64> %src2) nounwind read ; CHECK: # BB#0: ; CHECK-NEXT: pxor %xmm2, %xmm2 ; CHECK-NEXT: pcmpeqq %xmm2, %xmm0 -; CHECK-NEXT: pcmpeqd %xmm3, %xmm3 -; CHECK-NEXT: pxor %xmm0, %xmm3 ; CHECK-NEXT: pcmpeqq %xmm2, %xmm1 -; CHECK-NEXT: pandn %xmm3, %xmm1 -; CHECK-NEXT: movdqa %xmm1, (%rdi) +; CHECK-NEXT: pcmpeqd %xmm2, %xmm2 +; CHECK-NEXT: pxor %xmm1, %xmm2 +; CHECK-NEXT: pandn %xmm2, %xmm0 +; CHECK-NEXT: movdqa %xmm0, (%rdi) ; CHECK-NEXT: retq %cmp1 = icmp ne <2 x i64> %src1, zeroinitializer %cmp2 = icmp ne <2 x i64> %src2, zeroinitializer -- 2.50.1