Skip to content

Commit 7c4fe0e

Browse files
committed
[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 <[email protected]> for help in debugging. Differential Revision: https://reviews.llvm.org/D25223 llvm-svn: 283203
1 parent d2a6d7b commit 7c4fe0e

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,8 +3470,18 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
34703470
// pre-lowered to the correct types. This all depends upon WideVT not
34713471
// being a legal type for the architecture and thus has to be split to
34723472
// two arguments.
3473-
SDValue Args[] = { LHS, HiLHS, RHS, HiRHS };
3474-
SDValue Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3473+
SDValue Ret;
3474+
if(DAG.getDataLayout().isLittleEndian()) {
3475+
// Halves of WideVT are packed into registers in different order
3476+
// depending on platform endianness. This is usually handled by
3477+
// the C calling convention, but we can't defer to it in
3478+
// the legalizer.
3479+
SDValue Args[] = { LHS, HiLHS, RHS, HiRHS };
3480+
Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3481+
} else {
3482+
SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
3483+
Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl);
3484+
}
34753485
BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,
34763486
DAG.getIntPtrConstant(0, dl));
34773487
TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret,

0 commit comments

Comments
 (0)