No public description PiperOrigin-RevId: 558171617
diff --git a/sim/test/kelvin_vector_instructions_test.cc b/sim/test/kelvin_vector_instructions_test.cc index 6f2cddf..ac1b1d0 100644 --- a/sim/test/kelvin_vector_instructions_test.cc +++ b/sim/test/kelvin_vector_instructions_test.cc
@@ -500,22 +500,15 @@ } // Vector saturated add. - -// Uses unsigned arithmetic for the addition to avoid signed overflow, which, -// when compiled with --config=asan, will trigger an exception. template <typename Vd, typename Vs1, typename Vs2> struct VAddsOp { static Vd Op(Vs1 vs1, Vs2 vs2) { - using UT = typename std::make_unsigned<Vd>::type; - UT uvs1 = static_cast<UT>(vs1); - UT uvs2 = static_cast<UT>(vs2); - UT usum = uvs1 + uvs2; - Vd sum = static_cast<Vd>(usum); - if (((vs1 ^ vs2) >= 0) && ((sum ^ vs1) < 0)) { - return vs1 > 0 ? std::numeric_limits<Vd>::max() - : std::numeric_limits<Vd>::min(); - } - return sum; + // typenames Vs1 and Vs2 can be up to int32_t. Promoting to int64_t to + // prevent overflow. + int64_t sum = static_cast<int64_t>(vs1) + static_cast<int64_t>(vs2); + return std::min<int64_t>( + std::max<int64_t>(std::numeric_limits<Vd>::min(), sum), + std::numeric_limits<Vd>::max()); } static void KelvinOp(bool scalar, bool strip_mine, Instruction *inst) { KelvinVAdds<Vd>(scalar, strip_mine, inst); @@ -530,11 +523,8 @@ template <typename Vd, typename Vs1, typename Vs2> struct VAddsuOp { static Vd Op(Vs1 vs1, Vs2 vs2) { - Vd sum = vs1 + vs2; - if (sum < vs1) { - sum = std::numeric_limits<Vd>::max(); - } - return sum; + uint64_t sum = static_cast<uint64_t>(vs1) + static_cast<uint64_t>(vs2); + return std::min<uint64_t>(std::numeric_limits<Vd>::max(), sum); } static void KelvinOp(bool scalar, bool strip_mine, Instruction *inst) { KelvinVAddsu<Vd>(scalar, strip_mine, inst); @@ -546,22 +536,15 @@ } // Vector saturated sub. - -// Uses unsigned arithmetic for the addition to avoid signed overflow, which, -// when compiled with --config=asan, will trigger an exception. template <typename Vd, typename Vs1, typename Vs2> struct VSubsOp { static Vd Op(Vs1 vs1, Vs2 vs2) { - using UT = typename std::make_unsigned<Vd>::type; - UT uvs1 = static_cast<UT>(vs1); - UT uvs2 = static_cast<UT>(vs2); - UT usub = uvs1 - uvs2; - Vd sub = static_cast<Vd>(usub); - if (((vs1 ^ vs2) < 0) && ((sub ^ vs2) >= 0)) { - return vs2 < 0 ? std::numeric_limits<Vd>::max() - : std::numeric_limits<Vd>::min(); - } - return sub; + // typenames Vs1 and Vs2 can be up to int32_t. Promoting to int64_t to + // prevent overflow. + int64_t sub = static_cast<int64_t>(vs1) - static_cast<int64_t>(vs2); + return std::min<int64_t>( + std::max<int64_t>(std::numeric_limits<Vd>::min(), sub), + std::numeric_limits<Vd>::max()); } static void KelvinOp(bool scalar, bool strip_mine, Instruction *inst) { KelvinVSubs<Vd>(scalar, strip_mine, inst);