aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-01 03:44:24 +0000
committerChris Lattner <sabre@nondot.org>2006-03-01 03:44:24 +0000
commit0b1a85f110c4ed50f7adf181490d9f6a1b4f55a5 (patch)
treef05ba8c53d1575acad18bffd1d173ca36d075b4f /lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parentcf6a9fbd9b15aa218116577726a91501727a17a1 (diff)
Pull shifts by a constant through multiplies (a form of reassociation),
implementing Regression/CodeGen/X86/mul-shift-reassoc.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26440 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5607e719d5..ee8d22cb07 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -726,6 +726,33 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
DAG.getConstant(Log2_64(-N1C->getSignExtended()),
TLI.getShiftAmountTy())));
}
+
+ // (mul (shl X, c1), c2) -> (mul X, c2 << c1)
+ if (N1C && N0.getOpcode() == ISD::SHL &&
+ isa<ConstantSDNode>(N0.getOperand(1))) {
+ SDOperand C3 = DAG.getNode(ISD::SHL, VT, N1, N0.getOperand(1));
+ return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), C3);
+ }
+
+ // Change (mul (shl X, C), Y) -> (shl (mul X, Y), C) when the shift has one
+ // use.
+ {
+ SDOperand Sh(0,0), Y(0,0);
+ // Check for both (mul (shl X, C), Y) and (mul Y, (shl X, C)).
+ if (N0.getOpcode() == ISD::SHL && isa<ConstantSDNode>(N0.getOperand(1)) &&
+ N0.Val->hasOneUse()) {
+ Sh = N0; Y = N1;
+ } else if (N1.getOpcode() == ISD::SHL &&
+ isa<ConstantSDNode>(N1.getOperand(1)) && N1.Val->hasOneUse()) {
+ Sh = N1; Y = N0;
+ }
+ if (Sh.Val) {
+ SDOperand Mul = DAG.getNode(ISD::MUL, VT, Sh.getOperand(0), Y);
+ return DAG.getNode(ISD::SHL, VT, Mul, Sh.getOperand(1));
+ }
+ }
+
+
// reassociate mul
SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1);
if (RMUL.Val != 0)