Properly emit _fltused with FastISel. Refactor to share code with SDAG.

Patch by Joe Groff!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151183 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael J. Spencer 2012-02-22 19:06:13 +00:00
parent 2fc0977a98
commit c9c137b463
9 changed files with 68 additions and 27 deletions

View File

@ -202,7 +202,7 @@ public:
/// setArgumentFrameIndex - Record frame index for the byval
/// argument.
void setArgumentFrameIndex(const Argument *A, int FI);
/// getArgumentFrameIndex - Get frame index for the byval argument.
int getArgumentFrameIndex(const Argument *A);
@ -211,6 +211,13 @@ private:
IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
};
/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
/// being passed to this variadic function, and set the MachineModuleInfo's
/// usesVAFloatArgument flag if so. This flag is used to emit an undefined
/// reference to _fltused on Windows, which will link in MSVCRT's
/// floating-point support.
void ComputeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo *MMI);
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
/// call, and add them to the specified machine basic block.
void AddCatchInfo(const CallInst &I,

View File

@ -161,10 +161,10 @@ class MachineModuleInfo : public ImmutablePass {
/// in this module.
bool DbgInfoAvailable;
/// CallsExternalVAFunctionWithFloatingPointArguments - True if this module
/// calls VarArg function with floating point arguments. This is used to emit
/// an undefined reference to fltused on Windows targets.
bool CallsExternalVAFunctionWithFloatingPointArguments;
/// UsesVAFloatArgument - True if this module calls VarArg function with
/// floating-point arguments. This is used to emit an undefined reference
/// to _fltused on Windows targets.
bool UsesVAFloatArgument;
public:
static char ID; // Pass identification, replacement for typeid
@ -223,12 +223,12 @@ public:
bool callsUnwindInit() const { return CallsUnwindInit; }
void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
bool callsExternalVAFunctionWithFloatingPointArguments() const {
return CallsExternalVAFunctionWithFloatingPointArguments;
bool usesVAFloatArgument() const {
return UsesVAFloatArgument;
}
void setCallsExternalVAFunctionWithFloatingPointArguments(bool b) {
CallsExternalVAFunctionWithFloatingPointArguments = b;
void setUsesVAFloatArgument(bool b) {
UsesVAFloatArgument = b;
}
/// getFrameMoves - Returns a reference to a list of moves done in the current

View File

@ -257,7 +257,7 @@ MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI,
: ImmutablePass(ID), Context(MAI, MRI, MOFI),
ObjFileMMI(0), CompactUnwindEncoding(0), CurCallSite(0), CallsEHReturn(0),
CallsUnwindInit(0), DbgInfoAvailable(false),
CallsExternalVAFunctionWithFloatingPointArguments(false) {
UsesVAFloatArgument(false) {
initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry());
// Always emit some info, by default "no personality" info.
Personalities.push_back(NULL);

View File

@ -561,6 +561,9 @@ bool FastISel::SelectCall(const User *I) {
return true;
}
MachineModuleInfo &MMI = FuncInfo.MF->getMMI();
ComputeUsesVAFloatArgument(*Call, &MMI);
const Function *F = Call->getCalledFunction();
if (!F) return false;

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "function-lowering-info"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
@ -371,6 +372,30 @@ int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) {
return 0;
}
/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
/// being passed to this variadic function, and set the MachineModuleInfo's
/// usesVAFloatArgument flag if so. This flag is used to emit an undefined
/// reference to _fltused on Windows, which will link in MSVCRT's
/// floating-point support.
void llvm::ComputeUsesVAFloatArgument(const CallInst &I,
MachineModuleInfo *MMI)
{
FunctionType *FT = cast<FunctionType>(
I.getCalledValue()->getType()->getContainedType(0));
if (FT->isVarArg() && !MMI->usesVAFloatArgument()) {
for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
Type* T = I.getArgOperand(i)->getType();
for (po_iterator<Type*> i = po_begin(T), e = po_end(T);
i != e; ++i) {
if (i->isFloatingPointTy()) {
MMI->setUsesVAFloatArgument(true);
return;
}
}
}
}
}
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
/// call, and add them to the specified machine basic block.
void llvm::AddCatchInfo(const CallInst &I, MachineModuleInfo *MMI,

View File

@ -5454,23 +5454,8 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
return;
}
// See if any floating point values are being passed to this function. This is
// used to emit an undefined reference to fltused on Windows.
FunctionType *FT =
cast<FunctionType>(I.getCalledValue()->getType()->getContainedType(0));
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
if (FT->isVarArg() &&
!MMI.callsExternalVAFunctionWithFloatingPointArguments()) {
for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) {
Type* T = I.getArgOperand(i)->getType();
for (po_iterator<Type*> i = po_begin(T), e = po_end(T);
i != e; ++i) {
if (!i->isFloatingPointTy()) continue;
MMI.setCallsExternalVAFunctionWithFloatingPointArguments(true);
break;
}
}
}
ComputeUsesVAFloatArgument(I, &MMI);
const char *RenameFn = 0;
if (Function *F = I.getCalledFunction()) {

View File

@ -600,7 +600,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
}
if (Subtarget->isTargetWindows() && !Subtarget->isTargetCygMing() &&
MMI->callsExternalVAFunctionWithFloatingPointArguments()) {
MMI->usesVAFloatArgument()) {
StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused";
MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName);
OutStreamer.EmitSymbolAttribute(S, MCSA_Global);

View File

@ -4,6 +4,8 @@
; RUN: llc < %s -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32
; RUN: llc < %s -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64
; RUN: llc < %s -O0 -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32
; RUN: llc < %s -O0 -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64
@.str = private constant [4 x i8] c"%f\0A\00"

View File

@ -0,0 +1,19 @@
; The purpose of this test to to verify that the fltused symbol is emitted when
; any function is called with floating point arguments on Windows. And that it
; is not emitted otherwise.
; RUN: llc < %s -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32
; RUN: llc < %s -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64
; RUN: llc < %s -O0 -mtriple i686-pc-win32 | FileCheck %s --check-prefix WIN32
; RUN: llc < %s -O0 -mtriple x86_64-pc-win32 | FileCheck %s --check-prefix WIN64
@.str = private constant [4 x i8] c"%f\0A\00"
define i32 @foo(i32 (i8*, ...)* %f) nounwind {
entry:
%call = tail call i32 (i8*, ...)* %f(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), double 1.000000e+000) nounwind
ret i32 0
}
; WIN32: .globl __fltused
; WIN64: .globl _fltused