diff options
author | Jacob Bramley <jacob.bramley@arm.com> | 2020-11-04 09:06:03 +0000 |
---|---|---|
committer | Jacob Bramley <jacob.bramley@arm.com> | 2020-11-05 13:40:24 +0000 |
commit | f73036bad9bdb8c853d783c7f94be1f298cb508d (patch) | |
tree | 4e58d3a37d84f17c274cd061fa28a6f0efc3fb22 /src | |
parent | a26a26cbabf8b4ce67a96c9fc757bbe85818b173 (diff) | |
download | vixl-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.cc | 11 |
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; } |