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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251223
91177308-0d34-0410-b5e6-
96231b3b80d8
};
+ // 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 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
Entry.isZExt = !shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned);
Args.push_back(Entry);
}
+
+ markInRegArguments(DAG, Args);
+
if (LC == RTLIB::UNKNOWN_LIBCALL)
report_fatal_error("Unsupported library call operation!");
SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
Attribute::MinSize);
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;
+ }
+}
bool isIntDivCheap(EVT VT, AttributeSet Attr) const override;
+ void markInRegArguments(SelectionDAG &DAG, TargetLowering::ArgListTy& Args)
+ const override;
+
protected:
std::pair<const TargetRegisterClass *, uint8_t>
findRepresentativeClass(const TargetRegisterInfo *TRI,
--- /dev/null
+; 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"}