From: Craig Topper Date: Sun, 24 Dec 2017 02:05:18 +0000 (+0000) Subject: [DAGCombiners] Don't turn ANDs to shuffles with zero so early. Give some other combin... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8e5ca820e1151c1262c88e840ea9532a7f76a02;p=llvm [DAGCombiners] Don't turn ANDs to shuffles with zero so early. Give some other combines a chance to run. This moves the combine for turning ANDs into shuffle with zero out of SimplifyVBinOps and places it only in visitAND below the reassociate handling. This fixes the specific case I noticed where we failed to combine two ands with constants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321417 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 17f907eb07e..388663eb1db 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3987,6 +3987,12 @@ SDValue DAGCombiner::visitAND(SDNode *N) { // reassociate and if (SDValue RAND = ReassociateOps(ISD::AND, SDLoc(N), N0, N1)) return RAND; + + // Try to convert a constant mask AND into a shuffle clear mask. + if (VT.isVector()) + if (SDValue Shuffle = XformToShuffleWithZero(N)) + return Shuffle; + // fold (and (or x, C), D) -> D if (C & D) == D auto MatchSubset = [](ConstantSDNode *LHS, ConstantSDNode *RHS) { return RHS->getAPIntValue().isSubsetOf(LHS->getAPIntValue()); @@ -16480,6 +16486,8 @@ SDValue DAGCombiner::visitFP16_TO_FP(SDNode *N) { /// e.g. AND V, <0xffffffff, 0, 0xffffffff, 0>. ==> /// vector_shuffle V, Zero, <0, 4, 2, 4> SDValue DAGCombiner::XformToShuffleWithZero(SDNode *N) { + assert(N->getOpcode() == ISD::AND && "Unexpected opcode!"); + EVT VT = N->getValueType(0); SDValue LHS = N->getOperand(0); SDValue RHS = peekThroughBitcast(N->getOperand(1)); @@ -16490,9 +16498,6 @@ SDValue DAGCombiner::XformToShuffleWithZero(SDNode *N) { if (LegalOperations) return SDValue(); - if (N->getOpcode() != ISD::AND) - return SDValue(); - if (RHS.getOpcode() != ISD::BUILD_VECTOR) return SDValue(); @@ -16581,10 +16586,6 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { N->getOpcode(), SDLoc(LHS), LHS.getValueType(), Ops, N->getFlags())) return Fold; - // Try to convert a constant mask AND into a shuffle clear mask. - if (SDValue Shuffle = XformToShuffleWithZero(N)) - return Shuffle; - // Type legalization might introduce new shuffles in the DAG. // Fold (VBinOp (shuffle (A, Undef, Mask)), (shuffle (B, Undef, Mask))) // -> (shuffle (VBinOp (A, B)), Undef, Mask). diff --git a/test/CodeGen/X86/v8i1-masks.ll b/test/CodeGen/X86/v8i1-masks.ll index e3755de3693..a799b0e6f12 100644 --- a/test/CodeGen/X86/v8i1-masks.ll +++ b/test/CodeGen/X86/v8i1-masks.ll @@ -160,7 +160,6 @@ define <8 x i32> @and_mask_constant(<8 x i32> %v0, <8 x i32> %v1) { ; X32-AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 ; X32-AVX2-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0 ; X32-AVX2-NEXT: vpand LCPI2_0, %ymm0, %ymm0 -; X32-AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3],ymm0[4],ymm1[5],ymm0[6],ymm1[7],ymm0[8],ymm1[9],ymm0[10],ymm1[11],ymm0[12],ymm1[13],ymm0[14],ymm1[15] ; X32-AVX2-NEXT: retl ; ; X64-AVX2-LABEL: and_mask_constant: @@ -168,7 +167,6 @@ define <8 x i32> @and_mask_constant(<8 x i32> %v0, <8 x i32> %v1) { ; X64-AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1 ; X64-AVX2-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0 ; X64-AVX2-NEXT: vpand {{.*}}(%rip), %ymm0, %ymm0 -; X64-AVX2-NEXT: vpblendw {{.*#+}} ymm0 = ymm0[0],ymm1[1],ymm0[2],ymm1[3],ymm0[4],ymm1[5],ymm0[6],ymm1[7],ymm0[8],ymm1[9],ymm0[10],ymm1[11],ymm0[12],ymm1[13],ymm0[14],ymm1[15] ; X64-AVX2-NEXT: retq %m = icmp eq <8 x i32> %v0, zeroinitializer %mand = and <8 x i1> %m,