Repository: bitshifter/glam-rs
Pull request #440 (2023-11-26 13:43:47)

add more i16/u16 tests; fix cuda align for i16/u16
This is a follow-up for https://github.com/bitshifter/glam-rs/pull/439, adding the missing test cases (and some more).

Also the CUDA-alignment has been fixed (to my knowledge).

Test-coverage should at least be back to normal. API is backwards-compatible (no version-bump required IMO).

bitshifter: This is the alignment table I've been using, https://docs.nvidia.com/cuda/archive/11.7.0/cuda-c-programming-guide/index.html#vector-types__alignment-requirements-in-device-code. I think what you have looks about right.

Thanks for all your work here!

Patch:
diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera
index bba10c7..a783b86 100644
--- a/codegen/templates/vec.rs.tera
+++ b/codegen/templates/vec.rs.tera
@@ -91,10 +91,22 @@
     {% set try_from_types = ["I16Vec" ~ dim, "IVec" ~ dim, "I64Vec" ~ dim] %}
 {% endif %}
 
-{% if scalar_t == "f64" or scalar_t == "i64" or scalar_t == "u64" or dim == 4 %}
-    {% set cuda_align = 16 %}
-{% elif dim == 2 %}
-    {% set cuda_align = 8 %}
+{% if dim == 2 %}
+    {% if scalar_t == "i16" or scalar_t == "u16" %}
+        {% set cuda_align = 4 %}
+    {% elif scalar_t == "f32" or scalar_t == "i32" or scalar_t == "u32" %}
+        {% set cuda_align = 8 %}
+    {% elif scalar_t == "f64" or scalar_t == "i64" or scalar_t == "u64" %}
+        {% set cuda_align = 16 %}
+    {% endif %}
+{% elif dim == 4 %}
+    {% if scalar_t == "i16" or scalar_t == "u16" %}
+        {% set cuda_align = 8 %}
+    {% elif scalar_t == "f32" or scalar_t == "i32" or scalar_t == "u32" %}
+        {% set cuda_align = 16 %}
+    {% elif scalar_t == "f64" or scalar_t == "i64" or scalar_t == "u64" %}
+        {% set cuda_align = 16 %}
+    {% endif %}
 {% endif %}
 
 {% set components = ["x", "y", "z", "w"] | slice(end = dim) %}
diff --git a/src/i16.rs b/src/i16.rs
index cec4ceb..7d9acdc 100644
--- a/src/i16.rs
+++ b/src/i16.rs
@@ -11,18 +11,15 @@ mod test {
     use super::*;
 
     mod const_test_i16vec2 {
+        const_assert_eq!(4, core::mem::size_of::<super::I16Vec2>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<i16>(),
             core::mem::align_of::<super::I16Vec2>()
         );
-        #[cfg(not(feature = "cuda"))]
-        const_assert_eq!(4, core::mem::size_of::<super::I16Vec2>());
-
-        #[cfg(feature = "cuda")]
-        const_assert_eq!(8, core::mem::align_of::<super::I16Vec2>());
         #[cfg(feature = "cuda")]
-        const_assert_eq!(8, core::mem::size_of::<super::I16Vec2>());
+        const_assert_eq!(4, core::mem::align_of::<super::I16Vec2>());
     }
 
     mod const_test_i16vec3 {
@@ -34,17 +31,14 @@ mod test {
     }
 
     mod const_test_i16vec4 {
+        const_assert_eq!(8, core::mem::size_of::<super::I16Vec4>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<i16>(),
             core::mem::align_of::<super::I16Vec4>()
         );
-        #[cfg(not(feature = "cuda"))]
-        const_assert_eq!(8, core::mem::size_of::<super::I16Vec4>());
-
-        #[cfg(feature = "cuda")]
-        const_assert_eq!(16, core::mem::align_of::<super::I16Vec4>());
         #[cfg(feature = "cuda")]
-        const_assert_eq!(16, core::mem::size_of::<super::I16Vec4>());
+        const_assert_eq!(8, core::mem::align_of::<super::I16Vec4>());
     }
 }
diff --git a/src/i16/i16vec2.rs b/src/i16/i16vec2.rs
index 7b5bf9c..37eabe2 100644
--- a/src/i16/i16vec2.rs
+++ b/src/i16/i16vec2.rs
@@ -16,7 +16,7 @@ pub const fn i16vec2(x: i16, y: i16) -> I16Vec2 {
 /// A 2-dimensional vector.
 #[cfg_attr(not(target_arch = "spirv"), derive(Hash))]
 #[derive(Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "cuda", repr(align(8)))]
+#[cfg_attr(feature = "cuda", repr(align(4)))]
 #[cfg_attr(not(target_arch = "spirv"), repr(C))]
 #[cfg_attr(target_arch = "spirv", repr(simd))]
 pub struct I16Vec2 {
diff --git a/src/i16/i16vec4.rs b/src/i16/i16vec4.rs
index e8bd3d8..55e763e 100644
--- a/src/i16/i16vec4.rs
+++ b/src/i16/i16vec4.rs
@@ -16,7 +16,7 @@ pub const fn i16vec4(x: i16, y: i16, z: i16, w: i16) -> I16Vec4 {
 /// A 4-dimensional vector.
 #[cfg_attr(not(target_arch = "spirv"), derive(Hash))]
 #[derive(Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "cuda", repr(align(16)))]
+#[cfg_attr(feature = "cuda", repr(align(8)))]
 #[cfg_attr(not(target_arch = "spirv"), repr(C))]
 #[cfg_attr(target_arch = "spirv", repr(simd))]
 pub struct I16Vec4 {
diff --git a/src/i32.rs b/src/i32.rs
index 313f56c..663607b 100644
--- a/src/i32.rs
+++ b/src/i32.rs
@@ -11,6 +11,8 @@ mod test {
     use super::*;
 
     mod const_test_ivec2 {
+        const_assert_eq!(8, core::mem::size_of::<super::IVec2>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<i32>(),
@@ -18,7 +20,6 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(8, core::mem::align_of::<super::IVec2>());
-        const_assert_eq!(8, core::mem::size_of::<super::IVec2>());
     }
 
     mod const_test_ivec3 {
@@ -30,6 +31,8 @@ mod test {
     }
 
     mod const_test_ivec4 {
+        const_assert_eq!(16, core::mem::size_of::<super::IVec4>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<i32>(),
@@ -37,6 +40,5 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(16, core::mem::align_of::<super::IVec4>());
-        const_assert_eq!(16, core::mem::size_of::<super::IVec4>());
     }
 }
diff --git a/src/i64.rs b/src/i64.rs
index f4da9f8..03f2a0f 100644
--- a/src/i64.rs
+++ b/src/i64.rs
@@ -11,6 +11,8 @@ mod test {
     use super::*;
 
     mod const_test_i64vec2 {
+        const_assert_eq!(16, core::mem::size_of::<super::I64Vec2>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<i64>(),
@@ -18,18 +20,20 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(16, core::mem::align_of::<super::I64Vec2>());
-        const_assert_eq!(16, core::mem::size_of::<super::I64Vec2>());
     }
 
     mod const_test_i64vec3 {
+        const_assert_eq!(24, core::mem::size_of::<super::I64Vec3>());
+
         const_assert_eq!(
             core::mem::align_of::<i64>(),
             core::mem::align_of::<super::I64Vec3>()
         );
-        const_assert_eq!(24, core::mem::size_of::<super::I64Vec3>());
     }
 
     mod const_test_i64vec4 {
+        const_assert_eq!(32, core::mem::size_of::<super::I64Vec4>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<i64>(),
@@ -37,6 +41,5 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(16, core::mem::align_of::<super::I64Vec4>());
-        const_assert_eq!(32, core::mem::size_of::<super::I64Vec4>());
     }
 }
diff --git a/src/u16.rs b/src/u16.rs
index 36745f8..405278b 100644
--- a/src/u16.rs
+++ b/src/u16.rs
@@ -11,18 +11,15 @@ mod test {
     use super::*;
 
     mod const_test_u16vec2 {
+        const_assert_eq!(4, core::mem::size_of::<super::U16Vec2>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<u16>(),
             core::mem::align_of::<super::U16Vec2>()
         );
-        #[cfg(not(feature = "cuda"))]
-        const_assert_eq!(4, core::mem::size_of::<super::U16Vec2>());
-        #[cfg(feature = "cuda")]
-
-        const_assert_eq!(8, core::mem::align_of::<super::U16Vec2>());
         #[cfg(feature = "cuda")]
-        const_assert_eq!(8, core::mem::size_of::<super::U16Vec2>());
+        const_assert_eq!(4, core::mem::align_of::<super::U16Vec2>());
     }
 
     mod const_test_u16vec3 {
@@ -34,17 +31,14 @@ mod test {
     }
 
     mod const_test_u16vec4 {
+        const_assert_eq!(8, core::mem::size_of::<super::U16Vec4>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<u16>(),
             core::mem::align_of::<super::U16Vec4>()
         );
-        #[cfg(not(feature = "cuda"))]
-        const_assert_eq!(8, core::mem::size_of::<super::U16Vec4>());
-
-        #[cfg(feature = "cuda")]
-        const_assert_eq!(16, core::mem::align_of::<super::U16Vec4>());
         #[cfg(feature = "cuda")]
-        const_assert_eq!(16, core::mem::size_of::<super::U16Vec4>());
+        const_assert_eq!(8, core::mem::align_of::<super::U16Vec4>());
     }
 }
diff --git a/src/u16/u16vec2.rs b/src/u16/u16vec2.rs
index 37289ad..ae35d67 100644
--- a/src/u16/u16vec2.rs
+++ b/src/u16/u16vec2.rs
@@ -16,7 +16,7 @@ pub const fn u16vec2(x: u16, y: u16) -> U16Vec2 {
 /// A 2-dimensional vector.
 #[cfg_attr(not(target_arch = "spirv"), derive(Hash))]
 #[derive(Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "cuda", repr(align(8)))]
+#[cfg_attr(feature = "cuda", repr(align(4)))]
 #[cfg_attr(not(target_arch = "spirv"), repr(C))]
 #[cfg_attr(target_arch = "spirv", repr(simd))]
 pub struct U16Vec2 {
diff --git a/src/u16/u16vec4.rs b/src/u16/u16vec4.rs
index f9c200c..5882d8e 100644
--- a/src/u16/u16vec4.rs
+++ b/src/u16/u16vec4.rs
@@ -16,7 +16,7 @@ pub const fn u16vec4(x: u16, y: u16, z: u16, w: u16) -> U16Vec4 {
 /// A 4-dimensional vector.
 #[cfg_attr(not(target_arch = "spirv"), derive(Hash))]
 #[derive(Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "cuda", repr(align(16)))]
+#[cfg_attr(feature = "cuda", repr(align(8)))]
 #[cfg_attr(not(target_arch = "spirv"), repr(C))]
 #[cfg_attr(target_arch = "spirv", repr(simd))]
 pub struct U16Vec4 {
diff --git a/src/u32.rs b/src/u32.rs
index 3538c3e..f3c696d 100644
--- a/src/u32.rs
+++ b/src/u32.rs
@@ -10,6 +10,8 @@ pub use uvec4::{uvec4, UVec4};
 mod test {
     use super::*;
     mod const_test_uvec2 {
+        const_assert_eq!(8, core::mem::size_of::<super::UVec2>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<u32>(),
@@ -17,18 +19,20 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(8, core::mem::align_of::<super::UVec2>());
-        const_assert_eq!(8, core::mem::size_of::<super::UVec2>());
     }
 
     mod const_test_uvec3 {
+        const_assert_eq!(12, core::mem::size_of::<super::UVec3>());
+
         const_assert_eq!(
             core::mem::align_of::<u32>(),
             core::mem::align_of::<super::UVec3>()
         );
-        const_assert_eq!(12, core::mem::size_of::<super::UVec3>());
     }
 
     mod const_test_uvec4 {
+        const_assert_eq!(16, core::mem::size_of::<super::UVec4>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<u32>(),
@@ -36,6 +40,5 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(16, core::mem::align_of::<super::UVec4>());
-        const_assert_eq!(16, core::mem::size_of::<super::UVec4>());
     }
 }
diff --git a/src/u64.rs b/src/u64.rs
index d1bae83..afd2bd2 100644
--- a/src/u64.rs
+++ b/src/u64.rs
@@ -10,6 +10,8 @@ pub use u64vec4::{u64vec4, U64Vec4};
 mod test {
     use super::*;
     mod const_test_u64vec2 {
+        const_assert_eq!(16, core::mem::size_of::<super::U64Vec2>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<u64>(),
@@ -17,18 +19,20 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(16, core::mem::align_of::<super::U64Vec2>());
-        const_assert_eq!(16, core::mem::size_of::<super::U64Vec2>());
     }
 
     mod const_test_u64vec3 {
+        const_assert_eq!(24, core::mem::size_of::<super::U64Vec3>());
+
         const_assert_eq!(
             core::mem::align_of::<u64>(),
             core::mem::align_of::<super::U64Vec3>()
         );
-        const_assert_eq!(24, core::mem::size_of::<super::U64Vec3>());
     }
 
     mod const_test_u64vec4 {
+        const_assert_eq!(32, core::mem::size_of::<super::U64Vec4>());
+
         #[cfg(not(feature = "cuda"))]
         const_assert_eq!(
             core::mem::align_of::<u64>(),
@@ -36,6 +40,5 @@ mod test {
         );
         #[cfg(feature = "cuda")]
         const_assert_eq!(16, core::mem::align_of::<super::U64Vec4>());
-        const_assert_eq!(32, core::mem::size_of::<super::U64Vec4>());
     }
 }


Test patch:
diff --git a/tests/vec2.rs b/tests/vec2.rs
index 5956382..fd6df74 100644
--- a/tests/vec2.rs
+++ b/tests/vec2.rs
@@ -1166,14 +1166,11 @@ mod i16vec2 {
 
     glam_test!(test_align, {
         use core::mem;
+        assert_eq!(4, mem::size_of::<I16Vec2>());
         #[cfg(not(feature = "cuda"))]
         assert_eq!(2, mem::align_of::<I16Vec2>());
-        #[cfg(not(feature = "cuda"))]
-        assert_eq!(4, mem::size_of::<I16Vec2>());
         #[cfg(feature = "cuda")]
-        assert_eq!(8, mem::align_of::<I16Vec2>());
-        #[cfg(feature = "cuda")]
-        assert_eq!(8, mem::size_of::<I16Vec2>());
+        assert_eq!(4, mem::align_of::<I16Vec2>());
     });
 
     glam_test!(test_try_from, {
@@ -1284,14 +1281,11 @@ mod u16vec2 {
 
     glam_test!(test_align, {
         use core::mem;
+        assert_eq!(4, mem::size_of::<U16Vec2>());
         #[cfg(not(feature = "cuda"))]
         assert_eq!(2, mem::align_of::<U16Vec2>());
-        #[cfg(not(feature = "cuda"))]
-        assert_eq!(4, mem::size_of::<U16Vec2>());
-        #[cfg(feature = "cuda")]
-        assert_eq!(8, mem::align_of::<U16Vec2>());
         #[cfg(feature = "cuda")]
-        assert_eq!(8, mem::size_of::<U16Vec2>());
+        assert_eq!(4, mem::align_of::<U16Vec2>());
     });
 
     glam_test!(test_try_from, {
@@ -1404,7 +1398,7 @@ mod u16vec2 {
 }
 
 mod ivec2 {
-    use glam::{ivec2, BVec2, I64Vec2, IVec2, IVec3, U64Vec2, UVec2};
+    use glam::{ivec2, BVec2, I16Vec2, I64Vec2, IVec2, IVec3, U16Vec2, U64Vec2, UVec2};
 
     glam_test!(test_align, {
         use core::mem;
@@ -1418,6 +1412,9 @@ mod ivec2 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(IVec2::new(1, 2), IVec2::from(U16Vec2::new(1, 2)));
+        assert_eq!(IVec2::new(1, 2), IVec2::from(I16Vec2::new(1, 2)));
+
         assert_eq!(IVec2::new(1, 2), IVec2::try_from(UVec2::new(1, 2)).unwrap());
         assert!(IVec2::try_from(UVec2::new(u32::MAX, 2)).is_err());
         assert!(IVec2::try_from(UVec2::new(1, u32::MAX)).is_err());
@@ -1504,7 +1501,7 @@ mod ivec2 {
 }
 
 mod uvec2 {
-    use glam::{uvec2, BVec2, I16Vec2, I64Vec2, IVec2, U64Vec2, UVec2, UVec3};
+    use glam::{uvec2, BVec2, I16Vec2, I64Vec2, IVec2, U16Vec2, U64Vec2, UVec2, UVec3};
 
     glam_test!(test_align, {
         use core::mem;
@@ -1523,7 +1520,9 @@ mod uvec2 {
             UVec2::try_from(I16Vec2::new(1, 2)).unwrap()
         );
         assert!(UVec2::try_from(I16Vec2::new(-1, 2)).is_err());
-        assert!(UVec2::try_from(I16Vec2::new(1, -1)).is_err());
+        assert!(UVec2::try_from(I16Vec2::new(1, -2)).is_err());
+
+        assert_eq!(UVec2::new(1, 2), UVec2::from(U16Vec2::new(1, 2)));
 
         assert_eq!(UVec2::new(1, 2), UVec2::try_from(IVec2::new(1, 2)).unwrap());
         assert!(UVec2::try_from(IVec2::new(-1, 2)).is_err());
@@ -1614,7 +1613,7 @@ mod uvec2 {
 }
 
 mod i64vec2 {
-    use glam::{i64vec2, BVec2, I64Vec2, I64Vec3, IVec2, U64Vec2, UVec2};
+    use glam::{i64vec2, BVec2, I16Vec2, I64Vec2, I64Vec3, IVec2, U16Vec2, U64Vec2, UVec2};
 
     glam_test!(test_align, {
         use core::mem;
@@ -1628,7 +1627,10 @@ mod i64vec2 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(I64Vec2::new(1, 2), I64Vec2::from(I16Vec2::new(1, 2)));
+        assert_eq!(I64Vec2::new(1, 2), I64Vec2::from(U16Vec2::new(1, 2)));
         assert_eq!(I64Vec2::new(1, 2), I64Vec2::from(IVec2::new(1, 2)));
+        assert_eq!(I64Vec2::new(1, 2), I64Vec2::from(UVec2::new(1, 2)));
 
         assert_eq!(
             I64Vec2::new(1, 2),
@@ -1649,7 +1651,7 @@ mod i64vec2 {
 }
 
 mod u64vec2 {
-    use glam::{u64vec2, BVec2, I16Vec2, I64Vec2, IVec2, U64Vec2, U64Vec3, UVec2};
+    use glam::{u64vec2, BVec2, I16Vec2, I64Vec2, IVec2, U16Vec2, U64Vec2, U64Vec3, UVec2};
 
     glam_test!(test_align, {
         use core::mem;
@@ -1670,6 +1672,8 @@ mod u64vec2 {
         assert!(U64Vec2::try_from(I16Vec2::new(-1, 2)).is_err());
         assert!(U64Vec2::try_from(I16Vec2::new(1, -2)).is_err());
 
+        assert_eq!(U64Vec2::new(1, 2), U64Vec2::from(U16Vec2::new(1, 2)));
+
         assert_eq!(
             U64Vec2::new(1, 2),
             U64Vec2::try_from(IVec2::new(1, 2)).unwrap()
diff --git a/tests/vec3.rs b/tests/vec3.rs
index 129e51c..0997826 100644
--- a/tests/vec3.rs
+++ b/tests/vec3.rs
@@ -1180,11 +1180,16 @@ mod vec3 {
     });
 
     glam_test!(test_as, {
-        use glam::{DVec3, I64Vec3, IVec3, U64Vec3, UVec3, Vec3A};
+        use glam::{DVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3, Vec3A};
         assert_eq!(
             DVec3::new(-1.0, -2.0, -3.0),
             Vec3::new(-1.0, -2.0, -3.0).as_dvec3()
         );
+        assert_eq!(
+            I16Vec3::new(-1, -2, -3),
+            Vec3::new(-1.0, -2.0, -3.0).as_i16vec3()
+        );
+        assert_eq!(U16Vec3::new(1, 2, 3), Vec3::new(1.0, 2.0, 3.0).as_u16vec3());
         assert_eq!(
             IVec3::new(-1, -2, -3),
             Vec3::new(-1.0, -2.0, -3.0).as_ivec3()
@@ -1200,6 +1205,14 @@ mod vec3 {
             DVec3::new(-1.0, -2.0, -3.0),
             Vec3A::new(-1.0, -2.0, -3.0).as_dvec3()
         );
+        assert_eq!(
+            I16Vec3::new(-1, -2, -3),
+            Vec3A::new(-1.0, -2.0, -3.0).as_i16vec3()
+        );
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            Vec3A::new(1.0, 2.0, 3.0).as_u16vec3()
+        );
         assert_eq!(
             IVec3::new(-1, -2, -3),
             Vec3A::new(-1.0, -2.0, -3.0).as_ivec3()
@@ -1214,6 +1227,14 @@ mod vec3 {
             Vec3A::new(1.0, 2.0, 3.0).as_u64vec3()
         );
 
+        assert_eq!(
+            I16Vec3::new(-1, -2, -3),
+            DVec3::new(-1.0, -2.0, -3.0).as_i16vec3()
+        );
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            DVec3::new(1.0, 2.0, 3.0).as_u16vec3()
+        );
         assert_eq!(
             IVec3::new(-1, -2, -3),
             DVec3::new(-1.0, -2.0, -3.0).as_ivec3()
@@ -1236,12 +1257,50 @@ mod vec3 {
             DVec3::new(-1.0, -2.0, -3.0).as_vec3a()
         );
 
+        assert_eq!(
+            DVec3::new(-1.0, -2.0, -3.0),
+            I16Vec3::new(-1, -2, -3).as_dvec3()
+        );
+        assert_eq!(U16Vec3::new(1, 2, 3), I16Vec3::new(1, 2, 3).as_u16vec3());
+        assert_eq!(IVec3::new(-1, -2, -3), I16Vec3::new(-1, -2, -3).as_ivec3());
+        assert_eq!(UVec3::new(1, 2, 3), I16Vec3::new(1, 2, 3).as_uvec3());
+        assert_eq!(
+            I64Vec3::new(-1, -2, -3),
+            I16Vec3::new(-1, -2, -3).as_i64vec3()
+        );
+        assert_eq!(U64Vec3::new(1, 2, 3), I16Vec3::new(1, 2, 3).as_u64vec3());
+        assert_eq!(
+            Vec3::new(-1.0, -2.0, -3.0),
+            I16Vec3::new(-1, -2, -3).as_vec3()
+        );
+        assert_eq!(
+            Vec3A::new(-1.0, -2.0, -3.0),
+            I16Vec3::new(-1, -2, -3).as_vec3a()
+        );
+
+        assert_eq!(DVec3::new(1.0, 2.0, 3.0), U16Vec3::new(1, 2, 3).as_dvec3());
+        assert_eq!(I16Vec3::new(1, 2, 3), U16Vec3::new(1, 2, 3).as_i16vec3());
+        assert_eq!(IVec3::new(1, 2, 3), U16Vec3::new(1, 2, 3).as_ivec3());
+        assert_eq!(UVec3::new(1, 2, 3), U16Vec3::new(1, 2, 3).as_uvec3());
+        assert_eq!(I64Vec3::new(1, 2, 3), U16Vec3::new(1, 2, 3).as_i64vec3());
+        assert_eq!(U64Vec3::new(1, 2, 3), U16Vec3::new(1, 2, 3).as_u64vec3());
+        assert_eq!(Vec3::new(1.0, 2.0, 3.0), U16Vec3::new(1, 2, 3).as_vec3());
+        assert_eq!(Vec3A::new(1.0, 2.0, 3.0), U16Vec3::new(1, 2, 3).as_vec3a());
+
         assert_eq!(
             DVec3::new(-1.0, -2.0, -3.0),
             IVec3::new(-1, -2, -3).as_dvec3()
         );
+        assert_eq!(
+            I16Vec3::new(-1, -2, -3),
+            IVec3::new(-1, -2, -3).as_i16vec3()
+        );
+        assert_eq!(U16Vec3::new(1, 2, 3), IVec3::new(1, 2, 3).as_u16vec3());
         assert_eq!(UVec3::new(1, 2, 3), IVec3::new(1, 2, 3).as_uvec3());
-        assert_eq!(I64Vec3::new(1, 2, 3), IVec3::new(1, 2, 3).as_i64vec3());
+        assert_eq!(
+            I64Vec3::new(-1, -2, -3),
+            IVec3::new(-1, -2, -3).as_i64vec3()
+        );
         assert_eq!(U64Vec3::new(1, 2, 3), IVec3::new(1, 2, 3).as_u64vec3());
         assert_eq!(
             Vec3::new(-1.0, -2.0, -3.0),
@@ -1253,6 +1312,8 @@ mod vec3 {
         );
 
         assert_eq!(DVec3::new(1.0, 2.0, 3.0), UVec3::new(1, 2, 3).as_dvec3());
+        assert_eq!(I16Vec3::new(1, 2, 3), UVec3::new(1, 2, 3).as_i16vec3());
+        assert_eq!(U16Vec3::new(1, 2, 3), UVec3::new(1, 2, 3).as_u16vec3());
         assert_eq!(IVec3::new(1, 2, 3), UVec3::new(1, 2, 3).as_ivec3());
         assert_eq!(I64Vec3::new(1, 2, 3), UVec3::new(1, 2, 3).as_i64vec3());
         assert_eq!(U64Vec3::new(1, 2, 3), UVec3::new(1, 2, 3).as_u64vec3());
@@ -1263,8 +1324,13 @@ mod vec3 {
             DVec3::new(-1.0, -2.0, -3.0),
             I64Vec3::new(-1, -2, -3).as_dvec3()
         );
+        assert_eq!(U16Vec3::new(1, 2, 3), I64Vec3::new(1, 2, 3).as_u16vec3());
+        assert_eq!(
+            I16Vec3::new(-1, -2, -3),
+            I64Vec3::new(-1, -2, -3).as_i16vec3()
+        );
         assert_eq!(UVec3::new(1, 2, 3), I64Vec3::new(1, 2, 3).as_uvec3());
-        assert_eq!(IVec3::new(1, 2, 3), I64Vec3::new(1, 2, 3).as_ivec3());
+        assert_eq!(IVec3::new(-1, -2, -3), I64Vec3::new(-1, -2, -3).as_ivec3());
         assert_eq!(U64Vec3::new(1, 2, 3), I64Vec3::new(1, 2, 3).as_u64vec3());
         assert_eq!(
             Vec3::new(-1.0, -2.0, -3.0),
@@ -1276,9 +1342,11 @@ mod vec3 {
         );
 
         assert_eq!(DVec3::new(1.0, 2.0, 3.0), U64Vec3::new(1, 2, 3).as_dvec3());
+        assert_eq!(I16Vec3::new(1, 2, 3), U64Vec3::new(1, 2, 3).as_i16vec3());
+        assert_eq!(U16Vec3::new(1, 2, 3), U64Vec3::new(1, 2, 3).as_u16vec3());
         assert_eq!(IVec3::new(1, 2, 3), U64Vec3::new(1, 2, 3).as_ivec3());
-        assert_eq!(I64Vec3::new(1, 2, 3), U64Vec3::new(1, 2, 3).as_i64vec3());
         assert_eq!(UVec3::new(1, 2, 3), U64Vec3::new(1, 2, 3).as_uvec3());
+        assert_eq!(I64Vec3::new(1, 2, 3), U64Vec3::new(1, 2, 3).as_i64vec3());
         assert_eq!(Vec3::new(1.0, 2.0, 3.0), U64Vec3::new(1, 2, 3).as_vec3());
         assert_eq!(Vec3A::new(1.0, 2.0, 3.0), U64Vec3::new(1, 2, 3).as_vec3a());
     });
@@ -1379,8 +1447,250 @@ mod dvec3 {
     impl_vec3_float_tests!(f64, dvec3, DVec3, BVec3);
 }
 
+mod i16vec3 {
+    use glam::{i16vec3, BVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3};
+
+    glam_test!(test_align, {
+        use std::mem;
+        assert_eq!(6, mem::size_of::<I16Vec3>());
+        assert_eq!(2, mem::align_of::<I16Vec3>());
+    });
+
+    glam_test!(test_try_from, {
+        assert_eq!(
+            I16Vec3::new(1, 2, 3),
+            I16Vec3::try_from(U16Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(I16Vec3::try_from(U16Vec3::new(u16::MAX, 2, 3)).is_err());
+        assert!(I16Vec3::try_from(U16Vec3::new(1, u16::MAX, 3)).is_err());
+        assert!(I16Vec3::try_from(U16Vec3::new(1, 2, u16::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec3::new(1, 2, 3),
+            I16Vec3::try_from(IVec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(I16Vec3::try_from(IVec3::new(i32::MAX, 2, 3)).is_err());
+        assert!(I16Vec3::try_from(IVec3::new(1, i32::MAX, 3)).is_err());
+        assert!(I16Vec3::try_from(IVec3::new(1, 2, i32::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec3::new(1, 2, 3),
+            I16Vec3::try_from(UVec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(I16Vec3::try_from(UVec3::new(u32::MAX, 2, 3)).is_err());
+        assert!(I16Vec3::try_from(UVec3::new(1, u32::MAX, 3)).is_err());
+        assert!(I16Vec3::try_from(UVec3::new(1, 2, u32::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec3::new(1, 2, 3),
+            I16Vec3::try_from(I64Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(I16Vec3::try_from(I64Vec3::new(i64::MAX, 2, 3)).is_err());
+        assert!(I16Vec3::try_from(I64Vec3::new(1, i64::MAX, 3)).is_err());
+        assert!(I16Vec3::try_from(I64Vec3::new(1, 2, i64::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec3::new(1, 2, 3),
+            I16Vec3::try_from(U64Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(I16Vec3::try_from(U64Vec3::new(u64::MAX, 2, 3)).is_err());
+        assert!(I16Vec3::try_from(U64Vec3::new(1, u64::MAX, 3)).is_err());
+        assert!(I16Vec3::try_from(U64Vec3::new(1, 2, u64::MAX)).is_err());
+    });
+
+    glam_test!(test_wrapping_add, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, 5, i16::MIN).wrapping_add(I16Vec3::new(1, 3, i16::MAX)),
+            I16Vec3::new(i16::MIN, 8, -1),
+        );
+    });
+
+    glam_test!(test_wrapping_sub, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, 5, i16::MIN).wrapping_sub(I16Vec3::new(1, 3, i16::MAX)),
+            I16Vec3::new(32766, 2, 1),
+        );
+    });
+
+    glam_test!(test_wrapping_mul, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, 5, i16::MIN).wrapping_mul(I16Vec3::new(3, 3, 5)),
+            I16Vec3::new(32765, 15, -32768)
+        );
+    });
+
+    glam_test!(test_wrapping_div, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, 5, i16::MIN).wrapping_div(I16Vec3::new(3, 3, 5)),
+            I16Vec3::new(10922, 1, -6553)
+        );
+    });
+
+    glam_test!(test_saturating_add, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, i16::MIN, 0).saturating_add(I16Vec3::new(1, -1, 2)),
+            I16Vec3::new(i16::MAX, i16::MIN, 2)
+        );
+    });
+
+    glam_test!(test_saturating_sub, {
+        assert_eq!(
+            I16Vec3::new(i16::MIN, i16::MAX, 0).saturating_sub(I16Vec3::new(1, -1, 2)),
+            I16Vec3::new(i16::MIN, i16::MAX, -2)
+        );
+    });
+
+    glam_test!(test_saturating_mul, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, i16::MIN, 0).saturating_mul(I16Vec3::new(2, 2, 0)),
+            I16Vec3::new(i16::MAX, i16::MIN, 0)
+        );
+    });
+
+    glam_test!(test_saturating_div, {
+        assert_eq!(
+            I16Vec3::new(i16::MAX, i16::MIN, 0).saturating_div(I16Vec3::new(2, 2, 3)),
+            I16Vec3::new(16383, -16384, 0)
+        );
+    });
+
+    impl_vec3_signed_integer_tests!(i16, i16vec3, I16Vec3, BVec3);
+    impl_vec3_eq_hash_tests!(i16, i16vec3);
+
+    impl_vec3_scalar_shift_op_tests!(I16Vec3, -2, 2);
+    impl_vec3_shift_op_tests!(I16Vec3);
+
+    impl_vec3_scalar_bit_op_tests!(I16Vec3, -2, 2);
+    impl_vec3_bit_op_tests!(I16Vec3, -2, 2);
+}
+
+mod u16vec3 {
+    use glam::{u16vec3, BVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3};
+
+    glam_test!(test_align, {
+        use std::mem;
+        assert_eq!(6, mem::size_of::<U16Vec3>());
+        assert_eq!(2, mem::align_of::<U16Vec3>());
+    });
+
+    glam_test!(test_try_from, {
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            U16Vec3::try_from(I16Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U16Vec3::try_from(I16Vec3::new(-1, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(I16Vec3::new(1, -2, 3)).is_err());
+        assert!(U16Vec3::try_from(I16Vec3::new(1, 2, -3)).is_err());
+
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            U16Vec3::try_from(IVec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U16Vec3::try_from(IVec3::new(-1, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(IVec3::new(1, -2, 3)).is_err());
+        assert!(U16Vec3::try_from(IVec3::new(1, 2, -3)).is_err());
+
+        assert!(U16Vec3::try_from(IVec3::new(i32::MAX, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(IVec3::new(1, i32::MAX, 3)).is_err());
+        assert!(U16Vec3::try_from(IVec3::new(1, 2, i32::MAX)).is_err());
+
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            U16Vec3::try_from(UVec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U16Vec3::try_from(UVec3::new(u32::MAX, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(UVec3::new(1, u32::MAX, 3)).is_err());
+        assert!(U16Vec3::try_from(UVec3::new(1, 2, u32::MAX)).is_err());
+
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            U16Vec3::try_from(I64Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U16Vec3::try_from(I64Vec3::new(-1, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(I64Vec3::new(1, -2, 3)).is_err());
+        assert!(U16Vec3::try_from(I64Vec3::new(1, 2, -3)).is_err());
+
+        assert!(U16Vec3::try_from(I64Vec3::new(i64::MAX, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(I64Vec3::new(1, i64::MAX, 3)).is_err());
+        assert!(U16Vec3::try_from(I64Vec3::new(1, 2, i64::MAX)).is_err());
+
+        assert_eq!(
+            U16Vec3::new(1, 2, 3),
+            U16Vec3::try_from(U64Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U16Vec3::try_from(U64Vec3::new(u64::MAX, 2, 3)).is_err());
+        assert!(U16Vec3::try_from(U64Vec3::new(1, u64::MAX, 3)).is_err());
+        assert!(U16Vec3::try_from(U64Vec3::new(1, 2, u64::MAX)).is_err());
+    });
+
+    glam_test!(test_wrapping_add, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, 5, u16::MAX).wrapping_add(U16Vec3::new(1, 3, u16::MAX)),
+            U16Vec3::new(0, 8, 65534),
+        );
+    });
+
+    glam_test!(test_wrapping_sub, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, 5, u16::MAX - 1).wrapping_sub(U16Vec3::new(1, 3, u16::MAX)),
+            U16Vec3::new(65534, 2, 65535)
+        );
+    });
+
+    glam_test!(test_wrapping_mul, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, 5, u16::MAX).wrapping_mul(U16Vec3::new(3, 3, 5)),
+            U16Vec3::new(65533, 15, 65531)
+        );
+    });
+
+    glam_test!(test_wrapping_div, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, 5, u16::MAX).wrapping_div(U16Vec3::new(3, 3, 5)),
+            U16Vec3::new(21845, 1, 13107)
+        );
+    });
+
+    glam_test!(test_saturating_add, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, u16::MAX, 0).saturating_add(U16Vec3::new(1, u16::MAX, 2)),
+            U16Vec3::new(u16::MAX, u16::MAX, 2)
+        );
+    });
+
+    glam_test!(test_saturating_sub, {
+        assert_eq!(
+            U16Vec3::new(0, u16::MAX, 0).saturating_sub(U16Vec3::new(1, 1, 2)),
+            U16Vec3::new(0, 65534, 0)
+        );
+    });
+
+    glam_test!(test_saturating_mul, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, u16::MAX, 0).saturating_mul(U16Vec3::new(2, u16::MAX, 0)),
+            U16Vec3::new(u16::MAX, u16::MAX, 0)
+        );
+    });
+
+    glam_test!(test_saturating_div, {
+        assert_eq!(
+            U16Vec3::new(u16::MAX, u16::MAX, 0).saturating_div(U16Vec3::new(2, u16::MAX, 3)),
+            U16Vec3::new(32767, 1, 0)
+        );
+    });
+
+    impl_vec3_tests!(u16, u16vec3, U16Vec3, BVec3);
+    impl_vec3_eq_hash_tests!(u16, u16vec3);
+
+    impl_vec3_scalar_shift_op_tests!(U16Vec3, 0, 2);
+    impl_vec3_shift_op_tests!(U16Vec3);
+
+    impl_vec3_scalar_bit_op_tests!(U16Vec3, 0, 2);
+    impl_vec3_bit_op_tests!(U16Vec3, 0, 2);
+}
+
 mod ivec3 {
-    use glam::{ivec3, BVec3, I64Vec3, IVec3, U64Vec3, UVec3};
+    use glam::{ivec3, BVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3};
 
     glam_test!(test_align, {
         use std::mem;
@@ -1391,6 +1701,9 @@ mod ivec3 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(IVec3::new(1, 2, 3), IVec3::from(U16Vec3::new(1, 2, 3)));
+        assert_eq!(IVec3::new(1, 2, 3), IVec3::from(I16Vec3::new(1, 2, 3)));
+
         assert_eq!(
             IVec3::new(1, 2, 3),
             IVec3::try_from(UVec3::new(1, 2, 3)).unwrap()
@@ -1483,7 +1796,7 @@ mod ivec3 {
 }
 
 mod uvec3 {
-    use glam::{uvec3, BVec3, I64Vec3, IVec3, U64Vec3, UVec3};
+    use glam::{uvec3, BVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3};
 
     glam_test!(test_align, {
         use std::mem;
@@ -1494,6 +1807,16 @@ mod uvec3 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(
+            UVec3::new(1, 2, 3),
+            UVec3::try_from(I16Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(UVec3::try_from(I16Vec3::new(-1, 2, 3)).is_err());
+        assert!(UVec3::try_from(I16Vec3::new(1, -2, 3)).is_err());
+        assert!(UVec3::try_from(I16Vec3::new(1, 2, -3)).is_err());
+
+        assert_eq!(UVec3::new(1, 2, 3), UVec3::from(U16Vec3::new(1, 2, 3)));
+
         assert_eq!(
             UVec3::new(1, 2, 3),
             UVec3::try_from(IVec3::new(1, 2, 3)).unwrap()
@@ -1590,7 +1913,7 @@ mod uvec3 {
 }
 
 mod i64vec3 {
-    use glam::{i64vec3, BVec3, I64Vec3, IVec3, U64Vec3, UVec3};
+    use glam::{i64vec3, BVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3};
 
     glam_test!(test_align, {
         use std::mem;
@@ -1601,7 +1924,10 @@ mod i64vec3 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(I64Vec3::new(1, 2, 3), I64Vec3::from(I16Vec3::new(1, 2, 3)));
+        assert_eq!(I64Vec3::new(1, 2, 3), I64Vec3::from(U16Vec3::new(1, 2, 3)));
         assert_eq!(I64Vec3::new(1, 2, 3), I64Vec3::from(IVec3::new(1, 2, 3)));
+        assert_eq!(I64Vec3::new(1, 2, 3), I64Vec3::from(UVec3::new(1, 2, 3)));
 
         assert_eq!(
             I64Vec3::new(1, 2, 3),
@@ -1623,7 +1949,7 @@ mod i64vec3 {
 }
 
 mod u64vec3 {
-    use glam::{u64vec3, BVec3, I64Vec3, IVec3, U64Vec3, UVec3};
+    use glam::{u64vec3, BVec3, I16Vec3, I64Vec3, IVec3, U16Vec3, U64Vec3, UVec3};
 
     glam_test!(test_align, {
         use std::mem;
@@ -1634,6 +1960,24 @@ mod u64vec3 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(
+            U64Vec3::new(1, 2, 3),
+            U64Vec3::try_from(I16Vec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U64Vec3::try_from(I16Vec3::new(-1, 2, 3)).is_err());
+        assert!(U64Vec3::try_from(I16Vec3::new(1, -2, 3)).is_err());
+        assert!(U64Vec3::try_from(I16Vec3::new(1, 2, -3)).is_err());
+
+        assert_eq!(U64Vec3::new(1, 2, 3), U64Vec3::from(U16Vec3::new(1, 2, 3)));
+
+        assert_eq!(
+            U64Vec3::new(1, 2, 3),
+            U64Vec3::try_from(IVec3::new(1, 2, 3)).unwrap()
+        );
+        assert!(U64Vec3::try_from(IVec3::new(-1, 2, 3)).is_err());
+        assert!(U64Vec3::try_from(IVec3::new(1, -2, 3)).is_err());
+        assert!(U64Vec3::try_from(IVec3::new(1, 2, -3)).is_err());
+
         assert_eq!(U64Vec3::new(1, 2, 3), U64Vec3::from(UVec3::new(1, 2, 3)));
 
         assert_eq!(
diff --git a/tests/vec4.rs b/tests/vec4.rs
index 5ecba39..0ff9a32 100644
--- a/tests/vec4.rs
+++ b/tests/vec4.rs
@@ -1338,11 +1338,19 @@ mod vec4 {
     }
 
     glam_test!(test_as, {
-        use glam::{DVec4, I64Vec4, IVec4, U64Vec4, UVec4};
+        use glam::{DVec4, I16Vec4, I64Vec4, IVec4, U16Vec4, U64Vec4, UVec4, Vec4};
         assert_eq!(
             DVec4::new(-1.0, -2.0, -3.0, -4.0),
             Vec4::new(-1.0, -2.0, -3.0, -4.0).as_dvec4()
         );
+        assert_eq!(
+            I16Vec4::new(-1, -2, -3, -4),
+            Vec4::new(-1.0, -2.0, -3.0, -4.0).as_i16vec4()
+        );
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            Vec4::new(1.0, 2.0, 3.0, 4.0).as_u16vec4()
+        );
         assert_eq!(
             IVec4::new(-1, -2, -3, -4),
             Vec4::new(-1.0, -2.0, -3.0, -4.0).as_ivec4()
@@ -1352,14 +1360,26 @@ mod vec4 {
             Vec4::new(1.0, 2.0, 3.0, 4.0).as_uvec4()
         );
         assert_eq!(
-            I64Vec4::new(1, 2, 3, 4),
-            Vec4::new(1.0, 2.0, 3.0, 4.0).as_i64vec4()
+            I64Vec4::new(-1, -2, -3, -4),
+            Vec4::new(-1.0, -2.0, -3.0, -4.0).as_i64vec4()
         );
         assert_eq!(
             U64Vec4::new(1, 2, 3, 4),
             Vec4::new(1.0, 2.0, 3.0, 4.0).as_u64vec4()
         );
 
+        assert_eq!(
+            Vec4::new(-1.0, -2.0, -3.0, -4.0),
+            DVec4::new(-1.0, -2.0, -3.0, -4.0).as_vec4()
+        );
+        assert_eq!(
+            I16Vec4::new(-1, -2, -3, -4),
+            DVec4::new(-1.0, -2.0, -3.0, -4.0).as_i16vec4()
+        );
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            DVec4::new(1.0, 2.0, 3.0, 4.0).as_u16vec4()
+        );
         assert_eq!(
             IVec4::new(-1, -2, -3, -4),
             DVec4::new(-1.0, -2.0, -3.0, -4.0).as_ivec4()
@@ -1368,46 +1388,107 @@ mod vec4 {
             UVec4::new(1, 2, 3, 4),
             DVec4::new(1.0, 2.0, 3.0, 4.0).as_uvec4()
         );
+        assert_eq!(
+            I64Vec4::new(-1, -2, -3, -4),
+            DVec4::new(-1.0, -2.0, -3.0, -4.0).as_i64vec4()
+        );
+        assert_eq!(
+            U64Vec4::new(1, 2, 3, 4),
+            DVec4::new(1.0, 2.0, 3.0, 4.0).as_u64vec4()
+        );
+
         assert_eq!(
             Vec4::new(-1.0, -2.0, -3.0, -4.0),
-            DVec4::new(-1.0, -2.0, -3.0, -4.0).as_vec4()
+            I16Vec4::new(-1, -2, -3, -4).as_vec4()
+        );
+        assert_eq!(
+            DVec4::new(-1.0, -2.0, -3.0, -4.0),
+            I16Vec4::new(-1, -2, -3, -4).as_dvec4()
+        );
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            I16Vec4::new(1, 2, 3, 4).as_u16vec4()
+        );
+        assert_eq!(
+            IVec4::new(-1, -2, -3, -4),
+            I16Vec4::new(-1, -2, -3, -4).as_ivec4()
+        );
+        assert_eq!(UVec4::new(1, 2, 3, 4), I16Vec4::new(1, 2, 3, 4).as_uvec4());
+        assert_eq!(
+            I64Vec4::new(-1, -2, -3, -4),
+            I16Vec4::new(-1, -2, -3, -4).as_i64vec4()
+        );
+        assert_eq!(
+            U64Vec4::new(1, 2, 3, 4),
+            I16Vec4::new(1, 2, 3, 4).as_u64vec4()
+        );
+
+        assert_eq!(
+            Vec4::new(1.0, 2.0, 3.0, 4.0),
+            U16Vec4::new(1, 2, 3, 4).as_vec4()
         );
+        assert_eq!(
+            DVec4::new(1.0, 2.0, 3.0, 4.0),
+            U16Vec4::new(1, 2, 3, 4).as_dvec4()
+        );
+        assert_eq!(
+            I16Vec4::new(1, 2, 3, 4),
+            U16Vec4::new(1, 2, 3, 4).as_i16vec4()
+        );
+        assert_eq!(IVec4::new(1, 2, 3, 4), U16Vec4::new(1, 2, 3, 4).as_ivec4());
+        assert_eq!(UVec4::new(1, 2, 3, 4), U16Vec4::new(1, 2, 3, 4).as_uvec4());
         assert_eq!(
             I64Vec4::new(1, 2, 3, 4),
-            DVec4::new(1.0, 2.0, 3.0, 4.0).as_i64vec4()
+            U16Vec4::new(1, 2, 3, 4).as_i64vec4()
         );
         assert_eq!(
             U64Vec4::new(1, 2, 3, 4),
-            DVec4::new(1.0, 2.0, 3.0, 4.0).as_u64vec4()
+            U16Vec4::new(1, 2, 3, 4).as_u64vec4()
         );
 
+        assert_eq!(
+            Vec4::new(-1.0, -2.0, -3.0, -4.0),
+            IVec4::new(-1, -2, -3, -4).as_vec4()
+        );
         assert_eq!(
             DVec4::new(-1.0, -2.0, -3.0, -4.0),
             IVec4::new(-1, -2, -3, -4).as_dvec4()
         );
         assert_eq!(UVec4::new(1, 2, 3, 4), IVec4::new(1, 2, 3, 4).as_uvec4());
         assert_eq!(
-            Vec4::new(-1.0, -2.0, -3.0, -4.0),
-            IVec4::new(-1, -2, -3, -4).as_vec4()
+            I16Vec4::new(-1, -2, -3, -4),
+            IVec4::new(-1, -2, -3, -4).as_i16vec4()
         );
         assert_eq!(
-            I64Vec4::new(1, 2, 3, 4),
-            IVec4::new(1, 2, 3, 4).as_i64vec4()
+            U16Vec4::new(1, 2, 3, 4),
+            IVec4::new(1, 2, 3, 4).as_u16vec4()
+        );
+        assert_eq!(
+            I64Vec4::new(-1, -2, -3, -4),
+            IVec4::new(-1, -2, -3, -4).as_i64vec4()
         );
         assert_eq!(
             U64Vec4::new(1, 2, 3, 4),
             IVec4::new(1, 2, 3, 4).as_u64vec4()
         );
 
+        assert_eq!(
+            Vec4::new(1.0, 2.0, 3.0, 4.0),
+            UVec4::new(1, 2, 3, 4).as_vec4()
+        );
         assert_eq!(
             DVec4::new(1.0, 2.0, 3.0, 4.0),
             UVec4::new(1, 2, 3, 4).as_dvec4()
         );
-        assert_eq!(IVec4::new(1, 2, 3, 4), UVec4::new(1, 2, 3, 4).as_ivec4());
         assert_eq!(
-            Vec4::new(1.0, 2.0, 3.0, 4.0),
-            UVec4::new(1, 2, 3, 4).as_vec4()
+            I16Vec4::new(1, 2, 3, 4),
+            UVec4::new(1, 2, 3, 4).as_i16vec4()
+        );
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            UVec4::new(1, 2, 3, 4).as_u16vec4()
         );
+        assert_eq!(IVec4::new(1, 2, 3, 4), UVec4::new(1, 2, 3, 4).as_ivec4());
         assert_eq!(
             I64Vec4::new(1, 2, 3, 4),
             UVec4::new(1, 2, 3, 4).as_i64vec4()
@@ -1417,35 +1498,54 @@ mod vec4 {
             UVec4::new(1, 2, 3, 4).as_u64vec4()
         );
 
+        assert_eq!(
+            Vec4::new(-1.0, -2.0, -3.0, -4.0),
+            I64Vec4::new(-1, -2, -3, -4).as_vec4()
+        );
         assert_eq!(
             DVec4::new(-1.0, -2.0, -3.0, -4.0),
             I64Vec4::new(-1, -2, -3, -4).as_dvec4()
         );
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            I64Vec4::new(1, 2, 3, 4).as_u16vec4()
+        );
+        assert_eq!(
+            I16Vec4::new(-1, -2, -3, -4),
+            I64Vec4::new(-1, -2, -3, -4).as_i16vec4()
+        );
         assert_eq!(UVec4::new(1, 2, 3, 4), I64Vec4::new(1, 2, 3, 4).as_uvec4());
         assert_eq!(
-            Vec4::new(-1.0, -2.0, -3.0, -4.0),
-            I64Vec4::new(-1, -2, -3, -4).as_vec4()
+            IVec4::new(-1, -2, -3, -4),
+            I64Vec4::new(-1, -2, -3, -4).as_ivec4()
         );
-        assert_eq!(IVec4::new(1, 2, 3, 4), I64Vec4::new(1, 2, 3, 4).as_ivec4());
         assert_eq!(
             U64Vec4::new(1, 2, 3, 4),
             I64Vec4::new(1, 2, 3, 4).as_u64vec4()
         );
 
+        assert_eq!(
+            Vec4::new(1.0, 2.0, 3.0, 4.0),
+            U64Vec4::new(1, 2, 3, 4).as_vec4()
+        );
         assert_eq!(
             DVec4::new(1.0, 2.0, 3.0, 4.0),
             U64Vec4::new(1, 2, 3, 4).as_dvec4()
         );
-        assert_eq!(IVec4::new(1, 2, 3, 4), U64Vec4::new(1, 2, 3, 4).as_ivec4());
         assert_eq!(
-            Vec4::new(1.0, 2.0, 3.0, 4.0),
-            U64Vec4::new(1, 2, 3, 4).as_vec4()
+            I16Vec4::new(1, 2, 3, 4),
+            U64Vec4::new(1, 2, 3, 4).as_i16vec4()
         );
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            U64Vec4::new(1, 2, 3, 4).as_u16vec4()
+        );
+        assert_eq!(IVec4::new(1, 2, 3, 4), U64Vec4::new(1, 2, 3, 4).as_ivec4());
+        assert_eq!(UVec4::new(1, 2, 3, 4), U64Vec4::new(1, 2, 3, 4).as_uvec4());
         assert_eq!(
             I64Vec4::new(1, 2, 3, 4),
             U64Vec4::new(1, 2, 3, 4).as_i64vec4()
         );
-        assert_eq!(UVec4::new(1, 2, 3, 4), U64Vec4::new(1, 2, 3, 4).as_uvec4());
     });
 
     glam_test!(test_vec3a, {
@@ -1505,8 +1605,277 @@ mod dvec4 {
     impl_vec4_float_tests!(f64, dvec4, DVec4, DVec3, DVec2, BVec4);
 }
 
+mod i16vec4 {
+    use glam::{
+        i16vec4, BVec4, I16Vec2, I16Vec3, I16Vec4, I64Vec4, IVec4, U16Vec4, U64Vec4, UVec4,
+    };
+
+    glam_test!(test_align, {
+        use std::mem;
+        assert_eq!(8, mem::size_of::<I16Vec4>());
+        #[cfg(not(feature = "cuda"))]
+        assert_eq!(2, mem::align_of::<I16Vec4>());
+        #[cfg(feature = "cuda")]
+        assert_eq!(8, mem::align_of::<I16Vec4>());
+    });
+
+    glam_test!(test_try_from, {
+        assert_eq!(
+            I16Vec4::new(1, 2, 3, 4),
+            I16Vec4::try_from(U16Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(I16Vec4::try_from(U16Vec4::new(u16::MAX, 2, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(U16Vec4::new(1, u16::MAX, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(U16Vec4::new(1, 2, u16::MAX, 4)).is_err());
+        assert!(I16Vec4::try_from(U16Vec4::new(1, 2, 3, u16::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec4::new(1, 2, 3, 4),
+            I16Vec4::try_from(IVec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(I16Vec4::try_from(IVec4::new(i32::MAX, 2, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(IVec4::new(1, i32::MAX, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(IVec4::new(1, 2, i32::MAX, 4)).is_err());
+        assert!(I16Vec4::try_from(IVec4::new(1, 2, 3, i32::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec4::new(1, 2, 3, 4),
+            I16Vec4::try_from(UVec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(I16Vec4::try_from(UVec4::new(u32::MAX, 2, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(UVec4::new(1, u32::MAX, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(UVec4::new(1, 2, u32::MAX, 4)).is_err());
+        assert!(I16Vec4::try_from(UVec4::new(1, 2, 3, u32::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec4::new(1, 2, 3, 4),
+            I16Vec4::try_from(I64Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(I16Vec4::try_from(I64Vec4::new(i64::MAX, 2, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(I64Vec4::new(1, i64::MAX, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(I64Vec4::new(1, 2, i64::MAX, 4)).is_err());
+        assert!(I16Vec4::try_from(I64Vec4::new(1, 2, 3, i64::MAX)).is_err());
+
+        assert_eq!(
+            I16Vec4::new(1, 2, 3, 4),
+            I16Vec4::try_from(U64Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(I16Vec4::try_from(U64Vec4::new(u64::MAX, 2, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(U64Vec4::new(1, u64::MAX, 3, 4)).is_err());
+        assert!(I16Vec4::try_from(U64Vec4::new(1, 2, u64::MAX, 4)).is_err());
+        assert!(I16Vec4::try_from(U64Vec4::new(1, 2, 3, u64::MAX)).is_err());
+    });
+
+    glam_test!(test_wrapping_add, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, 5, i16::MIN, 0).wrapping_add(I16Vec4::new(1, 3, i16::MAX, 0)),
+            I16Vec4::new(i16::MIN, 8, -1, 0),
+        );
+    });
+
+    glam_test!(test_wrapping_sub, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, 5, i16::MIN, 0).wrapping_sub(I16Vec4::new(1, 3, i16::MAX, 0)),
+            I16Vec4::new(32766, 2, 1, 0)
+        );
+    });
+
+    glam_test!(test_wrapping_mul, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, 5, i16::MIN, 0).wrapping_mul(I16Vec4::new(3, 3, 5, 1)),
+            I16Vec4::new(32765, 15, -32768, 0)
+        );
+    });
+
+    glam_test!(test_wrapping_div, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, 5, i16::MIN, 0).wrapping_div(I16Vec4::new(3, 3, 5, 1)),
+            I16Vec4::new(10922, 1, -6553, 0)
+        );
+    });
+
+    glam_test!(test_saturating_add, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, i16::MIN, 0, 0).saturating_add(I16Vec4::new(1, -1, 2, 3)),
+            I16Vec4::new(i16::MAX, i16::MIN, 2, 3)
+        );
+    });
+
+    glam_test!(test_saturating_sub, {
+        assert_eq!(
+            I16Vec4::new(i16::MIN, i16::MAX, 0, 0).saturating_sub(I16Vec4::new(1, -1, 2, 3)),
+            I16Vec4::new(i16::MIN, i16::MAX, -2, -3)
+        );
+    });
+
+    glam_test!(test_saturating_mul, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, i16::MIN, 0, 0).saturating_mul(I16Vec4::new(2, 2, 0, 0)),
+            I16Vec4::new(i16::MAX, i16::MIN, 0, 0)
+        );
+    });
+
+    glam_test!(test_saturating_div, {
+        assert_eq!(
+            I16Vec4::new(i16::MAX, i16::MIN, 0, 0).saturating_div(I16Vec4::new(2, 2, 3, 4)),
+            I16Vec4::new(16383, -16384, 0, 0)
+        );
+    });
+
+    impl_vec4_signed_integer_tests!(i16, i16vec4, I16Vec4, I16Vec3, I16Vec2, BVec4);
+    impl_vec4_eq_hash_tests!(i16, i16vec4);
+
+    impl_vec4_scalar_shift_op_tests!(I16Vec4, -2, 2);
+    impl_vec4_shift_op_tests!(I16Vec4);
+
+    impl_vec4_scalar_bit_op_tests!(I16Vec4, -2, 2);
+    impl_vec4_bit_op_tests!(I16Vec4, -2, 2);
+}
+
+mod u16vec4 {
+    use glam::{
+        u16vec4, BVec4, I16Vec4, I64Vec4, IVec4, U16Vec2, U16Vec3, U16Vec4, U64Vec4, UVec4,
+    };
+
+    glam_test!(test_align, {
+        use std::mem;
+        assert_eq!(8, mem::size_of::<U16Vec4>());
+        #[cfg(not(feature = "cuda"))]
+        assert_eq!(2, mem::align_of::<U16Vec4>());
+        #[cfg(feature = "cuda")]
+        assert_eq!(8, mem::align_of::<U16Vec4>());
+    });
+
+    glam_test!(test_try_from, {
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            U16Vec4::try_from(I16Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U16Vec4::try_from(I16Vec4::new(-1, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(I16Vec4::new(1, -2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(I16Vec4::new(1, 2, -3, 4)).is_err());
+        assert!(U16Vec4::try_from(I16Vec4::new(1, 2, 3, -4)).is_err());
+
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            U16Vec4::try_from(IVec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U16Vec4::try_from(IVec4::new(-1, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(IVec4::new(1, -2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(IVec4::new(1, 2, -3, 4)).is_err());
+        assert!(U16Vec4::try_from(IVec4::new(1, 2, 3, -4)).is_err());
+
+        assert!(U16Vec4::try_from(IVec4::new(i32::MAX, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(IVec4::new(1, i32::MAX, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(IVec4::new(1, 2, i32::MAX, 4)).is_err());
+        assert!(U16Vec4::try_from(IVec4::new(1, 2, 3, i32::MAX)).is_err());
+
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            U16Vec4::try_from(UVec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U16Vec4::try_from(UVec4::new(u32::MAX, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(UVec4::new(1, u32::MAX, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(UVec4::new(1, 2, u32::MAX, 4)).is_err());
+        assert!(U16Vec4::try_from(UVec4::new(1, 2, 3, u32::MAX)).is_err());
+
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            U16Vec4::try_from(I64Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U16Vec4::try_from(I64Vec4::new(-1, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(I64Vec4::new(1, -2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(I64Vec4::new(1, 2, -3, 4)).is_err());
+        assert!(U16Vec4::try_from(I64Vec4::new(1, 2, 3, -4)).is_err());
+
+        assert!(U16Vec4::try_from(I64Vec4::new(i64::MAX, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(I64Vec4::new(1, i64::MAX, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(I64Vec4::new(1, 2, i64::MAX, 4)).is_err());
+        assert!(U16Vec4::try_from(I64Vec4::new(1, 2, 3, i64::MAX)).is_err());
+
+        assert_eq!(
+            U16Vec4::new(1, 2, 3, 4),
+            U16Vec4::try_from(U64Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U16Vec4::try_from(U64Vec4::new(u64::MAX, 2, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(U64Vec4::new(1, u64::MAX, 3, 4)).is_err());
+        assert!(U16Vec4::try_from(U64Vec4::new(1, 2, u64::MAX, 4)).is_err());
+        assert!(U16Vec4::try_from(U64Vec4::new(1, 2, 3, u64::MAX)).is_err());
+    });
+
+    glam_test!(test_wrapping_add, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, 5, u16::MAX, 0).wrapping_add(U16Vec4::new(1, 3, u16::MAX, 0)),
+            U16Vec4::new(0, 8, 65534, 0),
+        );
+    });
+
+    glam_test!(test_wrapping_sub, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, 5, u16::MAX - 1, 0).wrapping_sub(U16Vec4::new(
+                1,
+                3,
+                u16::MAX,
+                0
+            )),
+            U16Vec4::new(65534, 2, 65535, 0)
+        );
+    });
+
+    glam_test!(test_wrapping_mul, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, 5, u16::MAX, 0).wrapping_mul(U16Vec4::new(3, 3, 5, 1)),
+            U16Vec4::new(65533, 15, 65531, 0)
+        );
+    });
+
+    glam_test!(test_wrapping_div, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, 5, u16::MAX, 0).wrapping_div(U16Vec4::new(3, 3, 5, 1)),
+            U16Vec4::new(21845, 1, 13107, 0)
+        );
+    });
+
+    glam_test!(test_saturating_add, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, u16::MAX, 0, 0).saturating_add(U16Vec4::new(1, u16::MAX, 2, 3)),
+            U16Vec4::new(u16::MAX, u16::MAX, 2, 3)
+        );
+    });
+
+    glam_test!(test_saturating_sub, {
+        assert_eq!(
+            U16Vec4::new(0, u16::MAX, 0, 0).saturating_sub(U16Vec4::new(1, 1, 2, 3)),
+            U16Vec4::new(0, 65534, 0, 0)
+        );
+    });
+
+    glam_test!(test_saturating_mul, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, u16::MAX, 0, 0).saturating_mul(U16Vec4::new(2, u16::MAX, 0, 0)),
+            U16Vec4::new(u16::MAX, u16::MAX, 0, 0)
+        );
+    });
+
+    glam_test!(test_saturating_div, {
+        assert_eq!(
+            U16Vec4::new(u16::MAX, u16::MAX, 0, 0).saturating_div(U16Vec4::new(2, u16::MAX, 3, 4)),
+            U16Vec4::new(32767, 1, 0, 0)
+        );
+    });
+
+    impl_vec4_tests!(u16, u16vec4, U16Vec4, U16Vec3, U16Vec2, BVec4);
+    impl_vec4_eq_hash_tests!(u16, u16vec4);
+
+    impl_vec4_scalar_shift_op_tests!(U16Vec4, 0, 2);
+    impl_vec4_shift_op_tests!(U16Vec4);
+
+    impl_vec4_scalar_bit_op_tests!(U16Vec4, 0, 2);
+    impl_vec4_bit_op_tests!(U16Vec4, 0, 2);
+}
+
 mod ivec4 {
-    use glam::{ivec4, BVec4, I64Vec4, IVec2, IVec3, IVec4, U64Vec4, UVec4};
+    use glam::{ivec4, BVec4, I16Vec4, I64Vec4, IVec2, IVec3, IVec4, U16Vec4, U64Vec4, UVec4};
 
     glam_test!(test_align, {
         use std::mem;
@@ -1520,6 +1889,15 @@ mod ivec4 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(
+            IVec4::new(1, 2, 3, 4),
+            IVec4::from(U16Vec4::new(1, 2, 3, 4))
+        );
+        assert_eq!(
+            IVec4::new(1, 2, 3, 4),
+            IVec4::from(I16Vec4::new(1, 2, 3, 4))
+        );
+
         assert_eq!(
             IVec4::new(1, 2, 3, 4),
             IVec4::try_from(UVec4::new(1, 2, 3, 4)).unwrap()
@@ -1615,7 +1993,7 @@ mod ivec4 {
 }
 
 mod uvec4 {
-    use glam::{uvec4, BVec4, I64Vec4, IVec4, U64Vec4, UVec2, UVec3, UVec4};
+    use glam::{uvec4, BVec4, I16Vec4, I64Vec4, IVec4, U16Vec4, U64Vec4, UVec2, UVec3, UVec4};
 
     glam_test!(test_align, {
         use std::mem;
@@ -1629,6 +2007,20 @@ mod uvec4 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(
+            UVec4::new(1, 2, 3, 4),
+            UVec4::try_from(I16Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(UVec4::try_from(I16Vec4::new(-1, 2, 3, 4)).is_err());
+        assert!(UVec4::try_from(I16Vec4::new(1, -2, 3, 4)).is_err());
+        assert!(UVec4::try_from(I16Vec4::new(1, 2, -3, 4)).is_err());
+        assert!(UVec4::try_from(I16Vec4::new(1, 2, 3, -4)).is_err());
+
+        assert_eq!(
+            UVec4::new(1, 2, 3, 4),
+            UVec4::from(U16Vec4::new(1, 2, 3, 4))
+        );
+
         assert_eq!(
             UVec4::new(1, 2, 3, 4),
             UVec4::try_from(IVec4::new(1, 2, 3, 4)).unwrap()
@@ -1729,7 +2121,9 @@ mod uvec4 {
 }
 
 mod i64vec4 {
-    use glam::{i64vec4, BVec4, I64Vec2, I64Vec3, I64Vec4, IVec4, U64Vec4, UVec4};
+    use glam::{
+        i64vec4, BVec4, I16Vec4, I64Vec2, I64Vec3, I64Vec4, IVec4, U16Vec4, U64Vec4, UVec4,
+    };
 
     glam_test!(test_align, {
         use std::mem;
@@ -1743,10 +2137,22 @@ mod i64vec4 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(
+            I64Vec4::new(1, 2, 3, 4),
+            I64Vec4::from(I16Vec4::new(1, 2, 3, 4))
+        );
+        assert_eq!(
+            I64Vec4::new(1, 2, 3, 4),
+            I64Vec4::from(U16Vec4::new(1, 2, 3, 4))
+        );
         assert_eq!(
             I64Vec4::new(1, 2, 3, 4),
             I64Vec4::from(IVec4::new(1, 2, 3, 4))
         );
+        assert_eq!(
+            I64Vec4::new(1, 2, 3, 4),
+            I64Vec4::from(UVec4::new(1, 2, 3, 4))
+        );
 
         assert_eq!(
             I64Vec4::new(1, 2, 3, 4),
@@ -1769,7 +2175,9 @@ mod i64vec4 {
 }
 
 mod u64vec4 {
-    use glam::{u64vec4, BVec4, I64Vec4, IVec4, U64Vec2, U64Vec3, U64Vec4, UVec4};
+    use glam::{
+        u64vec4, BVec4, I16Vec4, I64Vec4, IVec4, U16Vec4, U64Vec2, U64Vec3, U64Vec4, UVec4,
+    };
 
     glam_test!(test_align, {
         use std::mem;
@@ -1783,6 +2191,29 @@ mod u64vec4 {
     });
 
     glam_test!(test_try_from, {
+        assert_eq!(
+            U64Vec4::new(1, 2, 3, 4),
+            U64Vec4::try_from(I16Vec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U64Vec4::try_from(I16Vec4::new(-1, 2, 3, 4)).is_err());
+        assert!(U64Vec4::try_from(I16Vec4::new(1, -2, 3, 4)).is_err());
+        assert!(U64Vec4::try_from(I16Vec4::new(1, 2, -3, 4)).is_err());
+        assert!(U64Vec4::try_from(I16Vec4::new(1, 2, 3, -4)).is_err());
+
+        assert_eq!(
+            U64Vec4::new(1, 2, 3, 4),
+            U64Vec4::from(U16Vec4::new(1, 2, 3, 4))
+        );
+
+        assert_eq!(
+            U64Vec4::new(1, 2, 3, 4),
+            U64Vec4::try_from(IVec4::new(1, 2, 3, 4)).unwrap()
+        );
+        assert!(U64Vec4::try_from(IVec4::new(-1, 2, 3, 4)).is_err());
+        assert!(U64Vec4::try_from(IVec4::new(1, -2, 3, 4)).is_err());
+        assert!(U64Vec4::try_from(IVec4::new(1, 2, -3, 4)).is_err());
+        assert!(U64Vec4::try_from(IVec4::new(1, 2, 3, -4)).is_err());
+
         assert_eq!(
             U64Vec4::new(1, 2, 3, 4),
             U64Vec4::from(UVec4::new(1, 2, 3, 4))