[compiler-rt] r245296 - [compiler-rt] Add AArch64 to CMake configuration and several missing builtins

Sergey Dmitrouk via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 06:43:37 PDT 2015


Author: sdmitrouk
Date: Tue Aug 18 08:43:37 2015
New Revision: 245296

URL: http://llvm.org/viewvc/llvm-project?rev=245296&view=rev
Log:
[compiler-rt] Add AArch64 to CMake configuration and several missing builtins

Summary:
Currently CMake doesn't build builtins for AArch64 and if one does this anyway
it's likely that at least `__multc3`, `__floatditf` and `__floatunditf` will be
missing.  There is actually more builtins to add, but these come from
different libc implementations, thus providing them makes compiler-rt for
AArch64 good enough at least for basic usage.

Builtins implementation were originally taken from FreeBSD project:

 * [[ https://reviews.freebsd.org/D2173 | __multc3 ]]
 * [[ https://reviews.freebsd.org/D2174 | __floatditf and __floatunditf ]]

Until they have been tested to find mistakes in `__float*` functions.
`__floatditf` was based on `__floatsitf`, which had the same mistakes
(fixed it in r243746).

Version of the builtins in this patch are fixed and complemented with basic
tests.  Additionally they were tested via GCC's torture (this is what revealed
these issues).

P.S. Ed (author of FreeBSD patches) asked for feedback on the list some time ago (here [[ http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-March/084064.html | here ]])
and got no response, but it seems to be worth adding these builtins as is and
extracting common part later.

Reviewers: howard.hinnant, t.p.northover, jmolloy, enefaim, rengolin, zatrazz

Subscribers: asl, emaste, samsonov, aemerson, llvm-commits, rengolin

Differential Revision: http://reviews.llvm.org/D11679

Added:
    compiler-rt/trunk/lib/builtins/floatditf.c
    compiler-rt/trunk/lib/builtins/floatunditf.c
    compiler-rt/trunk/lib/builtins/multc3.c
    compiler-rt/trunk/test/builtins/Unit/floatditf_test.c
    compiler-rt/trunk/test/builtins/Unit/floatunditf_test.c
Modified:
    compiler-rt/trunk/lib/builtins/CMakeLists.txt
    compiler-rt/trunk/test/builtins/Unit/multc3_test.c

Modified: compiler-rt/trunk/lib/builtins/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/CMakeLists.txt?rev=245296&r1=245295&r2=245296&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/builtins/CMakeLists.txt Tue Aug 18 08:43:37 2015
@@ -270,10 +270,29 @@ set(arm_SOURCES
   arm/unordsf2vfp.S
   ${GENERIC_SOURCES})
 
+set(aarch64_SOURCES
+  comparetf2.c
+  extenddftf2.c
+  extendsftf2.c
+  fixtfdi.c
+  fixtfsi.c
+  fixtfti.c
+  fixunstfdi.c
+  fixunstfsi.c
+  fixunstfti.c
+  floatditf.c
+  floatsitf.c
+  floatunditf.c
+  floatunsitf.c
+  multc3.c
+  trunctfdf2.c
+  trunctfsf2.c
+  ${GENERIC_SOURCES})
+
 add_custom_target(builtins)
 
 if (NOT WIN32 OR MINGW)
-  foreach (arch x86_64 i386 i686 arm)
+  foreach (arch x86_64 i386 i686 arm aarch64)
     if (CAN_TARGET_${arch})
       # Filter out generic versions of routines that are re-implemented in
       # architecture specific manner.  This prevents multiple definitions of the

Added: compiler-rt/trunk/lib/builtins/floatditf.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/floatditf.c?rev=245296&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/floatditf.c (added)
+++ compiler-rt/trunk/lib/builtins/floatditf.c Tue Aug 18 08:43:37 2015
@@ -0,0 +1,50 @@
+//===-- lib/floatditf.c - integer -> quad-precision conversion ----*- C -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements di_int to quad-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+COMPILER_RT_ABI fp_t __floatditf(di_int a) {
+
+    const int aWidth = sizeof a * CHAR_BIT;
+
+    // Handle zero as a special case to protect clz
+    if (a == 0)
+        return fromRep(0);
+
+    // All other cases begin by extracting the sign and absolute value of a
+    rep_t sign = 0;
+    du_int aAbs = (du_int)a;
+    if (a < 0) {
+        sign = signBit;
+        aAbs = ~(du_int)a + 1U;
+    }
+
+    // Exponent of (fp_t)a is the width of abs(a).
+    const int exponent = (aWidth - 1) - __builtin_clzll(aAbs);
+    rep_t result;
+
+    // Shift a into the significand field, rounding if it is a right-shift
+    const int shift = significandBits - exponent;
+    result = (rep_t)aAbs << shift ^ implicitBit;
+
+    // Insert the exponent
+    result += (rep_t)(exponent + exponentBias) << significandBits;
+    // Insert the sign bit and return
+    return fromRep(result | sign);
+}
+
+#endif

Added: compiler-rt/trunk/lib/builtins/floatunditf.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/floatunditf.c?rev=245296&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/floatunditf.c (added)
+++ compiler-rt/trunk/lib/builtins/floatunditf.c Tue Aug 18 08:43:37 2015
@@ -0,0 +1,40 @@
+//===-- lib/floatunditf.c - uint -> quad-precision conversion -----*- C -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements du_int to quad-precision conversion for the
+// compiler-rt library in the IEEE-754 default round-to-nearest, ties-to-even
+// mode.
+//
+//===----------------------------------------------------------------------===//
+
+#define QUAD_PRECISION
+#include "fp_lib.h"
+
+#if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT)
+COMPILER_RT_ABI fp_t __floatunditf(du_int a) {
+
+    const int aWidth = sizeof a * CHAR_BIT;
+
+    // Handle zero as a special case to protect clz
+    if (a == 0) return fromRep(0);
+
+    // Exponent of (fp_t)a is the width of abs(a).
+    const int exponent = (aWidth - 1) - __builtin_clzll(a);
+    rep_t result;
+
+    // Shift a into the significand field and clear the implicit bit.
+    const int shift = significandBits - exponent;
+    result = (rep_t)a << shift ^ implicitBit;
+
+    // Insert the exponent
+    result += (rep_t)(exponent + exponentBias) << significandBits;
+    return fromRep(result);
+}
+
+#endif

Added: compiler-rt/trunk/lib/builtins/multc3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/multc3.c?rev=245296&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/multc3.c (added)
+++ compiler-rt/trunk/lib/builtins/multc3.c Tue Aug 18 08:43:37 2015
@@ -0,0 +1,68 @@
+/* ===-- multc3.c - Implement __multc3 -------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __multc3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+#include "int_math.h"
+
+/* Returns: the product of a + ib and c + id */
+
+COMPILER_RT_ABI long double _Complex
+__multc3(long double a, long double b, long double c, long double d)
+{
+    long double ac = a * c;
+    long double bd = b * d;
+    long double ad = a * d;
+    long double bc = b * c;
+    long double _Complex z;
+    __real__ z = ac - bd;
+    __imag__ z = ad + bc;
+    if (crt_isnan(__real__ z) && crt_isnan(__imag__ z)) {
+        int recalc = 0;
+        if (crt_isinf(a) || crt_isinf(b)) {
+            a = crt_copysignl(crt_isinf(a) ? 1 : 0, a);
+            b = crt_copysignl(crt_isinf(b) ? 1 : 0, b);
+            if (crt_isnan(c))
+                c = crt_copysignl(0, c);
+            if (crt_isnan(d))
+                d = crt_copysignl(0, d);
+            recalc = 1;
+        }
+        if (crt_isinf(c) || crt_isinf(d)) {
+            c = crt_copysignl(crt_isinf(c) ? 1 : 0, c);
+            d = crt_copysignl(crt_isinf(d) ? 1 : 0, d);
+            if (crt_isnan(a))
+                a = crt_copysignl(0, a);
+            if (crt_isnan(b))
+                b = crt_copysignl(0, b);
+            recalc = 1;
+        }
+        if (!recalc && (crt_isinf(ac) || crt_isinf(bd) ||
+                          crt_isinf(ad) || crt_isinf(bc))) {
+            if (crt_isnan(a))
+                a = crt_copysignl(0, a);
+            if (crt_isnan(b))
+                b = crt_copysignl(0, b);
+            if (crt_isnan(c))
+                c = crt_copysignl(0, c);
+            if (crt_isnan(d))
+                d = crt_copysignl(0, d);
+            recalc = 1;
+        }
+        if (recalc) {
+            __real__ z = CRT_INFINITY * (a * c - b * d);
+            __imag__ z = CRT_INFINITY * (a * d + b * c);
+        }
+    }
+    return z;
+}

Added: compiler-rt/trunk/test/builtins/Unit/floatditf_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/floatditf_test.c?rev=245296&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/floatditf_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/floatditf_test.c Tue Aug 18 08:43:37 2015
@@ -0,0 +1,69 @@
+//===-- floatditf_test.c - Test __floatditf -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatditf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+#include <stdio.h>
+
+#if __LDBL_MANT_DIG__ == 113
+
+#include "fp_test.h"
+
+// Returns: long integer converted to long double
+
+COMPILER_RT_ABI long double __floatditf(long long a);
+
+int test__floatditf(long long a, uint64_t expectedHi, uint64_t expectedLo)
+{
+    long double x = __floatditf(a);
+    int ret = compareResultLD(x, expectedHi, expectedLo);
+
+    if (ret)
+        printf("error in __floatditf(%Ld) = %.20Lf, "
+               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
+    return ret;
+}
+
+char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __LDBL_MANT_DIG__ == 113
+    if (test__floatditf(0x7fffffffffffffff, UINT64_C(0x403dffffffffffff), UINT64_C(0xfffc000000000000)))
+        return 1;
+    if (test__floatditf(0x123456789abcdef1, UINT64_C(0x403b23456789abcd), UINT64_C(0xef10000000000000)))
+        return 1;
+    if (test__floatditf(0x2, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatditf(0x1, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatditf(0x0, UINT64_C(0x0), UINT64_C(0x0)))
+        return 1;
+    if (test__floatditf(0xffffffffffffffff, UINT64_C(0xbfff000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatditf(0xfffffffffffffffe, UINT64_C(0xc000000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatditf(-0x123456789abcdef1, UINT64_C(0xc03b23456789abcd), UINT64_C(0xef10000000000000)))
+        return 1;
+    if (test__floatditf(0x8000000000000000, UINT64_C(0xc03e000000000000), UINT64_C(0x0)))
+        return 1;
+
+#else
+    printf("skipped\n");
+
+#endif
+    return 0;
+}

Added: compiler-rt/trunk/test/builtins/Unit/floatunditf_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/floatunditf_test.c?rev=245296&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/floatunditf_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/floatunditf_test.c Tue Aug 18 08:43:37 2015
@@ -0,0 +1,67 @@
+//===-- floatunditf_test.c - Test __floatunditf ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __floatunditf for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <math.h>
+#include <complex.h>
+#include <stdio.h>
+
+#if __LDBL_MANT_DIG__ == 113
+
+#include "fp_test.h"
+
+// Returns: long integer converted to long double
+
+COMPILER_RT_ABI long double __floatunditf(unsigned long long a);
+
+int test__floatunditf(unsigned long long a, uint64_t expectedHi, uint64_t expectedLo)
+{
+    long double x = __floatunditf(a);
+    int ret = compareResultLD(x, expectedHi, expectedLo);
+
+    if (ret)
+        printf("error in __floatunditf(%Lu) = %.20Lf, "
+               "expected %.20Lf\n", a, x, fromRep128(expectedHi, expectedLo));
+    return ret;
+}
+
+char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
+
+#endif
+
+int main()
+{
+#if __LDBL_MANT_DIG__ == 113
+    if (test__floatunditf(0xffffffffffffffffULL, UINT64_C(0x403effffffffffff), UINT64_C(0xfffe000000000000)))
+        return 1;
+    if (test__floatunditf(0xfffffffffffffffeULL, UINT64_C(0x403effffffffffff), UINT64_C(0xfffc000000000000)))
+        return 1;
+    if (test__floatunditf(0x8000000000000000ULL, UINT64_C(0x403e000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatunditf(0x7fffffffffffffffULL, UINT64_C(0x403dffffffffffff), UINT64_C(0xfffc000000000000)))
+        return 1;
+    if (test__floatunditf(0x123456789abcdef1ULL, UINT64_C(0x403b23456789abcd), UINT64_C(0xef10000000000000)))
+        return 1;
+    if (test__floatunditf(0x2ULL, UINT64_C(0x4000000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatunditf(0x1ULL, UINT64_C(0x3fff000000000000), UINT64_C(0x0)))
+        return 1;
+    if (test__floatunditf(0x0ULL, UINT64_C(0x0), UINT64_C(0x0)))
+        return 1;
+
+#else
+    printf("skipped\n");
+
+#endif
+    return 0;
+}

Modified: compiler-rt/trunk/test/builtins/Unit/multc3_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/multc3_test.c?rev=245296&r1=245295&r2=245296&view=diff
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/multc3_test.c (original)
+++ compiler-rt/trunk/test/builtins/Unit/multc3_test.c Tue Aug 18 08:43:37 2015
@@ -13,7 +13,7 @@
 
 #include <stdio.h>
 
-#if _ARCH_PPC
+#if _ARCH_PPC || __aarch64__
 
 #include "int_lib.h"
 #include <math.h>
@@ -357,7 +357,7 @@ long double x[][2] =
 
 int main()
 {
-#if _ARCH_PPC
+#if _ARCH_PPC || __aarch64__
     const unsigned N = sizeof(x) / sizeof(x[0]);
     unsigned i, j;
     for (i = 0; i < N; ++i)




More information about the llvm-commits mailing list