From e1d10c3894978015fb20e7247f67b1e5d23d2811 Mon Sep 17 00:00:00 2001 From: Travis Boraten Date: Thu, 18 Apr 2019 18:03:14 -0400 Subject: [PATCH] arch-gcn3: Fix VOP3 V_LDEXP_F64 Replaced !std::isnormal with std::fpclassify because std::isnormal is not specific enough. !std::isnormal was incorrectly catching NaN, Inf, 0.0, and subnormals (aka denormals), where as it was only suppose to catch subnormals. The return value and error handling spec of std::ldexp listed on cppreference.com appears to match up in nearly all cases after making these changes. If std::ldexp handled subnormals as described in the GCN3 2016 guide, we could have used vdst[lane] = std::ldexp and not need to check for any corner cases. Change-Id: I4c77af77c3b7798f86d40442610cef1296a28441 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/29966 Maintainer: Anthony Gutierrez Tested-by: kokoro Reviewed-by: Matt Sinclair --- src/arch/gcn3/insts/instructions.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/arch/gcn3/insts/instructions.cc b/src/arch/gcn3/insts/instructions.cc index 2b992b165..302dad4eb 100644 --- a/src/arch/gcn3/insts/instructions.cc +++ b/src/arch/gcn3/insts/instructions.cc @@ -30282,10 +30282,11 @@ namespace Gcn3ISA for (int lane = 0; lane < NumVecElemPerVecReg; ++lane) { if (wf->execMask(lane)) { - if (std::isnan(src1[lane]) || std::isinf(src1[lane])) { + if (std::isnan(src0[lane]) || std::isinf(src0[lane])) { vdst[lane] = src0[lane]; - } else if (!std::isnormal(src1[lane])) { - if (std::signbit(src1[lane])) { + } else if (std::fpclassify(src0[lane]) == FP_SUBNORMAL + || std::fpclassify(src0[lane]) == FP_ZERO) { + if (std::signbit(src0[lane])) { vdst[lane] = -0.0; } else { vdst[lane] = +0.0; -- 2.30.2