From 195f3a15e61edac7c82a628b21eb459d07ad0cec Mon Sep 17 00:00:00 2001 From: Sergey Dmitrouk Date: Thu, 5 Nov 2015 18:36:42 +0000 Subject: [PATCH] [compiler-rt][aarch64] New tests for 128-bit floating-point builtins, fixes of tests and __fixuint Summary: The following tests for 128-bit floating-point type behaved in a strange way, thought it were bugs, but seem to be mistakes in tests: * `fixtfsi` test checked for `0x80000001` as a value returned for number less than can be represented, while `LONG_MIN` should be returned on saturation; * `fixunstfdi` wasn't enabled for AArch64, only for PPC, but there is nothing PPC specific in that test; * `multf3` tried to underflow multiplication by producing result with 16383 exponent, while there are still 112 bits of fraction plus implicit bit, so resultant exponent should be 16497. Tests for some other builtins didn't exist: * `fixtfdi` * `fixtfti` * `fixunstfti` They were made by copying similar files and adjusting for wider types and adding/removing some reasonable/extra checks. Also `__fixuint` seems to have off by one error, updated tests to catch this case. Reviewers: rengolin, zatrazz, howard.hinnant, t.p.northover, jmolloy, enefaim Subscribers: aemerson, llvm-commits, rengolin Differential Revision: http://reviews.llvm.org/D14187 llvm-svn: 252180 --- compiler-rt/lib/builtins/fp_fixuint_impl.inc | 2 +- compiler-rt/test/builtins/Unit/fixtfdi_test.c | 71 ++++++++++++ compiler-rt/test/builtins/Unit/fixtfsi_test.c | 2 +- compiler-rt/test/builtins/Unit/fixtfti_test.c | 83 ++++++++++++++ .../test/builtins/Unit/fixunsdfdi_test.c | 3 + .../test/builtins/Unit/fixunsdfsi_test.c | 2 + .../test/builtins/Unit/fixunsdfti_test.c | 3 + .../test/builtins/Unit/fixunssfdi_test.c | 2 + .../test/builtins/Unit/fixunssfsi_test.c | 2 + .../test/builtins/Unit/fixunstfdi_test.c | 8 +- .../test/builtins/Unit/fixunstfsi_test.c | 3 + .../test/builtins/Unit/fixunstfti_test.c | 103 ++++++++++++++++++ compiler-rt/test/builtins/Unit/multf3_test.c | 2 +- 13 files changed, 280 insertions(+), 6 deletions(-) create mode 100644 compiler-rt/test/builtins/Unit/fixtfdi_test.c create mode 100644 compiler-rt/test/builtins/Unit/fixtfti_test.c create mode 100644 compiler-rt/test/builtins/Unit/fixunstfti_test.c diff --git a/compiler-rt/lib/builtins/fp_fixuint_impl.inc b/compiler-rt/lib/builtins/fp_fixuint_impl.inc index b223c638404e..d68ccf27a79c 100644 --- a/compiler-rt/lib/builtins/fp_fixuint_impl.inc +++ b/compiler-rt/lib/builtins/fp_fixuint_impl.inc @@ -27,7 +27,7 @@ static __inline fixuint_t __fixuint(fp_t a) { return 0; // If the value is too large for the integer type, saturate. - if ((unsigned)exponent > sizeof(fixuint_t) * CHAR_BIT) + if ((unsigned)exponent >= sizeof(fixuint_t) * CHAR_BIT) return ~(fixuint_t)0; // If 0 <= exponent < significandBits, right shift to get the result. diff --git a/compiler-rt/test/builtins/Unit/fixtfdi_test.c b/compiler-rt/test/builtins/Unit/fixtfdi_test.c new file mode 100644 index 000000000000..cc25becb2f7c --- /dev/null +++ b/compiler-rt/test/builtins/Unit/fixtfdi_test.c @@ -0,0 +1,71 @@ +//===--------------- fixtfdi_test.c - Test __fixtfdi ----------------------===// +// +// 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 __fixtfdi for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include "int_lib.h" +#include + +#if __LDBL_MANT_DIG__ == 113 + +#include "fp_test.h" + +di_int __fixtfdi(long double a); + +int test__fixtfdi(long double a, di_int expected) +{ + di_int x = __fixtfdi(a); + int ret = (x != expected); + + if (ret) + { + printf("error in test__fixtfdi(%.20Lf) = %llX, " + "expected %llX\n", a, x, expected); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LDBL_MANT_DIG__ == 113 + if (test__fixtfdi(makeInf128(), 0x7fffffffffffffffLL)) + return 1; + if (test__fixtfdi(0, 0x0)) + return 1; + if (test__fixtfdi(0x1.23456789abcdefp+5L, 0x24LL)) + return 1; + if (test__fixtfdi(0x1.23456789abcdefp-3L, 0x0LL)) + return 1; + if (test__fixtfdi(0x1.23456789abcdef12345678p+20L, 0x123456LL)) + return 1; + if (test__fixtfdi(0x1.23456789abcdef12345678p+40L, 0x123456789abLL)) + return 1; + if (test__fixtfdi(0x1.23456789abcdef12345678p+60L, 0x123456789abcdef1LL)) + return 1; + if (test__fixtfdi(0x1.23456789abcdefp+256L, 0x7fffffffffffffffLL)) + return 1; + if (test__fixtfdi(-0x1.23456789abcdefp+20L, 0xffffffffffedcbaaLL)) + return 1; + if (test__fixtfdi(-0x1.23456789abcdefp+40L, 0xfffffedcba987655LL)) + return 1; + if (test__fixtfdi(-0x1.23456789abcdefp+256L, 0x8000000000000000LL)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} diff --git a/compiler-rt/test/builtins/Unit/fixtfsi_test.c b/compiler-rt/test/builtins/Unit/fixtfsi_test.c index 45ad0d243785..1da516bd07e6 100644 --- a/compiler-rt/test/builtins/Unit/fixtfsi_test.c +++ b/compiler-rt/test/builtins/Unit/fixtfsi_test.c @@ -54,7 +54,7 @@ int main() return 1; if (test__fixtfsi(-0x1.23456789abcdefp+20, 0xffedcbaa)) return 1; - if (test__fixtfsi(-0x1.23456789abcdefp+40, 0x80000001)) + if (test__fixtfsi(-0x1.23456789abcdefp+40, 0x80000000)) return 1; #else diff --git a/compiler-rt/test/builtins/Unit/fixtfti_test.c b/compiler-rt/test/builtins/Unit/fixtfti_test.c new file mode 100644 index 000000000000..52184ca624e1 --- /dev/null +++ b/compiler-rt/test/builtins/Unit/fixtfti_test.c @@ -0,0 +1,83 @@ +//===--------------- fixtfti_test.c - Test __fixtfti ----------------------===// +// +// 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 __fixtfti for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include "int_lib.h" +#include + +#if __LDBL_MANT_DIG__ == 113 + +#include "fp_test.h" + +ti_int __fixtfti(long double a); + +int test__fixtfti(long double a, ti_int expected) +{ + ti_int x = __fixtfti(a); + int ret = (x != expected); + + if (ret) + { + twords xt; + xt.all = x; + + twords expectedt; + expectedt.all = expected; + + printf("error in test__fixtfti(%.20Lf) = 0x%.16llX%.16llX, " + "expected 0x%.16llX%.16llX\n", + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LDBL_MANT_DIG__ == 113 + if (test__fixtfti(makeInf128(), make_ti(0x7fffffffffffffffLL, + 0xffffffffffffffffLL))) + return 1; + if (test__fixtfti(0, make_ti(0x0LL, 0x0LL))) + return 1; + if (test__fixtfti(0x1.23456789abcdefp+5L, make_ti(0x0LL, 0x24LL))) + return 1; + if (test__fixtfti(0x1.23456789abcdefp-3L, make_ti(0x0LL, 0x0LL))) + return 1; + if (test__fixtfti(0x1.23456789abcdef12345678p+20L, + make_ti(0x0LL, 0x123456LL))) + return 1; + if (test__fixtfti(0x1.23456789abcdef123456789abcdep+112L, + make_ti(0x123456789abcdLL, 0xef123456789abcdeLL))) + return 1; + if (test__fixtfti(-0x1.23456789abcdef123456789abcdep+112L, + make_ti(0xFFFEDCBA98765432LL, 0x10EDCBA987654322LL))) + return 1; + if (test__fixtfti(0x1.23456789abcdefp+256L, make_ti(0x7fffffffffffffffLL, + 0xffffffffffffffffLL))) + return 1; + if (test__fixtfti(-0x1.23456789abcdefp+20L, make_ti(0xffffffffffffffffLL, + 0xffffffffffedcbaaLL))) + return 1; + if (test__fixtfti(-0x1.23456789abcdefp+256L, make_ti(0x8000000000000000LL, + 0x0))) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} diff --git a/compiler-rt/test/builtins/Unit/fixunsdfdi_test.c b/compiler-rt/test/builtins/Unit/fixunsdfdi_test.c index 3998482876f3..1ddc5340b03d 100644 --- a/compiler-rt/test/builtins/Unit/fixunsdfdi_test.c +++ b/compiler-rt/test/builtins/Unit/fixunsdfdi_test.c @@ -95,6 +95,9 @@ int main() if (test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800LL)) return 1; + if (test__fixunsdfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFFLL)) + return 1; + #if !TARGET_LIBGCC if (test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0)) return 1; diff --git a/compiler-rt/test/builtins/Unit/fixunsdfsi_test.c b/compiler-rt/test/builtins/Unit/fixunsdfsi_test.c index 551fc88a5241..8d3d6304f473 100644 --- a/compiler-rt/test/builtins/Unit/fixunsdfsi_test.c +++ b/compiler-rt/test/builtins/Unit/fixunsdfsi_test.c @@ -75,6 +75,8 @@ int main() if (test__fixunsdfsi(0x1.000000p+31, 0x80000000)) return 1; + if (test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF)) + return 1; if (test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00)) return 1; if (test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80)) diff --git a/compiler-rt/test/builtins/Unit/fixunsdfti_test.c b/compiler-rt/test/builtins/Unit/fixunsdfti_test.c index e1aa56d7631e..0298fb9e9447 100644 --- a/compiler-rt/test/builtins/Unit/fixunsdfti_test.c +++ b/compiler-rt/test/builtins/Unit/fixunsdfti_test.c @@ -115,6 +115,9 @@ int main() return 1; if (test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, make_ti(0x7FFFFFFFFFFFF800LL, 0))) return 1; + if (test__fixunsdfti(0x1.0000000000000p+128, make_ti(0xFFFFFFFFFFFFFFFFLL, + 0xFFFFFFFFFFFFFFFFLL))) + return 1; #if !TARGET_LIBGCC if (test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0)) diff --git a/compiler-rt/test/builtins/Unit/fixunssfdi_test.c b/compiler-rt/test/builtins/Unit/fixunssfdi_test.c index 812457a002de..166153cb5b51 100644 --- a/compiler-rt/test/builtins/Unit/fixunssfdi_test.c +++ b/compiler-rt/test/builtins/Unit/fixunssfdi_test.c @@ -79,6 +79,8 @@ int main() return 1; if (test__fixunssfdi(0x1.000000p+63F, 0x8000000000000000LL)) return 1; + if (test__fixunssfdi(0x1.000000p+64F, 0xFFFFFFFFFFFFFFFFLL)) + return 1; if (test__fixunssfdi(0x1.FFFFFEp+62F, 0x7FFFFF8000000000LL)) return 1; if (test__fixunssfdi(0x1.FFFFFCp+62F, 0x7FFFFF0000000000LL)) diff --git a/compiler-rt/test/builtins/Unit/fixunssfsi_test.c b/compiler-rt/test/builtins/Unit/fixunssfsi_test.c index 94a8b0867eca..17293e438528 100644 --- a/compiler-rt/test/builtins/Unit/fixunssfsi_test.c +++ b/compiler-rt/test/builtins/Unit/fixunssfsi_test.c @@ -75,6 +75,8 @@ int main() if (test__fixunssfsi(0x1.000000p+31F, 0x80000000)) return 1; + if (test__fixunssfsi(0x1.000000p+32F, 0xFFFFFFFF)) + return 1; if (test__fixunssfsi(0x1.FFFFFEp+31F, 0xFFFFFF00)) return 1; if (test__fixunssfsi(0x1.FFFFFEp+30F, 0x7FFFFF80)) diff --git a/compiler-rt/test/builtins/Unit/fixunstfdi_test.c b/compiler-rt/test/builtins/Unit/fixunstfdi_test.c index 60ea503d2778..817c59b2d5d4 100644 --- a/compiler-rt/test/builtins/Unit/fixunstfdi_test.c +++ b/compiler-rt/test/builtins/Unit/fixunstfdi_test.c @@ -13,14 +13,14 @@ #include -#if _ARCH_PPC +#if _ARCH_PPC || __aarch64__ #include "int_lib.h" // Returns: convert a to a unsigned long long, rounding toward zero. // Negative values all become zero. -// Assumption: long double is a ppc 128 bit floating point type +// Assumption: long double is a 128 bit floating point type // du_int is a 64 bit integral type // value in long double is representable in du_int or is negative // (no range checking performed) @@ -44,7 +44,7 @@ char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0}; int main() { -#if _ARCH_PPC +#if _ARCH_PPC || __aarch64__ if (test__fixunstfdi(0.0, 0)) return 1; @@ -107,6 +107,8 @@ int main() return 1; if (test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62L, 0x7FFFFFFFFFFFFFFELL)) return 1; + if (test__fixunstfdi(0x1.p+64L, 0xFFFFFFFFFFFFFFFFLL)) + return 1; if (test__fixunstfdi(-0x1.0000000000000000p+63L, 0)) return 1; diff --git a/compiler-rt/test/builtins/Unit/fixunstfsi_test.c b/compiler-rt/test/builtins/Unit/fixunstfsi_test.c index 4bf8fdec607c..13ed77952248 100644 --- a/compiler-rt/test/builtins/Unit/fixunstfsi_test.c +++ b/compiler-rt/test/builtins/Unit/fixunstfsi_test.c @@ -56,6 +56,9 @@ int main() if (test__fixunstfsi(-0x1.23456789abcdefp+3, UINT32_C(0x0))) return 1; + if (test__fixunstfsi(0x1.p+32, 0xFFFFFFFFLL)) + return 1; + #else printf("skipped\n"); diff --git a/compiler-rt/test/builtins/Unit/fixunstfti_test.c b/compiler-rt/test/builtins/Unit/fixunstfti_test.c new file mode 100644 index 000000000000..60a0982b6266 --- /dev/null +++ b/compiler-rt/test/builtins/Unit/fixunstfti_test.c @@ -0,0 +1,103 @@ +//===-- fixunstfti_test.c - Test __fixunstfti -----------------------------===// +// +// 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 __fixunstfti for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include + +#if __LDBL_MANT_DIG__ == 113 + +#include "fp_test.h" +#include "int_lib.h" + +// Returns: convert a to a unsigned long long, rounding toward zero. +// Negative values all become zero. + +// Assumption: long double is a 128 bit floating point type +// tu_int is a 128 bit integral type +// value in long double is representable in tu_int or is negative +// (no range checking performed) + +COMPILER_RT_ABI tu_int __fixunstfti(long double a); + +int test__fixunstfti(long double a, tu_int expected) +{ + tu_int x = __fixunstfti(a); + if (x != expected) + { + twords xt; + xt.all = x; + + twords expectedt; + expectedt.all = expected; + + printf("error in __fixunstfti(%.20Lf) = 0x%.16llX%.16llX, " + "expected 0x%.16llX%.16llX\n", + a, xt.s.high, xt.s.low, expectedt.s.high, expectedt.s.low); + } + return x != expected; +} + +char assumption_1[sizeof(tu_int) == 4*sizeof(su_int)] = {0}; +char assumption_2[sizeof(tu_int)*CHAR_BIT == 128] = {0}; +char assumption_3[sizeof(long double)*CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LDBL_MANT_DIG__ == 113 + if (test__fixunstfti(makeInf128(), make_ti(0xffffffffffffffffLL, + 0xffffffffffffffffLL))) + return 1; + + if (test__fixunstfti(0.0, 0)) + return 1; + + if (test__fixunstfti(0.5, 0)) + return 1; + if (test__fixunstfti(0.99, 0)) + return 1; + if (test__fixunstfti(1.0, 1)) + return 1; + if (test__fixunstfti(1.5, 1)) + return 1; + if (test__fixunstfti(1.99, 1)) + return 1; + if (test__fixunstfti(2.0, 2)) + return 1; + if (test__fixunstfti(2.01, 2)) + return 1; + if (test__fixunstfti(-0.01, 0)) + return 1; + if (test__fixunstfti(-0.99, 0)) + return 1; + + if (test__fixunstfti(0x1.p+128, make_ti(0xffffffffffffffffLL, + 0xffffffffffffffffLL))) + return 1; + + if (test__fixunstfti(0x1.FFFFFEp+126, make_ti(0x7fffff8000000000LL, 0x0))) + return 1; + if (test__fixunstfti(0x1.FFFFFEp+127, make_ti(0xffffff0000000000LL, 0x0))) + return 1; + if (test__fixunstfti(0x1.FFFFFEp+128, make_ti(0xffffffffffffffffLL, + 0xffffffffffffffffLL))) + return 1; + if (test__fixunstfti(0x1.FFFFFEp+129, make_ti(0xffffffffffffffffLL, + 0xffffffffffffffffLL))) + return 1; + +#else + printf("skipped\n"); +#endif + return 0; +} diff --git a/compiler-rt/test/builtins/Unit/multf3_test.c b/compiler-rt/test/builtins/Unit/multf3_test.c index 98a8f7a3231e..42147550c702 100644 --- a/compiler-rt/test/builtins/Unit/multf3_test.c +++ b/compiler-rt/test/builtins/Unit/multf3_test.c @@ -82,7 +82,7 @@ int main() return 1; // underflow if (test__multf3(0x1.23456734245345p-10000L, - 0x1.edcba524498724p-6383L, + 0x1.edcba524498724p-6497L, UINT64_C(0x0), UINT64_C(0x0))) return 1;