forked from OSchip/llvm-project
[X86] Use correct calling convention for MCU psABI libcalls
When using the MCU psABI, compiler-generated library calls should pass some parameters in-register. However, since inreg marking for x86 is currently done by the front end, it will not be applied to backend-generated calls. This is a workaround for PR3997, which describes a similar issue for -mregparm. Differential Revision: http://reviews.llvm.org/D13977 llvm-svn: 251223
This commit is contained in:
parent
fe897623f3
commit
eaa16005af
|
@ -2437,6 +2437,13 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Mark inreg arguments for lib-calls. For normal calls this is done by
|
||||||
|
// the frontend ABI code.
|
||||||
|
virtual void markInRegArguments(SelectionDAG &DAG,
|
||||||
|
TargetLowering::ArgListTy &Args) const {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/// This function lowers an abstract call to a function into an actual call.
|
/// This function lowers an abstract call to a function into an actual call.
|
||||||
/// This returns a pair of operands. The first element is the return value
|
/// This returns a pair of operands. The first element is the return value
|
||||||
/// for the function (if RetTy is not VoidTy). The second element is the
|
/// for the function (if RetTy is not VoidTy). The second element is the
|
||||||
|
|
|
@ -100,6 +100,9 @@ TargetLowering::makeLibCall(SelectionDAG &DAG,
|
||||||
Entry.isZExt = !shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned);
|
Entry.isZExt = !shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned);
|
||||||
Args.push_back(Entry);
|
Args.push_back(Entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markInRegArguments(DAG, Args);
|
||||||
|
|
||||||
if (LC == RTLIB::UNKNOWN_LIBCALL)
|
if (LC == RTLIB::UNKNOWN_LIBCALL)
|
||||||
report_fatal_error("Unsupported library call operation!");
|
report_fatal_error("Unsupported library call operation!");
|
||||||
SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
|
SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
|
||||||
|
|
|
@ -27492,3 +27492,27 @@ bool X86TargetLowering::isIntDivCheap(EVT VT, AttributeSet Attr) const {
|
||||||
Attribute::MinSize);
|
Attribute::MinSize);
|
||||||
return OptSize && !VT.isVector();
|
return OptSize && !VT.isVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void X86TargetLowering::markInRegArguments(SelectionDAG &DAG,
|
||||||
|
TargetLowering::ArgListTy& Args) const {
|
||||||
|
// The MCU psABI requires some arguments to be passed in-register.
|
||||||
|
// For regular calls, the inreg arguments are marked by the front-end.
|
||||||
|
// However, for compiler generated library calls, we have to patch this
|
||||||
|
// up here.
|
||||||
|
if (!Subtarget->isTargetMCU() || !Args.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned FreeRegs = 3;
|
||||||
|
for (auto &Arg : Args) {
|
||||||
|
// For library functions, we do not expect any fancy types.
|
||||||
|
unsigned Size = DAG.getDataLayout().getTypeSizeInBits(Arg.Ty);
|
||||||
|
unsigned SizeInRegs = (Size + 31) / 32;
|
||||||
|
if (SizeInRegs > 2 || SizeInRegs > FreeRegs)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Arg.isInReg = true;
|
||||||
|
FreeRegs -= SizeInRegs;
|
||||||
|
if (!FreeRegs)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -917,6 +917,9 @@ namespace llvm {
|
||||||
|
|
||||||
bool isIntDivCheap(EVT VT, AttributeSet Attr) const override;
|
bool isIntDivCheap(EVT VT, AttributeSet Attr) const override;
|
||||||
|
|
||||||
|
void markInRegArguments(SelectionDAG &DAG, TargetLowering::ArgListTy& Args)
|
||||||
|
const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::pair<const TargetRegisterClass *, uint8_t>
|
std::pair<const TargetRegisterClass *, uint8_t>
|
||||||
findRepresentativeClass(const TargetRegisterInfo *TRI,
|
findRepresentativeClass(const TargetRegisterInfo *TRI,
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
; RUN: llc < %s -mtriple=i686-pc-linux-elfiamcu | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK-LABEL: test_lib_args:
|
||||||
|
; CHECK: movl %edx, %eax
|
||||||
|
; CHECK: calll __fixsfsi
|
||||||
|
define i32 @test_lib_args(float inreg %a, float inreg %b) #0 {
|
||||||
|
%ret = fptosi float %b to i32
|
||||||
|
ret i32 %ret
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { nounwind "use-soft-float"="true"}
|
Loading…
Reference in New Issue