From: Travis Boraten Date: Thu, 18 Apr 2019 22:03:14 +0000 (-0400) Subject: arch-gcn3: Fix VOP3 V_LDEXP_F64 X-Git-Tag: v20.1.0.0~428 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e1d10c3894978015fb20e7247f67b1e5d23d2811;p=gem5.git 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 --- 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;