Skip to content

Commit a70878d

Browse files
committed
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 llvm-svn: 24106
1 parent 9cc9f0f commit a70878d

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,7 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
735735

736736
// fold (mul c1, c2) -> c1*c2
737737
if (N0C && N1C)
738-
return DAG.getConstant(N0C->getValue() * N1C->getValue(),
739-
N->getValueType(0));
738+
return DAG.getConstant(N0C->getValue() * N1C->getValue(), VT);
740739
// canonicalize constant to RHS
741740
if (N0C && !N1C)
742741
return DAG.getNode(ISD::MUL, VT, N1, N0);
@@ -748,9 +747,20 @@ SDOperand DAGCombiner::visitMUL(SDNode *N) {
748747
return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
749748
// fold (mul x, (1 << c)) -> x << c
750749
if (N1C && isPowerOf2_64(N1C->getValue()))
751-
return DAG.getNode(ISD::SHL, N->getValueType(0), N0,
750+
return DAG.getNode(ISD::SHL, VT, N0,
752751
DAG.getConstant(Log2_64(N1C->getValue()),
753752
TLI.getShiftAmountTy()));
753+
// fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c
754+
if (N1C && isPowerOf2_64(-N1C->getSignExtended())) {
755+
// FIXME: If the input is something that is easily negated (e.g. a
756+
// single-use add), we should put the negate there.
757+
return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT),
758+
DAG.getNode(ISD::SHL, VT, N0,
759+
DAG.getConstant(Log2_64(-N1C->getSignExtended()),
760+
TLI.getShiftAmountTy())));
761+
}
762+
763+
754764
// fold (mul (mul x, c1), c2) -> (mul x, c1*c2)
755765
if (N1C && N0.getOpcode() == ISD::MUL) {
756766
ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));

0 commit comments

Comments
 (0)