From 14439f890d4958e2d9650339369f137b47ce6e13 Mon Sep 17 00:00:00 2001
From: "Jorge C. Leitao" <jorgecarleitao@gmail.com>
Date: Thu, 10 Mar 2022 21:22:20 +0000
Subject: [PATCH 1/2] Added .min and .max for integers

---
 crates/core_simd/src/comparisons.rs  | 34 ++++++++++++++++++++++++++++
 crates/core_simd/tests/i16_ops.rs    | 15 ++++++++++++
 crates/core_simd/tests/ops_macros.rs | 17 ++++++++++++++
 3 files changed, 66 insertions(+)

diff --git a/crates/core_simd/src/comparisons.rs b/crates/core_simd/src/comparisons.rs
index d024cf4ddbe..0b7bdcd0e48 100644
--- a/crates/core_simd/src/comparisons.rs
+++ b/crates/core_simd/src/comparisons.rs
@@ -66,3 +66,37 @@ where
         unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
     }
 }
+
+macro_rules! impl_min_max_vector {
+    { $type:ty } => {
+        impl<const LANES: usize> Simd<$type, LANES>
+        where
+            LaneCount<LANES>: SupportedLaneCount,
+        {
+            /// Returns the lane-wise minimum with other
+            #[must_use = "method returns a new mask and does not mutate the original value"]
+            #[inline]
+            pub fn min(self, other: Self) -> Self {
+                self.lanes_gt(other).select(other, self)
+            }
+
+            /// Returns the lane-wise maximum with other
+            #[must_use = "method returns a new mask and does not mutate the original value"]
+            #[inline]
+            pub fn max(self, other: Self) -> Self {
+                self.lanes_lt(other).select(other, self)
+            }
+        }
+    }
+}
+
+impl_min_max_vector!(i8);
+impl_min_max_vector!(i16);
+impl_min_max_vector!(i32);
+impl_min_max_vector!(i64);
+impl_min_max_vector!(isize);
+impl_min_max_vector!(u8);
+impl_min_max_vector!(u16);
+impl_min_max_vector!(u32);
+impl_min_max_vector!(u64);
+impl_min_max_vector!(usize);
diff --git a/crates/core_simd/tests/i16_ops.rs b/crates/core_simd/tests/i16_ops.rs
index f6c5d74fbbc..cd6cadc2d5e 100644
--- a/crates/core_simd/tests/i16_ops.rs
+++ b/crates/core_simd/tests/i16_ops.rs
@@ -1,5 +1,20 @@
 #![feature(portable_simd)]
+use core_simd::i16x2;
 
 #[macro_use]
 mod ops_macros;
 impl_signed_tests! { i16 }
+
+#[test]
+fn max_is_not_lexicographic() {
+    let a = i16x2::splat(10);
+    let b = i16x2::from_array([-4, 12]);
+    assert_eq!(a.max(b), i16x2::from_array([10, 12]));
+}
+
+#[test]
+fn min_is_not_lexicographic() {
+    let a = i16x2::splat(10);
+    let b = i16x2::from_array([12, -4]);
+    assert_eq!(a.min(b), i16x2::from_array([10, -4]));
+}
diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
index 50f7a4ca170..96da8c1b8dc 100644
--- a/crates/core_simd/tests/ops_macros.rs
+++ b/crates/core_simd/tests/ops_macros.rs
@@ -222,6 +222,23 @@ macro_rules! impl_signed_tests {
                     assert_eq!(a % b, Vector::<LANES>::splat(0));
                 }
 
+                fn min<const LANES: usize>() {
+                    let a = Vector::<LANES>::splat(Scalar::MIN);
+                    let b = Vector::<LANES>::splat(0);
+                    assert_eq!(a.min(b), a);
+                    let a = Vector::<LANES>::splat(Scalar::MAX);
+                    let b = Vector::<LANES>::splat(0);
+                    assert_eq!(a.min(b), b);
+                }
+
+                fn max<const LANES: usize>() {
+                    let a = Vector::<LANES>::splat(Scalar::MIN);
+                    let b = Vector::<LANES>::splat(0);
+                    assert_eq!(a.max(b), b);
+                    let a = Vector::<LANES>::splat(Scalar::MAX);
+                    let b = Vector::<LANES>::splat(0);
+                    assert_eq!(a.max(b), a);
+                }
             }
 
             test_helpers::test_lanes_panic! {

From 5b253df9be3511603daf9e087f43be4a63f5ff5a Mon Sep 17 00:00:00 2001
From: "Jorge C. Leitao" <jorgecarleitao@gmail.com>
Date: Thu, 10 Mar 2022 21:44:51 +0000
Subject: [PATCH 2/2] Fixed comment

---
 crates/core_simd/src/comparisons.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/crates/core_simd/src/comparisons.rs b/crates/core_simd/src/comparisons.rs
index 0b7bdcd0e48..88270a9b7e9 100644
--- a/crates/core_simd/src/comparisons.rs
+++ b/crates/core_simd/src/comparisons.rs
@@ -74,14 +74,14 @@ macro_rules! impl_min_max_vector {
             LaneCount<LANES>: SupportedLaneCount,
         {
             /// Returns the lane-wise minimum with other
-            #[must_use = "method returns a new mask and does not mutate the original value"]
+            #[must_use = "method returns a new vector and does not mutate the original value"]
             #[inline]
             pub fn min(self, other: Self) -> Self {
                 self.lanes_gt(other).select(other, self)
             }
 
             /// Returns the lane-wise maximum with other
-            #[must_use = "method returns a new mask and does not mutate the original value"]
+            #[must_use = "method returns a new vector and does not mutate the original value"]
             #[inline]
             pub fn max(self, other: Self) -> Self {
                 self.lanes_lt(other).select(other, self)