From d6a04617ace53a334c7d19fcbd996e7f498bbb5c Mon Sep 17 00:00:00 2001 From: Jerry Ge Date: Fri, 15 Dec 2023 22:45:39 +0000 Subject: Fix Cast Float to Int overflows - For Casting from Float to Integers, if the input float is greater than INT_MAX, an overflow will happen when calling rint which causes the clipplings to be ineffectives - Moved all the range checks and clippings before rint to avoid this issue Signed-off-by: Jerry Ge Change-Id: Ic189d59685b6d36464e3ef26766665148a660a14 --- reference_model/src/ops/type_conversion.cc | 33 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/reference_model/src/ops/type_conversion.cc b/reference_model/src/ops/type_conversion.cc index 17abaf7..484f768 100644 --- a/reference_model/src/ops/type_conversion.cc +++ b/reference_model/src/ops/type_conversion.cc @@ -1,5 +1,5 @@ -// Copyright (c) 2020-2023, ARM Limited. +// Copyright (c) 2020-2024, ARM Limited. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -459,10 +459,15 @@ CastHelper::CastHelper() fcn = [](float in) -> OutEigenType { // Cast from float representation back to half_float before rounding half_float::half h = half_float::half(in); - h = std::rint(h); - OutEigenType out = half_float::half_cast(h); - out = std::max(out, OutMin); - out = std::min(out, OutMax); + if (h >= half_float::half(float(OutMax))) + return OutMax; + + if (h <= half_float::half(float(OutMin))) + return OutMin; + + h = std::rint(h); + OutEigenType out = half_float::half_cast(h); + return out; }; } @@ -478,9 +483,13 @@ CastHelper::CastHelper() { // bf16 data (stored as fp32) converted to integer fcn = [](float in) -> OutEigenType { - OutEigenType out = std::round(in); - out = std::max(out, OutMin); - out = std::min(out, OutMax); + if (in >= float(OutMax)) + return OutMax; + + if (in <= float(OutMin)) + return OutMin; + + OutEigenType out = std::rint(in); return out; }; } @@ -527,9 +536,13 @@ CastHelper::CastHelper() case TOSA_REF_TYPE_INT32: // fp64 data converted to integer fcn = [](InEigenType in) -> OutEigenType { + if (in >= double(OutMax)) + return OutMax; + + if (in <= double(OutMin)) + return OutMin; + OutEigenType out = std::rint(in); - out = std::max(out, OutMin); - out = std::min(out, OutMax); return out; }; break; -- cgit v1.2.1