<div dir="rtl"><div dir="ltr">Thanks!</div><div dir="ltr"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div dir="ltr">2015-10-29 0:29 GMT+02:00 Reid Kleckner via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span>:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Wed Oct 28 17:29:52 2015<br>
New Revision: 251567<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=251567&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=251567&view=rev</a><br>
Log:<br>
Fix the calling convention of Mingw64 long double values<br>
<br>
GCC uses the x87DoubleExtended model for long doubles, and passes them<br>
indirectly by address through function calls.<br>
<br>
Also replace the existing mingw-long-double assembly emitting test with<br>
an IR-level test.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Basic/Targets.cpp<br>
    cfe/trunk/lib/CodeGen/TargetInfo.cpp<br>
    cfe/trunk/test/CodeGen/mingw-long-double.c<br>
<br>
Modified: cfe/trunk/lib/Basic/Targets.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=251567&r1=251566&r2=251567&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=251567&r1=251566&r2=251567&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Basic/Targets.cpp (original)<br>
+++ cfe/trunk/lib/Basic/Targets.cpp Wed Oct 28 17:29:52 2015<br>
@@ -4009,7 +4009,13 @@ public:<br>
 class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {<br>
 public:<br>
   MinGWX86_64TargetInfo(const llvm::Triple &Triple)<br>
-      : WindowsX86_64TargetInfo(Triple) {}<br>
+      : WindowsX86_64TargetInfo(Triple) {<br>
+    // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks<br>
+    // with x86 FP ops. Weird.<br>
+    LongDoubleWidth = LongDoubleAlign = 128;<br>
+    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;<br>
+  }<br>
+<br>
   void getTargetDefines(const LangOptions &Opts,<br>
                         MacroBuilder &Builder) const override {<br>
     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=251567&r1=251566&r2=251567&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=251567&r1=251566&r2=251567&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Oct 28 17:29:52 2015<br>
@@ -1772,12 +1772,10 @@ public:<br>
<br>
 /// WinX86_64ABIInfo - The Windows X86_64 ABI information.<br>
 class WinX86_64ABIInfo : public ABIInfo {<br>
-<br>
-  ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs,<br>
-                      bool IsReturnType) const;<br>
-<br>
 public:<br>
-  WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}<br>
+  WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT)<br>
+      : ABIInfo(CGT),<br>
+        IsMingw64(getTarget().getTriple().isWindowsGNUEnvironment()) {}<br>
<br>
   void computeInfo(CGFunctionInfo &FI) const override;<br>
<br>
@@ -1794,6 +1792,12 @@ public:<br>
     // FIXME: Assumes vectorcall is in use.<br>
     return isX86VectorCallAggregateSmallEnough(NumMembers);<br>
   }<br>
+<br>
+private:<br>
+  ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs,<br>
+                      bool IsReturnType) const;<br>
+<br>
+  bool IsMingw64;<br>
 };<br>
<br>
 class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {<br>
@@ -3317,7 +3321,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu<br>
<br>
   TypeInfo Info = getContext().getTypeInfo(Ty);<br>
   uint64_t Width = Info.Width;<br>
-  unsigned Align = getContext().toCharUnitsFromBits(Info.Align).getQuantity();<br>
+  CharUnits Align = getContext().toCharUnitsFromBits(Info.Align);<br>
<br>
   const RecordType *RT = Ty->getAs<RecordType>();<br>
   if (RT) {<br>
@@ -3330,9 +3334,9 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu<br>
       return getNaturalAlignIndirect(Ty, /*ByVal=*/false);<br>
<br>
     // FIXME: mingw-w64-gcc emits 128-bit struct as i128<br>
-    if (Width == 128 && getTarget().getTriple().isWindowsGNUEnvironment())<br>
-      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),<br>
-                                                          Width));<br>
+    if (Width == 128 && IsMingw64)<br>
+      return ABIArgInfo::getDirect(<br>
+          llvm::IntegerType::get(getVMContext(), Width));<br>
   }<br>
<br>
   // vectorcall adds the concept of a homogenous vector aggregate, similar to<br>
@@ -3346,8 +3350,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu<br>
         return ABIArgInfo::getDirect();<br>
       return ABIArgInfo::getExpand();<br>
     }<br>
-    return ABIArgInfo::getIndirect(CharUnits::fromQuantity(Align),<br>
-                                   /*ByVal=*/false);<br>
+    return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);<br>
   }<br>
<br>
<br>
@@ -3375,6 +3378,14 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu<br>
   if (BT && BT->getKind() == BuiltinType::Bool)<br>
     return ABIArgInfo::getExtend();<br>
<br>
+  // Mingw64 GCC uses the old 80 bit extended precision floating point unit. It<br>
+  // passes them indirectly through memory.<br>
+  if (IsMingw64 && BT && BT->getKind() == BuiltinType::LongDouble) {<br>
+    const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();<br>
+    if (LDF == &llvm::APFloat::x87DoubleExtended)<br>
+      return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);<br>
+  }<br>
+<br>
   return ABIArgInfo::getDirect();<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/CodeGen/mingw-long-double.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mingw-long-double.c?rev=251567&r1=251566&r2=251567&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mingw-long-double.c?rev=251567&r1=251566&r2=251567&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/mingw-long-double.c (original)<br>
+++ cfe/trunk/test/CodeGen/mingw-long-double.c Wed Oct 28 17:29:52 2015<br>
@@ -1,12 +1,41 @@<br>
-// REQUIRES: x86-registered-target<br>
-// RUN: %clang_cc1 -triple i686-pc-windows-gnu -S %s  -o - | FileCheck %s -check-prefix=CHECK_I686<br>
-// CHECK_I686: _lda,12<br>
-// CHECK_I686: _lds,16<br>
-// RUN: %clang_cc1 -triple x86_64-pc-windows-gnu -S %s  -o - | FileCheck %s -check-prefix=CHECK_X86_64<br>
-// CHECK_X86_64: lda,16<br>
-// CHECK_X86_64: lds,32<br>
-long double lda;<br>
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s \<br>
+// RUN:    | FileCheck %s --check-prefix=GNU32<br>
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \<br>
+// RUN:    | FileCheck %s --check-prefix=GNU64<br>
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s \<br>
+// RUN:    | FileCheck %s --check-prefix=MSC64<br>
+<br>
 struct {<br>
   char c;<br>
   long double ldb;<br>
-} lds;<br>
+} agggregate_LD = {};<br>
+// GNU32: %struct.anon = type { i8, x86_fp80 }<br>
+// GNU32: @agggregate_LD = global %struct.anon zeroinitializer, align 4<br>
+// GNU64: %struct.anon = type { i8, x86_fp80 }<br>
+// GNU64: @agggregate_LD = global %struct.anon zeroinitializer, align 16<br>
+// MSC64: %struct.anon = type { i8, double }<br>
+// MSC64: @agggregate_LD = global %struct.anon zeroinitializer, align 8<br>
+<br>
+long double dataLD = 1.0L;<br>
+// GNU32: @dataLD = global x86_fp80 0xK3FFF8000000000000000, align 4<br>
+// GNU64: @dataLD = global x86_fp80 0xK3FFF8000000000000000, align 16<br>
+// MSC64: @dataLD = global double 1.000000e+00, align 8<br>
+<br>
+long double _Complex dataLDC = {1.0L, 1.0L};<br>
+// GNU32: @dataLDC = global { x86_fp80, x86_fp80 } { x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK3FFF8000000000000000 }, align 4<br>
+// GNU64: @dataLDC = global { x86_fp80, x86_fp80 } { x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK3FFF8000000000000000 }, align 16<br>
+// MSC64: @dataLDC = global { double, double } { double 1.000000e+00, double 1.000000e+00 }, align 8<br>
+<br>
+long double TestLD(long double x) {<br>
+  return x * x;<br>
+}<br>
+// GNU32: define x86_fp80 @TestLD(x86_fp80 %x)<br>
+// GNU64: define void @TestLD(x86_fp80* noalias sret %agg.result, x86_fp80*)<br>
+// MSC64: define double @TestLD(double %x)<br>
+<br>
+long double _Complex TestLDC(long double _Complex x) {<br>
+  return x * x;<br>
+}<br>
+// GNU32: define void @TestLDC({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %x)<br>
+// GNU64: define void @TestLDC({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* %x)<br>
+// MSC64: define void @TestLDC({ double, double }* noalias sret %agg.result, { double, double }* %x)<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>