aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2013-09-25 19:01:01 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2013-09-25 19:01:01 +0000
commit2ce3ac8dd8c8e43f0a1a4db1a11f452b087ca24d (patch)
treeb0c12bd05f2e2f49c3a49dad30aa5048a383776d /lib
parent070156437752179833b1e5fddd50caa03fd7c12f (diff)
downloadexternal_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.cpp20
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