summaryrefslogtreecommitdiff
path: root/test/builtins/Unit/compiler_rt_logbf_test.c
diff options
context:
space:
mode:
authorJordan Rupprecht <rupprecht@google.com>2018-09-24 20:39:19 +0000
committerJordan Rupprecht <rupprecht@google.com>2018-09-24 20:39:19 +0000
commitb58a8aade2854d2f0fb3aaef91203ae9b647fe49 (patch)
treefb6eae16860dadea91d3e7fae5bc7330d64caa75 /test/builtins/Unit/compiler_rt_logbf_test.c
parent51ddca93afde5779cdaa5f96c4bebaf6384bed76 (diff)
downloadcompiler-rt-b58a8aade2854d2f0fb3aaef91203ae9b647fe49.tar.gz
[compiler-rt] [builtins] Add logb/logbf/logbl methods to compiler-rt to avoid libm dependencies when possible.
Summary: The complex division builtins (div?c3) use logb methods from libm to scale numbers during division and avoid rounding issues. However, these come from libm, meaning anyone that uses --rtlib=compiler-rt also has to include -lm. Implement logb* methods for standard ieee 754 floats so we can avoid -lm on those platforms, falling back to the old behavior (using either logb() or `__builtin_logb()`) when not supported. These new methods are defined internally as `__compiler_rt_logb` so as not to conflict with the libm definitions in any way. This fixes just the libm methods mentioned in PR32279 and PR28652. libc is still required, although that seems to not be an issue. Note: this is proposed as an alternative to just adding -lm: D49330. Reviewers: efriedma, compnerd, scanon, echristo Reviewed By: echristo Subscribers: jsji, echristo, nemanjai, dberris, mgorny, kbarton, delcypher, llvm-commits, #sanitizers Differential Revision: https://reviews.llvm.org/D49514 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@342917 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/builtins/Unit/compiler_rt_logbf_test.c')
-rw-r--r--test/builtins/Unit/compiler_rt_logbf_test.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/test/builtins/Unit/compiler_rt_logbf_test.c b/test/builtins/Unit/compiler_rt_logbf_test.c
new file mode 100644
index 000000000..cca8d4c74
--- /dev/null
+++ b/test/builtins/Unit/compiler_rt_logbf_test.c
@@ -0,0 +1,63 @@
+// RUN: %clang_builtins %s %librt -lm -o %t && %run %t
+//===-- compiler_rt_logbf_test.c - Test __compiler_rt_logbf ---------------===//
+//
+// 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 checks __compiler_rt_logbf from the compiler_rt library for
+// conformance against libm.
+//
+//===----------------------------------------------------------------------===//
+
+#define SINGLE_PRECISION
+#include <math.h>
+#include <stdio.h>
+#include "fp_lib.h"
+
+int test__compiler_rt_logbf(fp_t x) {
+ fp_t crt_value = __compiler_rt_logbf(x);
+ fp_t libm_value = logbf(x);
+ // Compare actual rep, e.g. to avoid NaN != the same NaN
+ if (toRep(crt_value) != toRep(libm_value)) {
+ printf("error: in __compiler_rt_logb(%a [%X]) = %a [%X] != %a [%X]\n", x,
+ toRep(x), crt_value, toRep(crt_value), libm_value,
+ toRep(libm_value));
+ return 1;
+ }
+ return 0;
+}
+
+double cases[] = {
+ 1.e-6, -1.e-6, NAN, -NAN, INFINITY, -INFINITY, -1,
+ -0.0, 0.0, 1, -2, 2, -0.5, 0.5,
+};
+
+int main() {
+ const unsigned N = sizeof(cases) / sizeof(cases[0]);
+ unsigned i;
+ for (i = 0; i < N; ++i) {
+ if (test__compiler_rt_logbf(cases[i])) return 1;
+ }
+
+ // Test a moving 1 bit, especially to handle denormal values.
+ // Test the negation as well.
+ rep_t x = signBit;
+ while (x) {
+ if (test__compiler_rt_logbf(fromRep(x))) return 1;
+ if (test__compiler_rt_logbf(fromRep(signBit ^ x))) return 1;
+ x >>= 1;
+ }
+ // Also try a couple moving ones
+ x = signBit | (signBit >> 1) | (signBit >> 2);
+ while (x) {
+ if (test__compiler_rt_logbf(fromRep(x))) return 1;
+ if (test__compiler_rt_logbf(fromRep(signBit ^ x))) return 1;
+ x >>= 1;
+ }
+
+ return 0;
+}