aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-06-23 15:15:44 +0000
committerDuncan Sands <baldrick@free.fr>2008-06-23 15:15:44 +0000
commite9c80f4d576bf1ff682958d447c1a60fa9348da3 (patch)
treefefc22785eedc0e5c061e745e72154c89a45f707
parent4a307ecce68f90e0eebf1ded52b947816cdc2304 (diff)
Port some integer multiplication fixes from LegalizeDAG.
Bail out with an error if there is no libcall available for the given size of integer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52622 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp32
1 files changed, 24 insertions, 8 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 44125065f0..d8dd4ed49e 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1203,14 +1203,13 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
GetExpandedInteger(N->getOperand(0), LL, LH);
GetExpandedInteger(N->getOperand(1), RL, RH);
unsigned OuterBitSize = VT.getSizeInBits();
- unsigned BitSize = NVT.getSizeInBits();
+ unsigned InnerBitSize = NVT.getSizeInBits();
unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
- if (DAG.MaskedValueIsZero(N->getOperand(0),
- APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
- DAG.MaskedValueIsZero(N->getOperand(1),
- APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
+ APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
+ if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
+ DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
// The inputs are both zero-extended.
if (HasUMUL_LOHI) {
// We can emit a umul_lohi.
@@ -1225,7 +1224,7 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
return;
}
}
- if (LHSSB > BitSize && RHSSB > BitSize) {
+ if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
// The input values are both sign-extended.
if (HasSMUL_LOHI) {
// We can emit a smul_lohi.
@@ -1252,12 +1251,29 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
return;
}
+ if (HasMULHU) {
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ 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);
+ return;
+ }
}
// If nothing else, we can make a libcall.
+ RTLIB::Libcall LC;
+ switch (VT.getSimpleVT()) {
+ default:
+ assert(false && "Unsupported MUL!");
+ case MVT::i64:
+ LC = RTLIB::MUL_I64;
+ break;
+ }
+
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
- SplitInteger(MakeLibCall(RTLIB::MUL_I64, VT, Ops, 2, true/*sign irrelevant*/),
- Lo, Hi);
+ SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi);
}
void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,