arch-gcn3: Fix roundNearestEven for V_RNDNE_F64 and V_RNDNE_F32
authorTravis Boraten <travis.boraten@amd.com>
Mon, 22 Apr 2019 21:14:13 +0000 (17:14 -0400)
committerAnthony Gutierrez <anthony.gutierrez@amd.com>
Fri, 17 Jul 2020 16:32:56 +0000 (16:32 +0000)
roundNearestEven is an inst_util function that RNDNE_F64 and F32
call, including both VOP1 and VOP3 formats. IEEE 754 spec says this
function should round inputs to the nearest integer but round ties
to the nearest even integer. Prior to this patch it was rounding all
inputs to nearest even, not just the ties. It was probably implemented
this way originally because the language in the ISA manual is ambiguous
although it provided the correct logic.

Fixed roundNearestEven to use the semantics originally described in
the GCN3 ISA manual.

Change-Id: I83ecb1d516fcf5bdf17e54ddf409b447a129a9a7
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29964
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com>
src/arch/gcn3/insts/inst_util.hh

index b40e890f6aa411fcd93579d9d9c26a1e7ca8412c..15ffe9a934b609bbbd63a86e2e15f2b98fda4cd2 100644 (file)
@@ -258,7 +258,13 @@ namespace Gcn3ISA
     template <typename T>
     inline T roundNearestEven(T val)
     {
-        T nearest_round = std::round(val * 0.5) * 2.0;
+        T int_part = 0;
+        T nearest_round = std::floor(val + 0.5);
+        if ((int)std::floor(val) % 2 == 0
+            && std::modf(std::abs(val), &int_part) == 0.5) {
+          nearest_round = nearest_round - 1;
+        }
+
         return nearest_round;
     }