diff options
author | Pirama Arumuga Nainar <pirama@google.com> | 2015-06-23 20:24:53 +0000 |
---|---|---|
committer | Pirama Arumuga Nainar <pirama@google.com> | 2015-06-23 20:24:53 +0000 |
commit | 4a39e80809f6160fbf95e4a6cbc4161346db50a6 (patch) | |
tree | 7bcb568465cf6e40d8eccb41abd38428b0bc4696 | |
parent | 2aec6216cb8d61bd5e7a22234e40be8780e2414d (diff) | |
download | bcm5719-llvm-4a39e80809f6160fbf95e4a6cbc4161346db50a6.tar.gz bcm5719-llvm-4a39e80809f6160fbf95e4a6cbc4161346db50a6.zip |
Fix incorrect truncation at the overflow boundary
Summary:
This patch fixes incorrect truncation when the input wider value is
exactly 2^dstBits. For that value, the overflow to infinity is not
correctly handled. The fix is to replace a strict '>' with '>='.
Currently,
__truncdfsf2(340282366900000000000000000000000000000.0) returns infinity
__truncdfsf2(340282366920938463463374607431768211456.0) returns 0
__truncdfsf2(400000000000000000000000000000000000000.0) returns infinity
Likewise, __truncdfhf2 and __truncsfhf2 (and consequently gnu_f2h_ieee)
are discontinuous at 65536.0.
This patch adds tests for all three cases, along with adding a missing
header include to fp_test.h.
Reviewers: joerg, ab, srhines
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D10594
llvm-svn: 240450
-rw-r--r-- | compiler-rt/lib/builtins/fp_trunc_impl.inc | 2 | ||||
-rw-r--r-- | compiler-rt/test/builtins/Unit/fp_test.h | 1 | ||||
-rw-r--r-- | compiler-rt/test/builtins/Unit/truncdfhf2_test.c | 3 | ||||
-rw-r--r-- | compiler-rt/test/builtins/Unit/truncdfsf2_test.c | 38 | ||||
-rw-r--r-- | compiler-rt/test/builtins/Unit/truncsfhf2_test.c | 3 |
5 files changed, 46 insertions, 1 deletions
diff --git a/compiler-rt/lib/builtins/fp_trunc_impl.inc b/compiler-rt/lib/builtins/fp_trunc_impl.inc index 21bffae02bf..372e8d6014d 100644 --- a/compiler-rt/lib/builtins/fp_trunc_impl.inc +++ b/compiler-rt/lib/builtins/fp_trunc_impl.inc @@ -99,7 +99,7 @@ static inline dst_t __truncXfYf2__(src_t a) { absResult |= dstQNaN; absResult |= ((aAbs & srcNaNCode) >> (srcSigBits - dstSigBits)) & dstNaNCode; } - else if (aAbs > overflow) { + else if (aAbs >= overflow) { // a overflows to infinity. absResult = (dst_rep_t)dstInfExp << dstSigBits; } diff --git a/compiler-rt/test/builtins/Unit/fp_test.h b/compiler-rt/test/builtins/Unit/fp_test.h index 79d652f1765..1f0e7be6d6a 100644 --- a/compiler-rt/test/builtins/Unit/fp_test.h +++ b/compiler-rt/test/builtins/Unit/fp_test.h @@ -14,6 +14,7 @@ #include <stdlib.h> #include <limits.h> #include <string.h> +#include <stdint.h> enum EXPECTED_RESULT { LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 diff --git a/compiler-rt/test/builtins/Unit/truncdfhf2_test.c b/compiler-rt/test/builtins/Unit/truncdfhf2_test.c index 98c5c9dac2e..6627a001eab 100644 --- a/compiler-rt/test/builtins/Unit/truncdfhf2_test.c +++ b/compiler-rt/test/builtins/Unit/truncdfhf2_test.c @@ -107,5 +107,8 @@ int main() if (test__truncdfhf2(-65520.0, UINT16_C(0xfc00))) return 1; + if (test__truncdfhf2(65536.0, + UINT16_C(0x7c00))) + return 1; return 0; } diff --git a/compiler-rt/test/builtins/Unit/truncdfsf2_test.c b/compiler-rt/test/builtins/Unit/truncdfsf2_test.c new file mode 100644 index 00000000000..a208a3a56be --- /dev/null +++ b/compiler-rt/test/builtins/Unit/truncdfsf2_test.c @@ -0,0 +1,38 @@ +//===--------------- truncdfsf2_test.c - Test __truncdfsf2 ----------------===// +// +// 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 __truncdfsf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#include "fp_test.h" + +float __truncdfsf2(double a); + +int test__truncdfsf2(double a) +{ + float actual = __truncdfsf2(a); + float expected = a; + + if (actual != expected) { + printf("error in test__truncdfsf2(%lf) = %f, " + "expected %f\n", a, actual, expected); + return 1; + } + return 0; +} + +int main() +{ + if (test__truncdfsf2(340282366920938463463374607431768211456.0)) + return 1; + return 0; +} diff --git a/compiler-rt/test/builtins/Unit/truncsfhf2_test.c b/compiler-rt/test/builtins/Unit/truncsfhf2_test.c index 2024605d010..5bc3c8e22d5 100644 --- a/compiler-rt/test/builtins/Unit/truncsfhf2_test.c +++ b/compiler-rt/test/builtins/Unit/truncsfhf2_test.c @@ -104,6 +104,9 @@ int main() if (test__truncsfhf2(65520.0f, UINT16_C(0x7c00))) return 1; + if (test__truncsfhf2(65536.0f, + UINT16_C(0x7c00))) + return 1; if (test__truncsfhf2(-65520.0f, UINT16_C(0xfc00))) return 1; |