[compiler-rt] r356529 - [builtins] Divide shouldn't underflow if rounded result would be normal.
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 14:55:58 PDT 2019
Author: efriedma
Date: Tue Mar 19 14:55:58 2019
New Revision: 356529
URL: http://llvm.org/viewvc/llvm-project?rev=356529&view=rev
Log:
[builtins] Divide shouldn't underflow if rounded result would be normal.
We were treating certain edge cases that are actually normal as denormal
results, and flushing them to zero; we shouldn't do that. Not sure this
is the cleanest way to implement this edge case, but I wanted to avoid
adding any code on the common path.
Differential Revision: https://reviews.llvm.org/D59070
Added:
compiler-rt/trunk/test/builtins/Unit/divdf3_test.c
compiler-rt/trunk/test/builtins/Unit/divsf3_test.c
Modified:
compiler-rt/trunk/lib/builtins/divdf3.c
compiler-rt/trunk/lib/builtins/divsf3.c
compiler-rt/trunk/lib/builtins/divtf3.c
compiler-rt/trunk/test/builtins/Unit/divtf3_test.c
Modified: compiler-rt/trunk/lib/builtins/divdf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/divdf3.c?rev=356529&r1=356528&r2=356529&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/divdf3.c (original)
+++ compiler-rt/trunk/lib/builtins/divdf3.c Tue Mar 19 14:55:58 2019
@@ -162,6 +162,18 @@ __divdf3(fp_t a, fp_t b) {
}
else if (writtenExponent < 1) {
+ if (writtenExponent == 0) {
+ // Check whether the rounded result is normal.
+ const bool round = (residual << 1) > bSignificand;
+ // Clear the implicit bit.
+ rep_t absResult = quotient & significandMask;
+ // Round.
+ absResult += round;
+ if (absResult & ~significandMask) {
+ // The rounded result is normal; return it.
+ return fromRep(absResult | quotientSign);
+ }
+ }
// Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly.
return fromRep(quotientSign);
Modified: compiler-rt/trunk/lib/builtins/divsf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/divsf3.c?rev=356529&r1=356528&r2=356529&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/divsf3.c (original)
+++ compiler-rt/trunk/lib/builtins/divsf3.c Tue Mar 19 14:55:58 2019
@@ -147,6 +147,18 @@ __divsf3(fp_t a, fp_t b) {
}
else if (writtenExponent < 1) {
+ if (writtenExponent == 0) {
+ // Check whether the rounded result is normal.
+ const bool round = (residual << 1) > bSignificand;
+ // Clear the implicit bit.
+ rep_t absResult = quotient & significandMask;
+ // Round.
+ absResult += round;
+ if (absResult & ~significandMask) {
+ // The rounded result is normal; return it.
+ return fromRep(absResult | quotientSign);
+ }
+ }
// Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly.
return fromRep(quotientSign);
Modified: compiler-rt/trunk/lib/builtins/divtf3.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/divtf3.c?rev=356529&r1=356528&r2=356529&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/divtf3.c (original)
+++ compiler-rt/trunk/lib/builtins/divtf3.c Tue Mar 19 14:55:58 2019
@@ -181,6 +181,18 @@ COMPILER_RT_ABI fp_t __divtf3(fp_t a, fp
return fromRep(infRep | quotientSign);
}
else if (writtenExponent < 1) {
+ if (writtenExponent == 0) {
+ // Check whether the rounded result is normal.
+ const bool round = (residual << 1) > bSignificand;
+ // Clear the implicit bit.
+ rep_t absResult = quotient & significandMask;
+ // Round.
+ absResult += round;
+ if (absResult & ~significandMask) {
+ // The rounded result is normal; return it.
+ return fromRep(absResult | quotientSign);
+ }
+ }
// Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly.
return fromRep(quotientSign);
Added: compiler-rt/trunk/test/builtins/Unit/divdf3_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/divdf3_test.c?rev=356529&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/divdf3_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/divdf3_test.c Tue Mar 19 14:55:58 2019
@@ -0,0 +1,45 @@
+// RUN: %clang_builtins %s %librt -o %t && %run %t
+//===--------------- divdf3_test.c - Test __divdf3 ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divdf3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+#include "fp_test.h"
+
+// Returns: a / b
+COMPILER_RT_ABI double __divdf3(double a, double b);
+
+int test__divdf3(double a, double b, uint64_t expected)
+{
+ double x = __divdf3(a, b);
+ int ret = compareResultD(x, expected);
+
+ if (ret){
+ printf("error in test__divdf3(%.20e, %.20e) = %.20e, "
+ "expected %.20e\n", a, b, x,
+ fromRep64(expected));
+ }
+ return ret;
+}
+
+int main()
+{
+ // 1/3
+ if (test__divdf3(1., 3., 0x3fd5555555555555ULL))
+ return 1;
+ // smallest normal result
+ if (test__divdf3(4.450147717014403e-308, 2., 0x10000000000000ULL))
+ return 1;
+
+ return 0;
+}
Added: compiler-rt/trunk/test/builtins/Unit/divsf3_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/divsf3_test.c?rev=356529&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/divsf3_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/divsf3_test.c Tue Mar 19 14:55:58 2019
@@ -0,0 +1,45 @@
+// RUN: %clang_builtins %s %librt -o %t && %run %t
+//===--------------- divsf3_test.c - Test __divsf3 ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divsf3 for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "int_lib.h"
+#include <stdio.h>
+
+#include "fp_test.h"
+
+// Returns: a / b
+COMPILER_RT_ABI float __divsf3(float a, float b);
+
+int test__divsf3(float a, float b, uint32_t expected)
+{
+ float x = __divsf3(a, b);
+ int ret = compareResultF(x, expected);
+
+ if (ret){
+ printf("error in test__divsf3(%.20e, %.20e) = %.20e, "
+ "expected %.20e\n", a, b, x,
+ fromRep32(expected));
+ }
+ return ret;
+}
+
+int main()
+{
+ // 1/3
+ if (test__divsf3(1.f, 3.f, 0x3EAAAAABU))
+ return 1;
+ // smallest normal result
+ if (test__divsf3(2.3509887e-38, 2., 0x00800000U))
+ return 1;
+
+ return 0;
+}
Modified: compiler-rt/trunk/test/builtins/Unit/divtf3_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/divtf3_test.c?rev=356529&r1=356528&r2=356529&view=diff
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/divtf3_test.c (original)
+++ compiler-rt/trunk/test/builtins/Unit/divtf3_test.c Tue Mar 19 14:55:58 2019
@@ -28,8 +28,8 @@ int test__divtf3(long double a, long dou
int ret = compareResultLD(x, expectedHi, expectedLo);
if (ret){
- printf("error in test__divtf3(%.20Lf, %.20Lf) = %.20Lf, "
- "expected %.20Lf\n", a, b, x,
+ printf("error in test__divtf3(%.20Le, %.20Le) = %.20Le, "
+ "expected %.20Le\n", a, b, x,
fromRep128(expectedHi, expectedLo));
}
return ret;
@@ -86,6 +86,11 @@ int main()
UINT64_C(0x50bf2e02f0798d36),
UINT64_C(0x5e6fcb6b60044078)))
return 1;
+ if (test__divtf3(6.72420628622418701252535563464350521E-4932L,
+ 2.L,
+ UINT64_C(0x0001000000000000),
+ UINT64_C(0)))
+ return 1;
#else
printf("skipped\n");
More information about the llvm-commits
mailing list