aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJacob Bramley <jacob.bramley@arm.com>2020-11-04 09:06:03 +0000
committerJacob Bramley <jacob.bramley@arm.com>2020-11-05 13:40:24 +0000
commitf73036bad9bdb8c853d783c7f94be1f298cb508d (patch)
tree4e58d3a37d84f17c274cd061fa28a6f0efc3fb22 /src
parenta26a26cbabf8b4ce67a96c9fc757bbe85818b173 (diff)
downloadvixl-f73036bad9bdb8c853d783c7f94be1f298cb508d.tar.gz
Fix FPRoundInt's handling of INT64_MAX.
This fixes a bug caused by an implicit conversion from `int64_t` to `double`, as well as several related warnings (from recent versions of Clang) in the "frint" tests. Change-Id: Ie5dccbf7a86c5e3a608570bd0ffc566bf3813380
Diffstat (limited to 'src')
-rw-r--r--src/aarch64/logic-aarch64.cc11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/aarch64/logic-aarch64.cc b/src/aarch64/logic-aarch64.cc
index cab02573..821c1db9 100644
--- a/src/aarch64/logic-aarch64.cc
+++ b/src/aarch64/logic-aarch64.cc
@@ -4711,11 +4711,20 @@ double Simulator::FPRoundInt(double value,
double result = FPRoundIntCommon(value, round_mode);
+ // We want to compare `result > INT64_MAX` below, but INT64_MAX isn't exactly
+ // representable as a double, and is rounded to (INT64_MAX + 1) when
+ // converted. To avoid this, we compare `result >= int64_max_plus_one`
+ // instead; this is safe because `result` is known to be integral, and
+ // `int64_max_plus_one` is exactly representable as a double.
+ constexpr uint64_t int64_max_plus_one = static_cast<uint64_t>(INT64_MAX) + 1;
+ VIXL_STATIC_ASSERT(static_cast<uint64_t>(static_cast<double>(
+ int64_max_plus_one)) == int64_max_plus_one);
+
if (frint_mode == kFrintToInt32) {
if ((result > INT32_MAX) || (result < INT32_MIN)) {
return INT32_MIN;
}
- } else if ((result > INT64_MAX) || (result < INT64_MIN)) {
+ } else if ((result >= int64_max_plus_one) || (result < INT64_MIN)) {
return INT64_MIN;
}