summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorEric Christopher <echristo@apple.com>2011-06-18 00:09:57 +0000
committerEric Christopher <echristo@apple.com>2011-06-18 00:09:57 +0000
commite4a1266a9a67c31c233e19a6ccea07c3baa3e068 (patch)
tree44a0b31608eab91d84e9619116fd0065f0ef7b21 /llvm/lib
parent4e4294bdeee8d41b74f8ddf671aa00952b645c3d (diff)
downloadbcm5719-llvm-e4a1266a9a67c31c233e19a6ccea07c3baa3e068.tar.gz
bcm5719-llvm-e4a1266a9a67c31c233e19a6ccea07c3baa3e068.zip
Fix UMULO support for 2x register width to allow the full
range without a libcall to a new mulo<mode> libcall that we'd have to create. Finishes the rest of rdar://9090077 and rdar://9210061 llvm-svn: 133318
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 6797bece13c..cbb8da8f18d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -2160,6 +2160,27 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N,
const Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext());
DebugLoc dl = N->getDebugLoc();
+ // A divide for UMULO should be faster than a function call.
+ if (N->getOpcode() == ISD::UMULO) {
+ SDValue LHS = N->getOperand(0), RHS = N->getOperand(1);
+ DebugLoc DL = N->getDebugLoc();
+
+ SDValue MUL = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
+ SplitInteger(MUL, Lo, Hi);
+
+ // A divide for UMULO will be faster than a function call. Select to
+ // make sure we aren't using 0.
+ SDValue isZero = DAG.getSetCC(dl, TLI.getSetCCResultType(VT),
+ RHS, DAG.getConstant(0, VT), ISD::SETNE);
+ SDValue NotZero = DAG.getNode(ISD::SELECT, dl, VT, isZero,
+ DAG.getConstant(1, VT), RHS);
+ SDValue DIV = DAG.getNode(ISD::UDIV, DL, LHS.getValueType(), MUL, NotZero);
+ SDValue Overflow;
+ Overflow = DAG.getSetCC(DL, N->getValueType(1), DIV, LHS, ISD::SETNE);
+ ReplaceValueWith(SDValue(N, 1), Overflow);
+ return;
+ }
+
// Replace this with a libcall that will check overflow.
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (VT == MVT::i32)
OpenPOWER on IntegriCloud