[cfe-commits] r148992 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_32-arguments-win32.c

Eli Friedman eli.friedman at gmail.com
Wed Jan 25 14:46:34 PST 2012


Author: efriedma
Date: Wed Jan 25 16:46:34 2012
New Revision: 148992

URL: http://llvm.org/viewvc/llvm-project?rev=148992&view=rev
Log:
Add some ABI tweaks for i386-pc-win32 triple so that we return structs in an MSVC-compatible way.  Patch by Joe Groff.


Added:
    cfe/trunk/test/CodeGen/x86_32-arguments-win32.c
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=148992&r1=148991&r2=148992&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Jan 25 16:46:34 2012
@@ -389,8 +389,8 @@
           ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
-/// UseX86_MMXType - Return true if this is an MMX type that should use the special
-/// x86_mmx type.
+/// UseX86_MMXType - Return true if this is an MMX type that should use the
+/// special x86_mmx type.
 bool UseX86_MMXType(llvm::Type *IRType) {
   // If the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>, use the
   // special x86_mmx type.
@@ -418,6 +418,7 @@
   bool IsDarwinVectorABI;
   bool IsSmallStructInRegABI;
   bool IsMMXDisabled;
+  bool IsWin32FloatStructABI;
 
   static bool isRegisterSize(unsigned Size) {
     return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
@@ -447,15 +448,16 @@
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
 
-  X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m)
+  X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m, bool w)
     : ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p),
-      IsMMXDisabled(m) {}
+      IsMMXDisabled(m), IsWin32FloatStructABI(w) {}
 };
 
 class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m)
-    :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m)) {}
+  X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT,
+      bool d, bool p, bool m, bool w)
+    :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m, w)) {}
 
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                            CodeGen::CodeGenModule &CGM) const;
@@ -586,10 +588,12 @@
 
       // As a special-case, if the struct is a "single-element" struct, and
       // the field is of type "float" or "double", return it in a
-      // floating-point register.  We apply a similar transformation for
-      // pointer types to improve the quality of the generated IR.
+      // floating-point register. (MSVC does not apply this special case.)
+      // We apply a similar transformation for pointer types to improve the
+      // quality of the generated IR.
       if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext()))
-        if (SeltTy->isRealFloatingType() || SeltTy->hasPointerRepresentation())
+        if ((!IsWin32FloatStructABI && SeltTy->isRealFloatingType())
+            || SeltTy->hasPointerRepresentation())
           return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0)));
 
       // FIXME: We should be able to narrow this integer in cases with dead
@@ -2238,7 +2242,8 @@
 
     // FIXME: mingw-w64-gcc emits 128-bit struct as i128
     if (Size == 128 &&
-        getContext().getTargetInfo().getTriple().getOS() == llvm::Triple::MinGW32)
+        getContext().getTargetInfo().getTriple().getOS()
+          == llvm::Triple::MinGW32)
       return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
                                                           Size));
 
@@ -2373,7 +2378,8 @@
   ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {}
 
   bool isEABI() const {
-    StringRef Env = getContext().getTargetInfo().getTriple().getEnvironmentName();
+    StringRef Env =
+      getContext().getTargetInfo().getTriple().getEnvironmentName();
     return (Env == "gnueabi" || Env == "eabi" || Env == "androideabi");
   }
 
@@ -3591,7 +3597,8 @@
 
     if (Triple.isOSDarwin())
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(Types, true, true, DisableMMX));
+               new X86_32TargetCodeGenInfo(
+                 Types, true, true, DisableMMX, false));
 
     switch (Triple.getOS()) {
     case llvm::Triple::Cygwin:
@@ -3601,11 +3608,18 @@
     case llvm::Triple::FreeBSD:
     case llvm::Triple::OpenBSD:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX));
+               new X86_32TargetCodeGenInfo(
+                 Types, false, true, DisableMMX, false));
+
+    case llvm::Triple::Win32:
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(
+                 Types, false, true, DisableMMX, true));
 
     default:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(Types, false, false, DisableMMX));
+               new X86_32TargetCodeGenInfo(
+                 Types, false, false, DisableMMX, false));
     }
   }
 

Added: cfe/trunk/test/CodeGen/x86_32-arguments-win32.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_32-arguments-win32.c?rev=148992&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/x86_32-arguments-win32.c (added)
+++ cfe/trunk/test/CodeGen/x86_32-arguments-win32.c Wed Jan 25 16:46:34 2012
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define i64 @f1_1()
+// CHECK: define void @f1_2(i32 %a0.0, i32 %a0.1)
+struct s1 {
+  int a;
+  int b;
+};
+struct s1 f1_1(void) { while (1) {} }
+void f1_2(struct s1 a0) {}
+
+// CHECK: define i32 @f2_1()
+struct s2 {
+  short a;
+  short b;
+};
+struct s2 f2_1(void) { while (1) {} }
+
+// CHECK: define i16 @f3_1()
+struct s3 {
+  char a;
+  char b;
+};
+struct s3 f3_1(void) { while (1) {} }
+
+// CHECK: define i8 @f4_1()
+struct s4 {
+  char a:4;
+  char b:4;
+};
+struct s4 f4_1(void) { while (1) {} }
+
+// CHECK: define i64 @f5_1()
+// CHECK: define void @f5_2(double %a0.0)
+struct s5 {
+  double a;
+};
+struct s5 f5_1(void) { while (1) {} }
+void f5_2(struct s5 a0) {}
+
+// CHECK: define i32 @f6_1()
+// CHECK: define void @f6_2(float %a0.0)
+struct s6 {
+  float a;
+};
+struct s6 f6_1(void) { while (1) {} }
+void f6_2(struct s6 a0) {}
+





More information about the cfe-commits mailing list