mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[SelectionDAG] Fix calling convention in expansion of ?MULO.
The SMULO/UMULO DAG nodes, when not directly supported by the target, expand to a multiplication twice as wide. In case that the resulting type is not legal, an __mul?i3 intrinsic is used. Since the type is not legal, the legalizer cannot directly call the intrinsic with the wide arguments; instead, it "pre-lowers" them by splitting them in halves. The "pre-lowering" code in essence made assumptions about the calling convention, specifically that i(N*2) values will be split into two iN values and passed in consecutive registers in little-endian order. This, naturally, breaks on a big-endian system, such as our OR1K out-of-tree backend. Thanks to James Miller <james@aatch.net> for help in debugging. Differential Revision: https://reviews.llvm.org/D25223 llvm-svn: 283203
This commit is contained in:
parent
45f9fcff68
commit
954b2ab4fd
@ -3470,8 +3470,18 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
// pre-lowered to the correct types. This all depends upon WideVT not
|
||||
// being a legal type for the architecture and thus has to be split to
|
||||
// two arguments.
|
||||
SDValue Args[] = { LHS, HiLHS, RHS, HiRHS };
|
||||
SDValue Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
|
||||
SDValue Ret;
|
||||
if(DAG.getDataLayout().isLittleEndian()) {
|
||||
// Halves of WideVT are packed into registers in different order
|
||||
// depending on platform endianness. This is usually handled by
|
||||
// the C calling convention, but we can't defer to it in
|
||||
// the legalizer.
|
||||
SDValue Args[] = { LHS, HiLHS, RHS, HiRHS };
|
||||
Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
|
||||
} else {
|
||||
SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
|
||||
Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
|
||||
}
|
||||
BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
|
||||
DAG.getIntPtrConstant(0, dl));
|
||||
TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
|
||||
|
Loading…
Reference in New Issue
Block a user