Properly emit _fltused with FastISel. Refactor to share code with SDAG.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Wed, 22 Feb 2012 19:06:13 +0000 (19:06 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Wed, 22 Feb 2012 19:06:13 +0000 (19:06 +0000)
Patch by Joe Groff!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151183 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/FunctionLoweringInfo.h
include/llvm/CodeGen/MachineModuleInfo.h
lib/CodeGen/MachineModuleInfo.cpp
lib/CodeGen/SelectionDAG/FastISel.cpp
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/Target/X86/X86AsmPrinter.cpp
test/CodeGen/X86/fltused.ll
test/CodeGen/X86/fltused_function_pointer.ll [new file with mode: 0644]

index 804435aef7edf5b4b320c95849300e3207014c5d..432fafd95d4f4862ec65311196e2669ca2f24087 100644 (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,
index 2bf7f1788f8a2fdc6f5836b61cb476507fe813d8..6b88d4a9499b455c8284038a77263e67e8a225bf 100644 (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
index d6df6e292c2c8a4ad815475896cdf193ea937d86..ea98b23c6d57387ea3db706fa91e505c35f0506c 100644 (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);
index dce3389b014098d7ac689680c49b7b3e6d6c233b..fd8ce7865415a4a6de0518697268e039bfb039ff 100644 (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;
 
index 1b969a16af8efa8b70b5a112edbd38a633cd5a03..fd8051e7ba2d82a25d5723af9ec7ac078bc9be9d 100644 (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,
index 524a91a6daa9a4844457dffc2c3a0efa501bf0f0..e2375dac4b97fb25aa180dd232ad3d96a825f345 100644 (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()) {
index c61ad729d9863784d8dce074a88264774444a616..268cbf41f35a7c098f8ce2c543f8c0f752e7b1ac 100644 (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);
index 2ffcb966782afdc9ce57022853afaa7f24860bdd..81511a33f5cb1c31ff7394f233588d36b5381d55 100644 (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"
 
diff --git a/test/CodeGen/X86/fltused_function_pointer.ll b/test/CodeGen/X86/fltused_function_pointer.ll
new file mode 100644 (file)
index 0000000..cfe484a
--- /dev/null
@@ -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