From 0206b30ea6ca3cdd04d968ca676ccb025ef75158 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Fri, 21 Feb 2014 23:42:41 +0000 Subject: [PATCH] [DAGCombiner] PCMP* sets its result to all ones or zeros so we can AND with the shifted mask rather than masking and shifting separately. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 18 ++++++++++++++ test/CodeGen/X86/shift-pcmp.ll | 30 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 test/CodeGen/X86/shift-pcmp.ll 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 +} -- 2.34.1