diff options
| author | Nate Begeman <natebegeman@mac.com> | 2005-08-30 02:44:00 +0000 |
|---|---|---|
| committer | Nate Begeman <natebegeman@mac.com> | 2005-08-30 02:44:00 +0000 |
| commit | 43144a2fe04beaac68c7235d02c03c7862a411d9 (patch) | |
| tree | 92cc9dd9b6080e7131229494d8eee6a058f27e7f /llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | |
| parent | c9d1e370a538c09971f390abcb5b0645551956c2 (diff) | |
| download | bcm5719-llvm-43144a2fe04beaac68c7235d02c03c7862a411d9.tar.gz bcm5719-llvm-43144a2fe04beaac68c7235d02c03c7862a411d9.zip | |
Add support for AssertSext and AssertZext, folding other extensions with
them. This allows for elminination of redundant extends in the entry
blocks of functions on PowerPC.
Add support for i32 x i32 -> i64 multiplies, by recognizing when the inputs
to ISD::MUL in ExpandOp are actually just extended i32 values and not real
i64 values. this allows us to codegen
int mulhs(int a, int b) { return ((long long)a * b) >> 32; }
as:
_mulhs:
mulhw r3, r4, r3
blr
instead of:
_mulhs:
mulhwu r2, r4, r3
srawi r5, r3, 31
mullw r5, r4, r5
add r2, r2, r5
srawi r4, r4, 31
mullw r3, r4, r3
add r3, r2, r3
blr
with a similar improvement on x86.
llvm-svn: 23147
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 695ae23777d..9480ed6f096 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -456,6 +456,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { assert(0 && "Do not know how to legalize this operator!"); abort(); case ISD::EntryToken: + case ISD::AssertSext: + case ISD::AssertZext: case ISD::FrameIndex: case ISD::GlobalAddress: case ISD::ExternalSymbol: @@ -3158,11 +3160,28 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ SDOperand LL, LH, RL, RH; ExpandOp(Node->getOperand(0), LL, LH); ExpandOp(Node->getOperand(1), RL, RH); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + unsigned SH = MVT::getSizeInBits(RH.getValueType())-1; + // MULHS implicitly sign extends its inputs. Check to see if ExpandOp + // extended the sign bit of the low half through the upper half, and if so + // emit a MULHS instead of the alternate sequence that is valid for any + // i64 x i64 multiply. + if (TLI.isOperationLegal(ISD::MULHS, NVT) && + // is RH an extension of the sign bit of RL? + RH.getOpcode() == ISD::SRA && RH.getOperand(0) == RL && + RH.getOperand(1).getOpcode() == ISD::Constant && + cast<ConstantSDNode>(RH.getOperand(1))->getValue() == SH && + // is LH an extension of the sign bit of LL? + LH.getOpcode() == ISD::SRA && LH.getOperand(0) == LL && + LH.getOperand(1).getOpcode() == ISD::Constant && + cast<ConstantSDNode>(LH.getOperand(1))->getValue() == SH) { + Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); + } else { + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + } Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); } else { Lo = ExpandLibCall("__muldi3" , Node, Hi); break; |

