diff options
| author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2013-09-25 19:01:01 +0000 |
|---|---|---|
| committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2013-09-25 19:01:01 +0000 |
| commit | 2ce3ac8dd8c8e43f0a1a4db1a11f452b087ca24d (patch) | |
| tree | b0c12bd05f2e2f49c3a49dad30aa5048a383776d /lib | |
| parent | 070156437752179833b1e5fddd50caa03fd7c12f (diff) | |
| download | external_llvm-2ce3ac8dd8c8e43f0a1a4db1a11f452b087ca24d.zip external_llvm-2ce3ac8dd8c8e43f0a1a4db1a11f452b087ca24d.tar.gz external_llvm-2ce3ac8dd8c8e43f0a1a4db1a11f452b087ca24d.tar.bz2 | |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191393 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d5f3e9c..dda35f6 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/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<ConstantSDNode>(N0.getOperand(0)->getOperand(1))) { + uint64_t c1 = + cast<ConstantSDNode>(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 |
