r345676 - [Win64] Handle passing i128 by value

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 31 07:39:02 PDT 2018


Also, don't we usually put ABI changes under an ABI compatibility check?  This would be making Clang incompatible with itself.
--paulr

From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On Behalf Of Richard Trieu via cfe-commits
Sent: Tuesday, October 30, 2018 10:16 PM
To: Reid Kleckner
Cc: cfe-commits
Subject: Re: r345676 - [Win64] Handle passing i128 by value

I have reverted this in r345691 because it caused test CodeGen/mingw-long-double.c to start failing.

Command Output (stderr):
--
/usr/local/google/clang/install/llvm/tools/clang/test/CodeGen/mingw-long-double.c:36:11: error: MSC64: expected string not found in input
// MSC64: define dso_local double @TestLD(double %x)
          ^
<stdin>:12:1: note: scanning from here
; Function Attrs: noinline nounwind optnone
^
<stdin>:35:1: note: possible intended match here
define dso_local void @TestLDC({ double, double }* noalias sret %agg.result, { double, double }* %x) #2 {
^

--

I suspect your patch has changed the type of "double" to a different floating point type, causing the failure.


On Tue, Oct 30, 2018 at 5:00 PM Reid Kleckner via cfe-commits <cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>> wrote:
Author: rnk
Date: Tue Oct 30 16:58:41 2018
New Revision: 345676

URL: http://llvm.org/viewvc/llvm-project?rev=345676&view=rev
Log:
[Win64] Handle passing i128 by value

For arguments, pass it indirectly, since the ABI doc says pretty clearly
that arguments larger than 8 bytes are passed indirectly. This makes
va_list handling easier, anyway.

When returning, GCC returns in XMM0, and we match them.

Fixes PR39492.

Added:
    cfe/trunk/test/CodeGen/win64-i128.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=345676&r1=345675&r2=345676&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Oct 30 16:58:41 2018
@@ -3944,18 +3944,39 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu
     return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Width));
   }

-  // Bool type is always extended to the ABI, other builtin types are not
-  // extended.
-  const BuiltinType *BT = Ty->getAs<BuiltinType>();
-  if (BT && BT->getKind() == BuiltinType::Bool)
-    return ABIArgInfo::getExtend(Ty);
-
-  // Mingw64 GCC uses the old 80 bit extended precision floating point unit. It
-  // passes them indirectly through memory.
-  if (IsMingw64 && BT && BT->getKind() == BuiltinType::LongDouble) {
-    const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
-    if (LDF == &llvm::APFloat::x87DoubleExtended())
-      return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
+  if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
+    switch (BT->getKind()) {
+    case BuiltinType::Bool:
+      // Bool type is always extended to the ABI, other builtin types are not
+      // extended.
+      return ABIArgInfo::getExtend(Ty);
+
+    case BuiltinType::LongDouble:
+      // Mingw64 GCC uses the old 80 bit extended precision floating point
+      // unit. It passes them indirectly through memory.
+      if (IsMingw64) {
+        const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
+        if (LDF == &llvm::APFloat::x87DoubleExtended())
+          return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
+        break;
+      }
+
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+      // If it's a parameter type, the normal ABI rule is that arguments larger
+      // than 8 bytes are passed indirectly. GCC follows it. We follow it too,
+      // even though it isn't particularly efficient.
+      if (!IsReturnType)
+        return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
+
+      // Mingw64 GCC returns i128 in XMM0. Coerce to v2i64 to handle that.
+      // Clang matches them for compatibility.
+      return ABIArgInfo::getDirect(
+          llvm::VectorType::get(llvm::Type::getInt64Ty(getVMContext()), 2));
+
+    default:
+      break;
+    }
   }

   return ABIArgInfo::getDirect();

Added: cfe/trunk/test/CodeGen/win64-i128.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/win64-i128.c?rev=345676&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/win64-i128.c (added)
+++ cfe/trunk/test/CodeGen/win64-i128.c Tue Oct 30 16:58:41 2018
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \
+// RUN:    | FileCheck %s --check-prefix=GNU64
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s \
+// RUN:    | FileCheck %s --check-prefix=MSC64
+
+typedef int int128_t __attribute__((mode(TI)));
+
+int128_t foo() { return 0; }
+
+// GNU64: define dso_local <2 x i64> @foo()
+// MSC64: define dso_local <2 x i64> @foo()
+
+int128_t bar(int128_t a, int128_t b) { return a * b; }
+
+// GNU64: define dso_local <2 x i64> @bar(i128*, i128*)
+// MSC64: define dso_local <2 x i64> @bar(i128*, i128*)


_______________________________________________
cfe-commits mailing list
cfe-commits at lists.llvm.org<mailto:cfe-commits at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181031/066e03b9/attachment-0001.html>


More information about the cfe-commits mailing list