From 833b8a2071643d0f26876b7956af3678411458e6 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 13 Oct 2016 12:05:20 +0000 Subject: [PATCH] [DAGCombiner] Add vector support to (sub -1, x) -> (xor x, -1) canonicalization Improves commutation potential llvm-svn: 284113 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 ++++++++++++- llvm/test/CodeGen/X86/combine-sub.ll | 5 ++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index fab67e779aa9..d01606e07e8b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -863,6 +863,17 @@ static bool isOneConstantOrOneSplatConstant(SDValue N) { return false; } +// Determines if it is a constant integer of all ones or a splatted vector of a +// constant integer of all ones (with no undefs). +// Do not permit build vector implicit truncation. +static bool isAllOnesConstantOrAllOnesSplatConstant(SDValue N) { + unsigned BitWidth = N.getScalarValueSizeInBits(); + if (ConstantSDNode *Splat = isConstOrConstSplat(N)) + return Splat->isAllOnesValue() && + Splat->getAPIntValue().getBitWidth() == BitWidth; + return false; +} + SDValue DAGCombiner::ReassociateOps(unsigned Opc, const SDLoc &DL, SDValue N0, SDValue N1) { EVT VT = N0.getValueType(); @@ -1938,7 +1949,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { } // Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1) - if (isAllOnesConstant(N0)) + if (isAllOnesConstantOrAllOnesSplatConstant(N0)) return DAG.getNode(ISD::XOR, DL, VT, N1, N0); // fold A-(A-B) -> B diff --git a/llvm/test/CodeGen/X86/combine-sub.ll b/llvm/test/CodeGen/X86/combine-sub.ll index 45ffc2caf65c..03978e78e48d 100644 --- a/llvm/test/CodeGen/X86/combine-sub.ll +++ b/llvm/test/CodeGen/X86/combine-sub.ll @@ -50,14 +50,13 @@ define <4 x i32> @combine_vec_sub_negone(<4 x i32> %x) { ; SSE-LABEL: combine_vec_sub_negone: ; SSE: # BB#0: ; SSE-NEXT: pcmpeqd %xmm1, %xmm1 -; SSE-NEXT: psubd %xmm0, %xmm1 -; SSE-NEXT: movdqa %xmm1, %xmm0 +; SSE-NEXT: pxor %xmm1, %xmm0 ; SSE-NEXT: retq ; ; AVX-LABEL: combine_vec_sub_negone: ; AVX: # BB#0: ; AVX-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1 -; AVX-NEXT: vpsubd %xmm0, %xmm1, %xmm0 +; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 ; AVX-NEXT: retq %1 = sub <4 x i32> , %x ret <4 x i32> %1