From 9f3313109f416f937b8de4c6af06b1d48c8fb377 Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Wed, 25 Sep 2013 19:01:01 +0000 Subject: Teach DAGCombiner how to canonicalize dags according to the rule (shl (zext (shr A, X)), X) => (zext (shl (shr A, X), X)). The rule only triggers when there are no other uses of the zext to avoid materializing more instructions. This helps the DAGCombiner understand that the shl/shr sequence can then be converted into an and instruction. llvm-svn: 191393 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'llvm/lib') diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d5f3e9c53e2..dda35f65c2a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3748,6 +3748,26 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { } } + // fold (shl (zext (srl x, C)), C) -> (zext (shl (srl x, C), C)) + // Only fold this if the inner zext has no other uses to avoid increasing + // the total number of instructions. + if (N1C && N0.getOpcode() == ISD::ZERO_EXTEND && N0.hasOneUse() && + N0.getOperand(0).getOpcode() == ISD::SRL && + isa(N0.getOperand(0)->getOperand(1))) { + uint64_t c1 = + cast(N0.getOperand(0)->getOperand(1))->getZExtValue(); + if (c1 < VT.getSizeInBits()) { + uint64_t c2 = N1C->getZExtValue(); + if (c1 == c2) { + SDValue NewOp0 = N0.getOperand(0); + EVT ShiftVT = NewOp0.getValueType(); + SDValue NewSHL = DAG.getNode(ISD::SHL, SDLoc(N), ShiftVT, + NewOp0, DAG.getConstant(c2, ShiftVT)); + return DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N0), VT, NewSHL); + } + } + } + // fold (shl (srl x, c1), c2) -> (and (shl x, (sub c2, c1), MASK) or // (and (srl x, (sub c1, c2), MASK) // Only fold this if the inner shift has no other uses -- if it does, folding -- cgit v1.2.3