Add support for FastISel'ing varargs calls.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129765 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2011-04-19 17:22:22 +00:00
parent 430721cff8
commit 3762046dbf
2 changed files with 40 additions and 4 deletions

View File

@ -1508,14 +1508,17 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
if (CC == CallingConv::Fast && GuaranteedTailCallOpt)
return false;
// Let SDISel handle vararg functions.
const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
if (FTy->isVarArg())
bool isVarArg = FTy->isVarArg();
// Don't know how to handle Win64 varargs yet. Nothing special needed for
// x86-32. Special handling for x86-64 is implemented.
if (isVarArg && Subtarget->isTargetWin64())
return false;
// Fast-isel doesn't know about callee-pop yet.
if (Subtarget->IsCalleePop(FTy->isVarArg(), CC))
if (Subtarget->IsCalleePop(isVarArg, CC))
return false;
// Handle *simple* calls for now.
@ -1623,7 +1626,7 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CC, false, TM, ArgLocs, I->getParent()->getContext());
CCState CCInfo(CC, isVarArg, TM, ArgLocs, I->getParent()->getContext());
// Allocate shadow area for Win64
if (Subtarget->isTargetWin64())
@ -1721,6 +1724,17 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
X86::EBX).addReg(Base);
}
if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64()) {
// Count the number of XMM registers allocated.
static const unsigned XMMArgRegs[] = {
X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
};
unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::MOV8ri),
X86::AL).addImm(NumXMMRegs);
}
// Issue the call.
MachineInstrBuilder MIB;
if (CalleeOp) {
@ -1775,6 +1789,9 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
if (Subtarget->isPICStyleGOT())
MIB.addReg(X86::EBX);
if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64())
MIB.addReg(X86::AL);
// Add implicit physical register uses to the call.
for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
MIB.addReg(RegArgs[i]);

View File

@ -181,3 +181,22 @@ define void @test15(i8* %a, i8* %b) nounwind {
; CHECK-NEXT: movl %eax, (%rdi)
; CHECK-NEXT: ret
}
; Handling for varargs calls
declare void @test16callee(...) nounwind
define void @test16() nounwind {
; CHECK: test16:
; CHECK: movl $1, %edi
; CHECK: movb $0, %al
; CHECK: callq _test16callee
call void (...)* @test16callee(i32 1)
br label %block2
block2:
; CHECK: movabsq $1
; CHECK: cvtsi2sdq {{.*}} %xmm0
; CHECK: movb $1, %al
; CHECK: callq _test16callee
call void (...)* @test16callee(double 1.000000e+00)
ret void
}