diff options
author | Craig Topper <craig.topper@intel.com> | 2018-07-25 01:15:38 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-07-25 01:15:38 +0000 |
commit | fc501a9223e2e8ea8202fca06a58d6750f9a73a8 (patch) | |
tree | 2007115b77209bcbda67553e301153c7f97b7d4f /llvm/lib | |
parent | 5be253d9886479f158904feeeebdce62a34019d4 (diff) | |
download | bcm5719-llvm-fc501a9223e2e8ea8202fca06a58d6750f9a73a8.tar.gz bcm5719-llvm-fc501a9223e2e8ea8202fca06a58d6750f9a73a8.zip |
[X86] Use a shift plus an lea for multiplying by a constant that is a power of 2 plus 2/4/8.
The LEA allows us to combine an add and the multiply by 2/4/8 together so we just need a shift for the larger power of 2.
llvm-svn: 337875
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index fc29069ffdd..c7deffd5619 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -33749,6 +33749,24 @@ static SDValue combineMulSpecial(uint64_t MulAmt, SDNode *N, SelectionDAG &DAG, return DAG.getNode(ISD::ADD, DL, VT, N->getOperand(0), combineMulMulAddOrSub(9, 3, /*isAdd*/ true)); } + + // Another trick. If this is a power 2 + 2/4/8, we can use a shift followed + // by a single LEA. + // First check if this a sum of two power of 2s because that's easy. Then + // count how many zeros are up to the first bit. + // TODO: We can do this even without LEA at a cost of two shifts and an add. + if (isPowerOf2_64(MulAmt & (MulAmt - 1))) { + unsigned ScaleShift = countTrailingZeros(MulAmt); + if (ScaleShift >= 1 && ScaleShift < 4) { + unsigned ShiftAmt = Log2_64((MulAmt & (MulAmt - 1))); + SDValue Shift1 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0), + DAG.getConstant(ShiftAmt, DL, MVT::i8)); + SDValue Shift2 = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0), + DAG.getConstant(ScaleShift, DL, MVT::i8)); + return DAG.getNode(ISD::ADD, DL, VT, Shift1, Shift2); + } + } + return SDValue(); } |