diff options
author | Chris Lattner <sabre@nondot.org> | 2005-10-30 06:41:49 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-10-30 06:41:49 +0000 |
commit | 3e6099b05fa85d9e5d82f04f73722f2af301c772 (patch) | |
tree | fc75ec12026b7ccbec80c98902b3ba4554268202 /lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | 4446e0450949d612b40907cbd016b55c3b226c3d (diff) |
Codegen mul by negative power of two with a shift and negate.
This implements test/Regression/CodeGen/PowerPC/mul-neg-power-2.ll,
producing:
_foo:
slwi r2, r3, 1
subfic r3, r2, 63
blr
instead of:
_foo:
mulli r2, r3, -2
addi r3, r2, 63
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24106 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 412b47e2a4..048737f13e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -735,8 +735,7 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) { // fold (mul c1, c2) -> c1*c2 if (N0C && N1C) - return DAG.getConstant(N0C->getValue() * N1C->getValue(), - N->getValueType(0)); + return DAG.getConstant(N0C->getValue() * N1C->getValue(), VT); // canonicalize constant to RHS if (N0C && !N1C) return DAG.getNode(ISD::MUL, VT, N1, N0); @@ -748,9 +747,20 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) { return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0); // fold (mul x, (1 << c)) -> x << c if (N1C && isPowerOf2_64(N1C->getValue())) - return DAG.getNode(ISD::SHL, N->getValueType(0), N0, + return DAG.getNode(ISD::SHL, VT, N0, DAG.getConstant(Log2_64(N1C->getValue()), TLI.getShiftAmountTy())); + // fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c + if (N1C && isPowerOf2_64(-N1C->getSignExtended())) { + // FIXME: If the input is something that is easily negated (e.g. a + // single-use add), we should put the negate there. + return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), + DAG.getNode(ISD::SHL, VT, N0, + DAG.getConstant(Log2_64(-N1C->getSignExtended()), + TLI.getShiftAmountTy()))); + } + + // fold (mul (mul x, c1), c2) -> (mul x, c1*c2) if (N1C && N0.getOpcode() == ISD::MUL) { ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0)); |