[llvm-commits] [llvm] r67935 - in /llvm/branches/Apple/Dib: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/imul-lea-2.ll
Bill Wendling
isanbard at gmail.com
Sat Mar 28 02:09:02 PDT 2009
Author: void
Date: Sat Mar 28 04:08:59 2009
New Revision: 67935
URL: http://llvm.org/viewvc/llvm-project?rev=67935&view=rev
Log:
--- Merging (from foreign repository) r67917 into '.':
A test/CodeGen/X86/imul-lea-2.ll
U include/llvm/Target/TargetLowering.h
U lib/CodeGen/SelectionDAG/DAGCombiner.cpp
U lib/Target/X86/X86ISelLowering.cpp
Optimize some 64-bit multiplication by constants into two lea's or one lea + shl
since imulq is slow (latency 5). e.g. x * 40
=>
shlq $3, %rdi
leaq (%rdi,%rdi,4), %rax
This has the added benefit of allowing more multiply to be folded into
addressing mode. e.g. a * 24 + b
=>
leaq (%rdi,%rdi,2), %rax
leaq (%rsi,%rax,8), %rax
Added:
llvm/branches/Apple/Dib/test/CodeGen/X86/imul-lea-2.ll
Modified:
llvm/branches/Apple/Dib/include/llvm/Target/TargetLowering.h
llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp
Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetLowering.h?rev=67935&r1=67934&r2=67935&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetLowering.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetLowering.h Sat Mar 28 04:08:59 2009
@@ -791,9 +791,10 @@
bool isCalledByLegalizer() const { return CalledByLegalizer; }
void AddToWorklist(SDNode *N);
- SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To);
- SDValue CombineTo(SDNode *N, SDValue Res);
- SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1);
+ SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
+ bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
};
Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=67935&r1=67934&r2=67935&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Mar 28 04:08:59 2009
@@ -93,14 +93,14 @@
}
SDValue CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
- bool AddTo = true);
+ bool AddTo = true);
SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true) {
return CombineTo(N, &Res, 1, AddTo);
}
SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1,
- bool AddTo = true) {
+ bool AddTo = true) {
SDValue To[] = { Res0, Res1 };
return CombineTo(N, To, 2, AddTo);
}
@@ -293,19 +293,19 @@
}
SDValue TargetLowering::DAGCombinerInfo::
-CombineTo(SDNode *N, const std::vector<SDValue> &To) {
- return ((DAGCombiner*)DC)->CombineTo(N, &To[0], To.size());
+CombineTo(SDNode *N, const std::vector<SDValue> &To, bool AddTo) {
+ return ((DAGCombiner*)DC)->CombineTo(N, &To[0], To.size(), AddTo);
}
SDValue TargetLowering::DAGCombinerInfo::
-CombineTo(SDNode *N, SDValue Res) {
- return ((DAGCombiner*)DC)->CombineTo(N, Res);
+CombineTo(SDNode *N, SDValue Res, bool AddTo) {
+ return ((DAGCombiner*)DC)->CombineTo(N, Res, AddTo);
}
SDValue TargetLowering::DAGCombinerInfo::
-CombineTo(SDNode *N, SDValue Res0, SDValue Res1) {
- return ((DAGCombiner*)DC)->CombineTo(N, Res0, Res1);
+CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo) {
+ return ((DAGCombiner*)DC)->CombineTo(N, Res0, Res1, AddTo);
}
void TargetLowering::DAGCombinerInfo::
Modified: llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp?rev=67935&r1=67934&r2=67935&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/X86/X86ISelLowering.cpp Sat Mar 28 04:08:59 2009
@@ -824,6 +824,8 @@
setTargetDAGCombine(ISD::SRA);
setTargetDAGCombine(ISD::SRL);
setTargetDAGCombine(ISD::STORE);
+ if (Subtarget->is64Bit())
+ setTargetDAGCombine(ISD::MUL);
computeRegisterProperties();
@@ -8398,6 +8400,74 @@
}
+/// PerformMulCombine - Optimize a single multiply with constant into two
+/// in order to implement it with two cheaper instructions, e.g.
+/// LEA + SHL, LEA + LEA.
+static SDValue PerformMulCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ if (DAG.getMachineFunction().
+ getFunction()->hasFnAttr(Attribute::OptimizeForSize))
+ return SDValue();
+
+ if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
+ return SDValue();
+
+ MVT VT = N->getValueType(0);
+ if (VT != MVT::i64)
+ return SDValue();
+
+ ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ if (!C)
+ return SDValue();
+ uint64_t MulAmt = C->getZExtValue();
+ if (isPowerOf2_64(MulAmt) || MulAmt == 3 || MulAmt == 5 || MulAmt == 9)
+ return SDValue();
+
+ uint64_t MulAmt1 = 0;
+ uint64_t MulAmt2 = 0;
+ if ((MulAmt % 9) == 0) {
+ MulAmt1 = 9;
+ MulAmt2 = MulAmt / 9;
+ } else if ((MulAmt % 5) == 0) {
+ MulAmt1 = 5;
+ MulAmt2 = MulAmt / 5;
+ } else if ((MulAmt % 3) == 0) {
+ MulAmt1 = 3;
+ MulAmt2 = MulAmt / 3;
+ }
+ if (MulAmt2 &&
+ (isPowerOf2_64(MulAmt2) || MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9)){
+ DebugLoc DL = N->getDebugLoc();
+
+ if (isPowerOf2_64(MulAmt2) &&
+ !(N->hasOneUse() && N->use_begin()->getOpcode() == ISD::ADD))
+ // If second multiplifer is pow2, issue it first. We want the multiply by
+ // 3, 5, or 9 to be folded into the addressing mode unless the lone use
+ // is an add.
+ std::swap(MulAmt1, MulAmt2);
+
+ SDValue NewMul;
+ if (isPowerOf2_64(MulAmt1))
+ NewMul = DAG.getNode(ISD::SHL, DL, VT, N->getOperand(0),
+ DAG.getConstant(Log2_64(MulAmt1), MVT::i8));
+ else
+ NewMul = DAG.getNode(ISD::MUL, DL, VT, N->getOperand(0),
+ DAG.getConstant(MulAmt1, VT));
+
+ if (isPowerOf2_64(MulAmt2))
+ NewMul = DAG.getNode(ISD::SHL, DL, VT, NewMul,
+ DAG.getConstant(Log2_64(MulAmt2), MVT::i8));
+ else
+ NewMul = DAG.getNode(ISD::MUL, DL, VT, NewMul,
+ DAG.getConstant(MulAmt2, VT));
+
+ // Do not add new nodes to DAG combiner worklist.
+ DCI.CombineTo(N, NewMul, false);
+ }
+ return SDValue();
+}
+
+
/// PerformShiftCombine - Transforms vector shift nodes to use vector shifts
/// when possible.
static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG,
@@ -8659,6 +8729,7 @@
return PerformBuildVectorCombine(N, DAG, DCI, Subtarget, *this);
case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget);
case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI);
+ case ISD::MUL: return PerformMulCombine(N, DAG, DCI);
case ISD::SHL:
case ISD::SRA:
case ISD::SRL: return PerformShiftCombine(N, DAG, Subtarget);
Added: llvm/branches/Apple/Dib/test/CodeGen/X86/imul-lea-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/imul-lea-2.ll?rev=67935&view=auto
==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/imul-lea-2.ll (added)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/imul-lea-2.ll Sat Mar 28 04:08:59 2009
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | llc -march=x86-64 | grep lea | count 3
+; RUN: llvm-as < %s | llc -march=x86-64 | grep shl | count 1
+; RUN: llvm-as < %s | llc -march=x86-64 | not grep imul
+
+define i64 @t1(i64 %a) nounwind readnone {
+entry:
+ %0 = mul i64 %a, 81 ; <i64> [#uses=1]
+ ret i64 %0
+}
+
+define i64 @t2(i64 %a) nounwind readnone {
+entry:
+ %0 = mul i64 %a, 40 ; <i64> [#uses=1]
+ ret i64 %0
+}
More information about the llvm-commits
mailing list