From: Quentin Colombet Date: Fri, 21 Feb 2014 23:42:41 +0000 (+0000) Subject: [DAGCombiner] PCMP* sets its result to all ones or zeros so we can AND with the X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=0206b30ea6ca3cdd04d968ca676ccb025ef75158;p=oota-llvm.git [DAGCombiner] PCMP* sets its result to all ones or zeros so we can AND with the shifted mask rather than masking and shifting separately. The patch adds this transformation to the DAGCombiner:   (shl (and (setcc:i8v16 ...) N01C) N1C) -> (and (setcc:i8v16 ...) N01C< Patch by Adam Nemet git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201906 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index de8fbc9d789..76974c26d99 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3818,6 +3818,24 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { if (VT.isVector()) { SDValue FoldedVOp = SimplifyVBinOp(N); if (FoldedVOp.getNode()) return FoldedVOp; + + BuildVectorSDNode *N1CV = dyn_cast(N1); + // If setcc produces all-one true value then: + // (shl (and (setcc) N01CV) N1CV) -> (and (setcc) N01CV<isConstant() && + TLI.getBooleanContents(true) == + TargetLowering::ZeroOrNegativeOneBooleanContent && + N0.getOpcode() == ISD::AND) { + SDValue N00 = N0->getOperand(0); + SDValue N01 = N0->getOperand(1); + BuildVectorSDNode *N01CV = dyn_cast(N01); + + if (N01CV && N01CV->isConstant() && N00.getOpcode() == ISD::SETCC) { + SDValue C = DAG.FoldConstantArithmetic(ISD::SHL, VT, N01CV, N1CV); + if (C.getNode()) + return DAG.getNode(ISD::AND, SDLoc(N), VT, N00, C); + } + } } // fold (shl c1, c2) -> c1< @foo(<8 x i16> %a, <8 x i16> %b) { +; CHECK: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-NEXT: .short 32 +; CHECK-LABEL: foo +; CHECK-NOT: psll +entry: + %icmp = icmp eq <8 x i16> %a, %b + %zext = zext <8 x i1> %icmp to <8 x i16> + %shl = shl nuw nsw <8 x i16> %zext, + ret <8 x i16> %shl +} + +; Don't fail with an assert due to an undef in the buildvector +define <8 x i16> @bar(<8 x i16> %a, <8 x i16> %b) { +; CHECK-LABEL: bar +entry: + %icmp = icmp eq <8 x i16> %a, %b + %zext = zext <8 x i1> %icmp to <8 x i16> + %shl = shl nuw nsw <8 x i16> %zext, + ret <8 x i16> %shl +}