diff options
author | Jerry Ge <jerry.ge@arm.com> | 2023-12-15 22:45:39 +0000 |
---|---|---|
committer | Jerry Ge <jerry.ge@arm.com> | 2024-01-03 17:02:41 +0000 |
commit | d6a04617ace53a334c7d19fcbd996e7f498bbb5c (patch) | |
tree | 1368e8948d41a3b85468d0279098edcbbdc0dca2 /reference_model/src/ops/type_conversion.cc | |
parent | 44827be1377e2ba635599596b903b47ac99764ac (diff) | |
download | reference_model-d6a04617ace53a334c7d19fcbd996e7f498bbb5c.tar.gz |
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 <jerry.ge@arm.com>
Change-Id: Ic189d59685b6d36464e3ef26766665148a660a14
Diffstat (limited to 'reference_model/src/ops/type_conversion.cc')
-rw-r--r-- | reference_model/src/ops/type_conversion.cc | 33 |
1 files 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<TOSA_REF_TYPE_FP16, OutDtype>::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<OutEigenType, half_float::half>(h); - out = std::max<OutEigenType>(out, OutMin); - out = std::min<OutEigenType>(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<OutEigenType, half_float::half>(h); + return out; }; } @@ -478,9 +483,13 @@ CastHelper<TOSA_REF_TYPE_BF16, OutDtype>::CastHelper() { // bf16 data (stored as fp32) converted to integer fcn = [](float in) -> OutEigenType { - OutEigenType out = std::round(in); - out = std::max<OutEigenType>(out, OutMin); - out = std::min<OutEigenType>(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<TOSA_REF_TYPE_FP64, OutDtype>::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<OutEigenType>(out, OutMin); - out = std::min<OutEigenType>(out, OutMax); return out; }; break; |