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);