aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/MachineModuleInfo.h23
-rw-r--r--llvm/lib/CodeGen/MachineModuleInfo.cpp21
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp3
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp3
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp29
-rw-r--r--llvm/lib/Target/X86/X86AsmPrinter.cpp39
-rw-r--r--llvm/test/CodeGen/X86/fltused.ll5
-rw-r--r--llvm/test/CodeGen/X86/fltused_function_pointer.ll5
-rw-r--r--llvm/test/CodeGen/X86/fltused_math.ll18
9 files changed, 79 insertions, 67 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index 4a45243..9b81dc6 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -113,10 +113,9 @@ class MachineModuleInfo : public ImmutablePass {
/// True if debugging information is available in this module.
bool DbgInfoAvailable;
- /// 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;
+ /// True if this module is being built for windows/msvc, and uses floating
+ /// point. This is used to emit an undefined reference to _fltused.
+ bool UsesMSVCFloatingPoint;
/// True if the module calls the __morestack function indirectly, as is
/// required under the large code model on x86. This is used to emit
@@ -186,13 +185,9 @@ public:
bool hasDebugInfo() const { return DbgInfoAvailable; }
void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
- bool usesVAFloatArgument() const {
- return UsesVAFloatArgument;
- }
+ bool usesMSVCFloatingPoint() const { return UsesMSVCFloatingPoint; }
- void setUsesVAFloatArgument(bool b) {
- UsesVAFloatArgument = b;
- }
+ void setUsesMSVCFloatingPoint(bool b) { UsesMSVCFloatingPoint = b; }
bool usesMorestackAddr() const {
return UsesMorestackAddr;
@@ -257,14 +252,6 @@ public:
/// \}
}; // End class MachineModuleInfo
-//===- MMI building helpers -----------------------------------------------===//
-
-/// 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);
-
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEMODULEINFO_H
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
index 3dd4ea7..8e03b59 100644
--- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -205,7 +205,7 @@ MachineModuleInfo::~MachineModuleInfo() = default;
bool MachineModuleInfo::doInitialization(Module &M) {
ObjFileMMI = nullptr;
CurCallSite = 0;
- UsesVAFloatArgument = UsesMorestackAddr = false;
+ UsesMSVCFloatingPoint = UsesMorestackAddr = false;
HasSplitStack = HasNosplitStack = false;
AddrLabelSymbols = nullptr;
TheModule = &M;
@@ -327,22 +327,3 @@ char FreeMachineFunction::ID;
FunctionPass *llvm::createFreeMachineFunctionPass() {
return new FreeMachineFunction();
}
-
-//===- MMI building helpers -----------------------------------------------===//
-
-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 (auto i : post_order(T)) {
- if (i->isFloatingPointTy()) {
- MMI.setUsesVAFloatArgument(true);
- return;
- }
- }
- }
- }
-}
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index f98c231..30294ae 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1303,9 +1303,6 @@ bool FastISel::selectCall(const User *I) {
return true;
}
- MachineModuleInfo &MMI = FuncInfo.MF->getMMI();
- computeUsesVAFloatArgument(*Call, MMI);
-
// Handle intrinsic function calls.
if (const auto *II = dyn_cast<IntrinsicInst>(Call))
return selectIntrinsicCall(II);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 7244aac..5275dd0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6987,9 +6987,6 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
return;
}
- MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
- computeUsesVAFloatArgument(I, MMI);
-
const char *RenameFn = nullptr;
if (Function *F = I.getCalledFunction()) {
if (F->isDeclaration()) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index fb27925..9c69e7e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -41,6 +41,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -62,6 +63,7 @@
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -378,6 +380,30 @@ static void SplitCriticalSideEffectEdges(Function &Fn, DominatorTree *DT,
}
}
+static void computeUsesMSVCFloatingPoint(const Triple &TT, const Function &F,
+ MachineModuleInfo &MMI) {
+ // Only needed for MSVC
+ if (!TT.isKnownWindowsMSVCEnvironment())
+ return;
+
+ // If it's already set, nothing to do.
+ if (MMI.usesMSVCFloatingPoint())
+ return;
+
+ for (const Instruction &I : instructions(F)) {
+ if (I.getType()->isFPOrFPVectorTy()) {
+ MMI.setUsesMSVCFloatingPoint(true);
+ return;
+ }
+ for (const auto &Op : I.operands()) {
+ if (Op->getType()->isFPOrFPVectorTy()) {
+ MMI.setUsesMSVCFloatingPoint(true);
+ return;
+ }
+ }
+ }
+}
+
bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// If we already selected that function, we do not need to run SDISel.
if (mf.getProperties().hasProperty(
@@ -589,6 +615,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// Determine if there is a call to setjmp in the machine function.
MF->setExposesReturnsTwice(Fn.callsFunctionThatReturnsTwice());
+ // Determine if floating point is used for msvc
+ computeUsesMSVCFloatingPoint(TM.getTargetTriple(), Fn, MF->getMMI());
+
// Replace forward-declared registers with the registers containing
// the desired value.
MachineRegisterInfo &MRI = MF->getRegInfo();
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index f1fba09..8b5ac8f 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -682,26 +682,31 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// stripping. Since LLVM never generates code that does this, it is always
// safe to set.
OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
- return;
- }
-
- if (TT.isKnownWindowsMSVCEnvironment() && MMI->usesVAFloatArgument()) {
- StringRef SymbolName =
- (TT.getArch() == Triple::x86_64) ? "_fltused" : "__fltused";
- MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
- OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
- return;
- }
-
- if (TT.isOSBinFormatCOFF()) {
+ } else if (TT.isOSBinFormatCOFF()) {
+ if (MMI->usesMSVCFloatingPoint()) {
+ // In Windows' libcmt.lib, there is a file which is linked in only if the
+ // symbol _fltused is referenced. Linking this in causes some
+ // side-effects:
+ //
+ // 1. For x86-32, it will set the x87 rounding mode to 53-bit instead of
+ // 64-bit mantissas at program start.
+ //
+ // 2. It links in support routines for floating-point in scanf and printf.
+ //
+ // MSVC emits an undefined reference to _fltused when there are any
+ // floating point operations in the program (including calls). A program
+ // that only has: `scanf("%f", &global_float);` may fail to trigger this,
+ // but oh well...that's a documented issue.
+ StringRef SymbolName =
+ (TT.getArch() == Triple::x86) ? "__fltused" : "_fltused";
+ MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
+ OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
+ return;
+ }
emitStackMaps(SM);
- return;
- }
-
- if (TT.isOSBinFormatELF()) {
+ } else if (TT.isOSBinFormatELF()) {
emitStackMaps(SM);
FM.serializeToFaultMapSection();
- return;
}
}
diff --git a/llvm/test/CodeGen/X86/fltused.ll b/llvm/test/CodeGen/X86/fltused.ll
index f1819bb..0d020c7 100644
--- a/llvm/test/CodeGen/X86/fltused.ll
+++ b/llvm/test/CodeGen/X86/fltused.ll
@@ -1,6 +1,5 @@
-; The purpose of this test 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.
+; The purpose of this test to verify that the fltused symbol is
+; emitted when a floating point call is made on Windows.
; 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
diff --git a/llvm/test/CodeGen/X86/fltused_function_pointer.ll b/llvm/test/CodeGen/X86/fltused_function_pointer.ll
index 218b28f2..b99ff1c 100644
--- a/llvm/test/CodeGen/X86/fltused_function_pointer.ll
+++ b/llvm/test/CodeGen/X86/fltused_function_pointer.ll
@@ -1,6 +1,5 @@
-; The purpose of this test 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.
+; The purpose of this test to verify that the fltused symbol is
+; emitted when a floating point call is made on Windows.
; 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
diff --git a/llvm/test/CodeGen/X86/fltused_math.ll b/llvm/test/CodeGen/X86/fltused_math.ll
new file mode 100644
index 0000000..6f0348e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fltused_math.ll
@@ -0,0 +1,18 @@
+; The purpose of this test to verify that the fltused symbol is
+; emitted when floating point operations are used on Windows.
+
+; 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
+
+define i32 @foo(i32 %a) nounwind {
+entry:
+ %da = sitofp i32 %a to double
+ %div = fdiv double %da, 3.100000e+00
+ %res = fptosi double %div to i32
+ ret i32 %res
+}
+
+; WIN32: .globl __fltused
+; WIN64: .globl _fltused