mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
If we can, lower the multiply part of a umulo/smulo call to a libcall
with an invalid type then split the result and perform the overflow check normally. Fixes the 32-bit parts of rdar://8622122 and rdar://8774702. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123864 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e449d1f189
commit
38a18261b9
@ -3181,14 +3181,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
|
||||
BottomHalf = DAG.getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS,
|
||||
RHS);
|
||||
TopHalf = BottomHalf.getValue(1);
|
||||
} else {
|
||||
// FIXME: We should be able to fall back to a libcall with an illegal
|
||||
// type in some cases.
|
||||
// Also, we can fall back to a division in some cases, but that's a big
|
||||
// performance hit in the general case.
|
||||
assert(TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(),
|
||||
VT.getSizeInBits() * 2)) &&
|
||||
"Don't know how to expand this operation yet!");
|
||||
} else if (TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(),
|
||||
VT.getSizeInBits() * 2))) {
|
||||
EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2);
|
||||
LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS);
|
||||
RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS);
|
||||
@ -3197,6 +3191,31 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
|
||||
DAG.getIntPtrConstant(0));
|
||||
TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1,
|
||||
DAG.getIntPtrConstant(1));
|
||||
} else {
|
||||
// We can fall back to a libcall with an illegal type for the MUL if we
|
||||
// have a libcall big enough.
|
||||
// Also, we can fall back to a division in some cases, but that's a big
|
||||
// performance hit in the general case.
|
||||
EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2);
|
||||
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
||||
if (WideVT == MVT::i16)
|
||||
LC = RTLIB::MUL_I16;
|
||||
else if (WideVT == MVT::i32)
|
||||
LC = RTLIB::MUL_I32;
|
||||
else if (WideVT == MVT::i64)
|
||||
LC = RTLIB::MUL_I64;
|
||||
else if (WideVT == MVT::i128)
|
||||
LC = RTLIB::MUL_I128;
|
||||
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!");
|
||||
LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS);
|
||||
RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS);
|
||||
|
||||
SDValue Ops[2] = { LHS, RHS };
|
||||
SDValue Ret = ExpandLibCall(LC, Node, Ops);
|
||||
BottomHalf = DAG.getNode(ISD::TRUNCATE, dl, VT, Ret);
|
||||
TopHalf = DAG.getNode(ISD::SRL, dl, Ret.getValueType(), Ret,
|
||||
DAG.getConstant(VT.getSizeInBits(), TLI.getPointerTy()));
|
||||
TopHalf = DAG.getNode(ISD::TRUNCATE, dl, VT, TopHalf);
|
||||
}
|
||||
if (isSigned) {
|
||||
Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, TLI.getShiftAmountTy());
|
||||
|
14
test/CodeGen/ARM/umulo-32.ll
Normal file
14
test/CodeGen/ARM/umulo-32.ll
Normal file
@ -0,0 +1,14 @@
|
||||
; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s
|
||||
|
||||
%umul.ty = type { i32, i1 }
|
||||
|
||||
define i32 @func(i32 %a) nounwind {
|
||||
; CHECK: func
|
||||
; CHECK: muldi3
|
||||
%tmp0 = tail call %umul.ty @llvm.umul.with.overflow.i32(i32 %a, i32 37)
|
||||
%tmp1 = extractvalue %umul.ty %tmp0, 0
|
||||
%tmp2 = select i1 undef, i32 -1, i32 %tmp1
|
||||
ret i32 %tmp2
|
||||
}
|
||||
|
||||
declare %umul.ty @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
|
Loading…
x
Reference in New Issue
Block a user