summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-04-11 03:01:51 +0000
committerNate Begeman <natebegeman@mac.com>2005-04-11 03:01:51 +0000
commitc7c16575fea9aeffe8a63ddabe7c3c25f81ed799 (patch)
treec7bbf9e67628c7f11d133f5260634ca814dc6c6f /lib/CodeGen
parent2bb6f412820cad829e1dd3ea4bd8a1b26c8c23b6 (diff)
downloadllvm-c7c16575fea9aeffe8a63ddabe7c3c25f81ed799.tar.gz
llvm-c7c16575fea9aeffe8a63ddabe7c3c25f81ed799.tar.bz2
llvm-c7c16575fea9aeffe8a63ddabe7c3c25f81ed799.tar.xz
Fix libcall code to not pass a NULL Chain to LowerCallTo
Fix libcall code to not crash or assert looking for an ADJCALLSTACKUP node when it is known that there is no ADJCALLSTACKDOWN to match. Expand i64 multiply when ISD::MULHU is legal for the target. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21214 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index d5d707b87a..e1d9836f81 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -910,6 +910,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
+ case ISD::MULHS:
+ case ISD::MULHU:
case ISD::UDIV:
case ISD::SDIV:
case ISD::AND:
@@ -1678,12 +1680,20 @@ static SDNode *FindAdjCallStackUp(SDNode *Node) {
static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain,
SDOperand Entry) {
SDNode *LatestAdjCallStackDown = Entry.Val;
+ SDNode *LatestAdjCallStackUp = 0;
FindLatestAdjCallStackDown(OpNode, LatestAdjCallStackDown);
//std::cerr << "Found node: "; LatestAdjCallStackDown->dump(); std::cerr <<"\n";
-
- SDNode *LatestAdjCallStackUp = FindAdjCallStackUp(LatestAdjCallStackDown);
-
-
+
+ // It is possible that no ISD::ADJCALLSTACKDOWN was found because there is no
+ // previous call in the function. LatestCallStackDown may in that case be
+ // the entry node itself. Do not attempt to find a matching ADJCALLSTACKUP
+ // unless LatestCallStackDown is an ADJCALLSTACKDOWN.
+ if (LatestAdjCallStackDown->getOpcode() == ISD::ADJCALLSTACKDOWN)
+ LatestAdjCallStackUp = FindAdjCallStackUp(LatestAdjCallStackDown);
+ else
+ LatestAdjCallStackUp = Entry.Val;
+ assert(LatestAdjCallStackUp && "NULL return from FindAdjCallStackUp");
+
SDNode *EarliestAdjCallStackUp = 0;
FindEarliestAdjCallStackUp(OpNode, EarliestAdjCallStackUp);
@@ -2042,7 +2052,22 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
ExpandByParts(ISD::SUB_PARTS, Node->getOperand(0), Node->getOperand(1),
Lo, Hi);
break;
- case ISD::MUL: Lo = ExpandLibCall("__muldi3" , Node, Hi); break;
+ case ISD::MUL: {
+ if (TLI.getOperationAction(ISD::MULHU, NVT) == TargetLowering::Legal) {
+ 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);
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ } else {
+ Lo = ExpandLibCall("__muldi3" , Node, Hi); break;
+ }
+ break;
+ }
case ISD::SDIV: Lo = ExpandLibCall("__divdi3" , Node, Hi); break;
case ISD::UDIV: Lo = ExpandLibCall("__udivdi3", Node, Hi); break;
case ISD::SREM: Lo = ExpandLibCall("__moddi3" , Node, Hi); break;