tint: refactor Number<T> constants for highest, lowest, etc.

Bug: tint:1581
Change-Id: I3945e8d6021370e5b9837e77d29eeb46fcb97082
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97560
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/number.cc b/src/tint/number.cc
index 6371442..91dbb45 100644
--- a/src/tint/number.cc
+++ b/src/tint/number.cc
@@ -34,10 +34,10 @@
 }
 
 f16::type f16::Quantize(f16::type value) {
-    if (value > kHighest) {
+    if (value > kHighestValue) {
         return std::numeric_limits<f16::type>::infinity();
     }
-    if (value < kLowest) {
+    if (value < kLowestValue) {
         return -std::numeric_limits<f16::type>::infinity();
     }
     // Below value must be within the finite range of a f16.
@@ -82,17 +82,17 @@
     // 2. We can decide whether a given normal f32 number v is in the set R, by looking at its
     // mantissa bits and biased exponent `e`. Recall that biased exponent e is unbiased exponent +
     // 127, and in the range of 1 to 254 for normal f32 number.
-    //   2.1. If e >= 143, i.e. abs(v) >= 2^16 > f16::kHighest = 0x1.ffcp15, v is larger than any
-    //   finite f16 value and can not be in set R.
-    //   2.2. If 142 >= e >= 113, or f16::kHighest >= abs(v) >= f16::kSmallest = 2^-14, v falls in
-    //   the range of normal f16 values. In this case, v is in the set R iff the lowest 13 mantissa
-    //   bits are all 0. (See below for proof)
+    //   2.1. If e >= 143, i.e. abs(v) >= 2^16 > f16::kHighestValue = 0x1.ffcp15, v is larger than
+    //   any finite f16 value and can not be in set R. 2.2. If 142 >= e >= 113, or
+    //   f16::kHighestValue >= abs(v) >= f16::kSmallestValue = 2^-14, v falls in the range of normal
+    //   f16 values. In this case, v is in the set R iff the lowest 13 mantissa bits are all 0. (See
+    //   below for proof)
     //     2.2.1. If we let v' be v with lowest 13 mantissa bits masked to 0, v' will be in set R
     //     and the largest one in set R that no larger than v. Such v' is the quantized value of v.
-    //   2.3. If 112 >= e >= 103, i.e. 2^-14 > abs(v) >= f16::kSmallestSubnormal = 2^-24, v falls in
-    //   the range of subnormal f16 values. In this case, v is in the set R iff the lowest 126-e
-    //   mantissa bits are all 0. Notice that 126-e is in range 14 to 23, inclusive. (See below for
-    //   proof)
+    //   2.3. If 112 >= e >= 103, i.e. 2^-14 > abs(v) >= f16::kSmallestSubnormalValue = 2^-24, v
+    //   falls in the range of subnormal f16 values. In this case, v is in the set R iff the lowest
+    //   126-e mantissa bits are all 0. Notice that 126-e is in range 14 to 23, inclusive. (See
+    //   below for proof)
     //     2.3.1. If we let v' be v with lowest 126-e mantissa bits masked to 0, v' will be in set R
     //     and the largest on in set R that no larger than v. Such v' is the quantized value of v.
     //   2.4. If 2^-24 > abs(v) > 0, i.e. 103 > e, v is smaller than any finite f16 value and not
@@ -174,17 +174,17 @@
     // in range [103, 112], or unbiased exponent in [-24, -15].
 
     float abs_value = std::fabs(value);
-    if (abs_value >= kSmallest) {
+    if (abs_value >= kSmallestValue) {
         // Value falls in the normal f16 range, quantize it to a normal f16 value by masking out
         // lowest 13 mantissa bits.
         u32 = u32 & ~((1u << 13) - 1);
-    } else if (abs_value >= kSmallestSubnormal) {
+    } else if (abs_value >= kSmallestSubnormalValue) {
         // Value should be quantized to a subnormal f16 value.
 
         // Get the biased exponent `e` of f32 value, e.g. value 127 representing exponent 2^0.
         uint32_t biased_exponent_original = (u32 & exponent_mask) >> 23;
-        // Since we ensure that kSmallest = 0x1f-14 > abs(value) >= kSmallestSubnormal = 0x1f-24,
-        // value will have a unbiased exponent in range -24 to -15 (inclusive), and the
+        // Since we ensure that kSmallestValue = 0x1f-14 > abs(value) >= kSmallestSubnormalValue =
+        // 0x1f-24, value will have a unbiased exponent in range -24 to -15 (inclusive), and the
         // corresponding biased exponent in f32 is in range 103 to 112 (inclusive).
         TINT_ASSERT(Semantic,
                     (103 <= biased_exponent_original) && (biased_exponent_original <= 112));
diff --git a/src/tint/number.h b/src/tint/number.h
index 32cca59..13ba76c 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -68,26 +68,47 @@
 template <typename T>
 constexpr bool IsNumeric = IsInteger<T> || IsFloatingPoint<T>;
 
+/// Resolves to the underlying type for a Number.
+template <typename T>
+using UnwrapNumber = typename detail::NumberUnwrapper<T>::type;
+
+/// NumberBase is a CRTP base class for Number<T>
+template <typename NumberT>
+struct NumberBase {
+    /// @returns value of type `Number<T>` with the highest value for that type.
+    static NumberT Highest() { return NumberT(NumberT::kHighestValue); }
+    /// @returns value of type `Number<T>` with the lowest value for that type.
+    static NumberT Lowest() { return NumberT(NumberT::kLowestValue); }
+    /// @returns value of type `Number<T>` with the smallest value for that type.
+    static NumberT Smallest() { return NumberT(NumberT::kSmallestValue); }
+    /// @returns value of type `Number<T>` that represents NaN for that type.
+    static NumberT NaN() {
+        return NumberT(std::numeric_limits<UnwrapNumber<NumberT>>::quiet_NaN());
+    }
+    /// @returns value of type `Number<T>` that represents infinity for that type.
+    static NumberT Inf() { return NumberT(std::numeric_limits<UnwrapNumber<NumberT>>::infinity()); }
+};
+
 /// Number wraps a integer or floating point number, enforcing explicit casting.
 template <typename T>
-struct Number {
+struct Number : NumberBase<Number<T>> {
     static_assert(IsNumeric<T>, "Number<T> constructed with non-numeric type");
 
     /// type is the underlying type of the Number
     using type = T;
 
     /// Highest finite representable value of this type.
-    static constexpr type kHighest = std::numeric_limits<type>::max();
+    static constexpr type kHighestValue = std::numeric_limits<type>::max();
 
     /// Lowest finite representable value of this type.
-    static constexpr type kLowest = std::numeric_limits<type>::lowest();
+    static constexpr type kLowestValue = std::numeric_limits<type>::lowest();
 
     /// Smallest positive normal value of this type.
-    static constexpr type kSmallest =
+    static constexpr type kSmallestValue =
         std::is_integral_v<type> ? 0 : std::numeric_limits<type>::min();
 
     /// Smallest positive subnormal value of this type, 0 for integral type.
-    static constexpr type kSmallestSubnormal =
+    static constexpr type kSmallestSubnormalValue =
         std::is_integral_v<type> ? 0 : std::numeric_limits<type>::denorm_min();
 
     /// Constructor. The value is zero-initialized.
@@ -123,10 +144,6 @@
     type value = {};
 };
 
-/// Resolves to the underlying type for a Number.
-template <typename T>
-using UnwrapNumber = typename detail::NumberUnwrapper<T>::type;
-
 /// Writes the number to the ostream.
 /// @param out the std::ostream to write to
 /// @param num the Number
@@ -139,23 +156,23 @@
 /// The partial specification of Number for f16 type, storing the f16 value as float,
 /// and enforcing proper explicit casting.
 template <>
-struct Number<detail::NumberKindF16> {
+struct Number<detail::NumberKindF16> : NumberBase<Number<detail::NumberKindF16>> {
     /// C++ does not have a native float16 type, so we use a 32-bit float instead.
     using type = float;
 
     /// Highest finite representable value of this type.
-    static constexpr type kHighest = 65504.0f;  // 2¹⁵ × (1 + 1023/1024)
+    static constexpr type kHighestValue = 65504.0f;  // 2¹⁵ × (1 + 1023/1024)
 
     /// Lowest finite representable value of this type.
-    static constexpr type kLowest = -65504.0f;
+    static constexpr type kLowestValue = -65504.0f;
 
     /// Smallest positive normal value of this type.
     /// binary16 0_00001_0000000000, value is 2⁻¹⁴.
-    static constexpr type kSmallest = 0x1p-14f;
+    static constexpr type kSmallestValue = 0x1p-14f;
 
     /// Smallest positive subnormal value of this type.
     /// binary16 0_00000_0000000001, value is 2⁻¹⁴ * 2⁻¹⁰ = 2⁻²⁴.
-    static constexpr type kSmallestSubnormal = 0x1p-24f;
+    static constexpr type kSmallestSubnormalValue = 0x1p-24f;
 
     /// Constructor. The value is zero-initialized.
     Number() = default;
@@ -239,10 +256,10 @@
     using T = std::conditional_t<IsFloatingPoint<UnwrapNumber<TO>> || IsFloatingPoint<FROM>,
                                  AFloat::type, AInt::type>;
     const auto value = static_cast<T>(num.value);
-    if (value > static_cast<T>(TO::kHighest)) {
+    if (value > static_cast<T>(TO::kHighestValue)) {
         return ConversionFailure::kExceedsPositiveLimit;
     }
-    if (value < static_cast<T>(TO::kLowest)) {
+    if (value < static_cast<T>(TO::kLowestValue)) {
         return ConversionFailure::kExceedsNegativeLimit;
     }
     return TO(value);  // Success
@@ -333,11 +350,11 @@
     }
 #else   // TINT_HAS_OVERFLOW_BUILTINS
     if (a.value >= 0) {
-        if (AInt::kHighest - a.value < b.value) {
+        if (AInt::kHighestValue - a.value < b.value) {
             return {};
         }
     } else {
-        if (b.value < AInt::kLowest - a.value) {
+        if (b.value < AInt::kLowestValue - a.value) {
             return {};
         }
     }
@@ -356,21 +373,21 @@
 #else   // TINT_HAS_OVERFLOW_BUILTINS
     if (a > 0) {
         if (b > 0) {
-            if (a > (AInt::kHighest / b)) {
+            if (a > (AInt::kHighestValue / b)) {
                 return {};
             }
         } else {
-            if (b < (AInt::kLowest / a)) {
+            if (b < (AInt::kLowestValue / a)) {
                 return {};
             }
         }
     } else {
         if (b > 0) {
-            if (a < (AInt::kLowest / b)) {
+            if (a < (AInt::kLowestValue / b)) {
                 return {};
             }
         } else {
-            if ((a != 0) && (b < (AInt::kHighest / a))) {
+            if ((a != 0) && (b < (AInt::kHighestValue / a))) {
                 return {};
             }
         }
diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc
index eeb31ed..16925ed 100644
--- a/src/tint/number_test.cc
+++ b/src/tint/number_test.cc
@@ -26,38 +26,19 @@
 namespace tint {
 namespace {
 
-constexpr int64_t kHighestI32 = static_cast<int64_t>(std::numeric_limits<int32_t>::max());
-constexpr int64_t kHighestU32 = static_cast<int64_t>(std::numeric_limits<uint32_t>::max());
-constexpr int64_t kLowestI32 = static_cast<int64_t>(std::numeric_limits<int32_t>::min());
-constexpr int64_t kLowestU32 = static_cast<int64_t>(std::numeric_limits<uint32_t>::min());
-
-// Highest float32 value.
-constexpr double kHighestF32 = 0x1.fffffep+127;
-
 // Next ULP up from kHighestF32 for a float64.
 constexpr double kHighestF32NextULP = 0x1.fffffe0000001p+127;
 
-// Smallest positive normal float32 value.
-constexpr double kSmallestF32 = 0x1p-126;
-
 // Highest subnormal value for a float32.
 constexpr double kHighestF32Subnormal = 0x0.fffffep-126;
 
-// Highest float16 value.
-constexpr double kHighestF16 = 0x1.ffcp+15;
-
 // Next ULP up from kHighestF16 for a float64.
 constexpr double kHighestF16NextULP = 0x1.ffc0000000001p+15;
 
-// Smallest positive normal float16 value.
-constexpr double kSmallestF16 = 0x1p-14;
-
 // Highest subnormal value for a float16.
 constexpr double kHighestF16Subnormal = 0x0.ffcp-14;
 
-constexpr double kLowestF32 = -kHighestF32;
 constexpr double kLowestF32NextULP = -kHighestF32NextULP;
-constexpr double kLowestF16 = -kHighestF16;
 constexpr double kLowestF16NextULP = -kHighestF16NextULP;
 
 // MSVC (only in release builds) can grumble about some of the inlined numerical overflow /
@@ -155,38 +136,38 @@
 }
 
 TEST(NumberTest, CheckedConvertLargestValue) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kHighestI32)), i32(kHighestI32));
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kHighestU32)), u32(kHighestU32));
-    EXPECT_EQ(CheckedConvert<u32>(i32(kHighestI32)), u32(kHighestI32));
-    EXPECT_EQ(CheckedConvert<f32>(AFloat(kHighestF32)), f32(kHighestF32));
-    EXPECT_EQ(CheckedConvert<f16>(AFloat(kHighestF16)), f16(kHighestF16));
+    EXPECT_EQ(CheckedConvert<i32>(AInt(i32::Highest())), i32::Highest());
+    EXPECT_EQ(CheckedConvert<u32>(AInt(u32::Highest())), u32::Highest());
+    EXPECT_EQ(CheckedConvert<u32>(i32::Highest()), u32(i32::Highest()));
+    EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Highest())), f32::Highest());
+    EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Highest())), f16::Highest());
 }
 
 TEST(NumberTest, CheckedConvertLowestValue) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kLowestI32)), i32(kLowestI32));
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kLowestU32)), u32(kLowestU32));
-    EXPECT_EQ(CheckedConvert<f32>(AFloat(kLowestF32)), f32(kLowestF32));
-    EXPECT_EQ(CheckedConvert<f16>(AFloat(kLowestF16)), f16(kLowestF16));
+    EXPECT_EQ(CheckedConvert<i32>(AInt(i32::Lowest())), i32::Lowest());
+    EXPECT_EQ(CheckedConvert<u32>(AInt(u32::Lowest())), u32::Lowest());
+    EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Lowest())), f32::Lowest());
+    EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Lowest())), f16::Lowest());
 }
 
 TEST(NumberTest, CheckedConvertSmallestValue) {
     EXPECT_EQ(CheckedConvert<i32>(AInt(0)), i32(0));
     EXPECT_EQ(CheckedConvert<u32>(AInt(0)), u32(0));
-    EXPECT_EQ(CheckedConvert<f32>(AFloat(kSmallestF32)), f32(kSmallestF32));
-    EXPECT_EQ(CheckedConvert<f16>(AFloat(kSmallestF16)), f16(kSmallestF16));
+    EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Smallest())), f32::Smallest());
+    EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Smallest())), f16::Smallest());
 }
 
 TEST(NumberTest, CheckedConvertExceedsPositiveLimit) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kHighestI32 + 1)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kHighestU32 + 1)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<i32>(u32(kHighestU32)), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AInt(static_cast<int64_t>(i32::Highest()) + 1)),
+              ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AInt(static_cast<uint64_t>(u32::Highest()) + 1)),
+              ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(u32::Highest()), ConversionFailure::kExceedsPositiveLimit);
     EXPECT_EQ(CheckedConvert<i32>(u32(0x80000000)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<u32>(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<i32>(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AFloat(AFloat::kHighest)),
-              ConversionFailure::kExceedsPositiveLimit);
-    EXPECT_EQ(CheckedConvert<i32>(AFloat(AFloat::kHighest)),
-              ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<u32>(f32::Highest()), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(f32::Highest()), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AFloat::Highest()), ConversionFailure::kExceedsPositiveLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AFloat::Highest()), ConversionFailure::kExceedsPositiveLimit);
     EXPECT_EQ(CheckedConvert<f32>(AFloat(kHighestF32NextULP)),
               ConversionFailure::kExceedsPositiveLimit);
     EXPECT_EQ(CheckedConvert<f16>(AFloat(kHighestF16NextULP)),
@@ -194,16 +175,16 @@
 }
 
 TEST(NumberTest, CheckedConvertExceedsNegativeLimit) {
-    EXPECT_EQ(CheckedConvert<i32>(AInt(kLowestI32 - 1)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AInt(kLowestU32 - 1)), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AInt(static_cast<int64_t>(i32::Lowest()) - 1)),
+              ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AInt(static_cast<uint64_t>(u32::Lowest()) - 1)),
+              ConversionFailure::kExceedsNegativeLimit);
     EXPECT_EQ(CheckedConvert<u32>(i32(-1)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(i32(kLowestI32)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<i32>(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<u32>(AFloat(AFloat::kLowest)),
-              ConversionFailure::kExceedsNegativeLimit);
-    EXPECT_EQ(CheckedConvert<i32>(AFloat(AFloat::kLowest)),
-              ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(i32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(f32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<i32>(f32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<u32>(AFloat::Lowest()), ConversionFailure::kExceedsNegativeLimit);
+    EXPECT_EQ(CheckedConvert<i32>(AFloat::Lowest()), ConversionFailure::kExceedsNegativeLimit);
     EXPECT_EQ(CheckedConvert<f32>(AFloat(kLowestF32NextULP)),
               ConversionFailure::kExceedsNegativeLimit);
     EXPECT_EQ(CheckedConvert<f16>(AFloat(kLowestF16NextULP)),
@@ -401,19 +382,19 @@
         {AInt(-1), AInt(-2), AInt(1)},
         {AInt(0x300), AInt(0x100), AInt(0x200)},
         {AInt(0x100), AInt(-0x100), AInt(0x200)},
-        {AInt(AInt::kHighest), AInt(1), AInt(AInt::kHighest - 1)},
-        {AInt(AInt::kLowest), AInt(-1), AInt(AInt::kLowest + 1)},
-        {AInt(AInt::kHighest), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
-        {AInt(AInt::kHighest), AInt(AInt::kHighest), AInt(0)},
-        {AInt(AInt::kLowest), AInt(AInt::kLowest), AInt(0)},
-        {OVERFLOW, AInt(1), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(-1), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(2), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(-2), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(10000), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(-10000), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(AInt::kLowest), AInt(AInt::kLowest)},
+        {AInt::Highest(), AInt(1), AInt(AInt::kHighestValue - 1)},
+        {AInt::Lowest(), AInt(-1), AInt(AInt::kLowestValue + 1)},
+        {AInt::Highest(), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
+        {AInt::Highest(), AInt::Highest(), AInt(0)},
+        {AInt::Lowest(), AInt::Lowest(), AInt(0)},
+        {OVERFLOW, AInt(1), AInt::Highest()},
+        {OVERFLOW, AInt(-1), AInt::Lowest()},
+        {OVERFLOW, AInt(2), AInt::Highest()},
+        {OVERFLOW, AInt(-2), AInt::Lowest()},
+        {OVERFLOW, AInt(10000), AInt::Highest()},
+        {OVERFLOW, AInt(-10000), AInt::Lowest()},
+        {OVERFLOW, AInt::Highest(), AInt::Highest()},
+        {OVERFLOW, AInt::Lowest(), AInt::Lowest()},
         ////////////////////////////////////////////////////////////////////////
     }));
 
@@ -452,14 +433,14 @@
         {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4)},
         {AInt(-0x8000000000000000ll), AInt(0x1000000000000000ll), AInt(-8)},
         {AInt(-0x8000000000000000ll), AInt(-0x1000000000000000ll), AInt(8)},
-        {AInt(0), AInt(AInt::kHighest), AInt(0)},
-        {AInt(0), AInt(AInt::kLowest), AInt(0)},
+        {AInt(0), AInt::Highest(), AInt(0)},
+        {AInt(0), AInt::Lowest(), AInt(0)},
         {OVERFLOW, AInt(0x1000000000000000ll), AInt(8)},
         {OVERFLOW, AInt(-0x1000000000000000ll), AInt(-8)},
         {OVERFLOW, AInt(0x800000000000000ll), AInt(0x10)},
         {OVERFLOW, AInt(0x80000000ll), AInt(0x100000000ll)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kLowest)},
+        {OVERFLOW, AInt::Highest(), AInt::Highest()},
+        {OVERFLOW, AInt::Highest(), AInt::Lowest()},
         ////////////////////////////////////////////////////////////////////////
     }));
 
@@ -489,8 +470,8 @@
         {AInt(-1), AInt(-1), AInt(1), AInt(0)},
         {AInt(2), AInt(2), AInt(1), AInt(0)},
         {AInt(-2), AInt(-2), AInt(1), AInt(0)},
-        {AInt(0), AInt(AInt::kHighest), AInt(0), AInt(0)},
-        {AInt(0), AInt(AInt::kLowest), AInt(0), AInt(0)},
+        {AInt(0), AInt::Highest(), AInt(0), AInt(0)},
+        {AInt(0), AInt::Lowest(), AInt(0), AInt(0)},
         {AInt(3), AInt(1), AInt(2), AInt(1)},
         {AInt(0x300), AInt(1), AInt(0x100), AInt(0x200)},
         {AInt(0x100), AInt(1), AInt(-0x100), AInt(0x200)},
@@ -511,27 +492,27 @@
         {AInt(-0x4000000000000000ll), AInt(0x1000000000000000ll), AInt(-4), AInt(0)},
         {AInt(-0x8000000000000000ll), AInt(0x1000000000000000ll), AInt(-8), AInt(0)},
         {AInt(-0x8000000000000000ll), AInt(-0x1000000000000000ll), AInt(8), AInt(0)},
-        {AInt(AInt::kHighest), AInt(1), AInt(1), AInt(AInt::kHighest - 1)},
-        {AInt(AInt::kLowest), AInt(1), AInt(-1), AInt(AInt::kLowest + 1)},
-        {AInt(AInt::kHighest), AInt(1), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
-        {AInt(AInt::kHighest), AInt(1), AInt(AInt::kHighest), AInt(0)},
-        {AInt(AInt::kLowest), AInt(1), AInt(AInt::kLowest), AInt(0)},
+        {AInt::Highest(), AInt(1), AInt(1), AInt(AInt::kHighestValue - 1)},
+        {AInt::Lowest(), AInt(1), AInt(-1), AInt(AInt::kLowestValue + 1)},
+        {AInt::Highest(), AInt(1), AInt(0x7fffffff00000000ll), AInt(0x00000000ffffffffll)},
+        {AInt::Highest(), AInt(1), AInt::Highest(), AInt(0)},
+        {AInt::Lowest(), AInt(1), AInt::Lowest(), AInt(0)},
         {OVERFLOW, AInt(0x1000000000000000ll), AInt(8), AInt(0)},
         {OVERFLOW, AInt(-0x1000000000000000ll), AInt(-8), AInt(0)},
         {OVERFLOW, AInt(0x800000000000000ll), AInt(0x10), AInt(0)},
         {OVERFLOW, AInt(0x80000000ll), AInt(0x100000000ll), AInt(0)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kHighest), AInt(0)},
-        {OVERFLOW, AInt(AInt::kHighest), AInt(AInt::kLowest), AInt(0)},
-        {OVERFLOW, AInt(1), AInt(1), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(-1), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(2), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(-2), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(10000), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(-10000), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(AInt::kHighest), AInt(AInt::kHighest)},
-        {OVERFLOW, AInt(1), AInt(AInt::kLowest), AInt(AInt::kLowest)},
-        {OVERFLOW, AInt(1), AInt(AInt::kHighest), AInt(1)},
-        {OVERFLOW, AInt(1), AInt(AInt::kLowest), AInt(-1)},
+        {OVERFLOW, AInt::Highest(), AInt::Highest(), AInt(0)},
+        {OVERFLOW, AInt::Highest(), AInt::Lowest(), AInt(0)},
+        {OVERFLOW, AInt(1), AInt(1), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt(-1), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt(2), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt(-2), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt(10000), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt(-10000), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt::Highest(), AInt::Highest()},
+        {OVERFLOW, AInt(1), AInt::Lowest(), AInt::Lowest()},
+        {OVERFLOW, AInt(1), AInt::Highest(), AInt(1)},
+        {OVERFLOW, AInt(1), AInt::Lowest(), AInt(-1)},
     }));
 
 TINT_END_DISABLE_WARNING(CONSTANT_OVERFLOW);
diff --git a/src/tint/reader/wgsl/lexer.cc b/src/tint/reader/wgsl/lexer.cc
index c9056e0..778cb3f 100644
--- a/src/tint/reader/wgsl/lexer.cc
+++ b/src/tint/reader/wgsl/lexer.cc
@@ -706,8 +706,8 @@
 
     if (has_f_suffix) {
         // Check value fits in f32
-        if (result_f64 < static_cast<double>(f32::kLowest) ||
-            result_f64 > static_cast<double>(f32::kHighest)) {
+        if (result_f64 < static_cast<double>(f32::kLowestValue) ||
+            result_f64 > static_cast<double>(f32::kHighestValue)) {
             return {Token::Type::kError, source, "value cannot be represented as 'f32'"};
         }
         // Check the value can be exactly represented, i.e. only high 23 mantissa bits are valid for
@@ -715,13 +715,14 @@
         // 0.
         int valid_mantissa_bits = 0;
         double abs_result_f64 = std::fabs(result_f64);
-        if (abs_result_f64 >= static_cast<double>(f32::kSmallest)) {
+        if (abs_result_f64 >= static_cast<double>(f32::kSmallestValue)) {
             // The result shall be a normal f32 value.
             valid_mantissa_bits = 23;
-        } else if (abs_result_f64 >= static_cast<double>(f32::kSmallestSubnormal)) {
+        } else if (abs_result_f64 >= static_cast<double>(f32::kSmallestSubnormalValue)) {
             // The result shall be a subnormal f32 value, represented as double.
-            // The smallest positive normal f32 is f32::kSmallest = 2^-126 = 0x1.0p-126, and the
-            //   smallest positive subnormal f32 is f32::kSmallestSubnormal = 2^-149. Thus, the
+            // The smallest positive normal f32 is f32::kSmallestValue = 2^-126 = 0x1.0p-126, and
+            // the
+            //   smallest positive subnormal f32 is f32::kSmallestSubnormalValue = 2^-149. Thus, the
             //   value v in range 2^-126 > v >= 2^-149 must be represented as a subnormal f32
             //   number, but is still normal double (f64) number, and has a exponent in range -127
             //   to -149, inclusive.
@@ -758,8 +759,8 @@
         return {Token::Type::kFloatLiteral_F, source, result_f64};
     } else if (has_h_suffix) {
         // Check value fits in f16
-        if (result_f64 < static_cast<double>(f16::kLowest) ||
-            result_f64 > static_cast<double>(f16::kHighest)) {
+        if (result_f64 < static_cast<double>(f16::kLowestValue) ||
+            result_f64 > static_cast<double>(f16::kHighestValue)) {
             return {Token::Type::kError, source, "value cannot be represented as 'f16'"};
         }
         // Check the value can be exactly represented, i.e. only high 10 mantissa bits are valid for
@@ -767,15 +768,15 @@
         // 0.
         int valid_mantissa_bits = 0;
         double abs_result_f64 = std::fabs(result_f64);
-        if (abs_result_f64 >= static_cast<double>(f16::kSmallest)) {
+        if (abs_result_f64 >= static_cast<double>(f16::kSmallestValue)) {
             // The result shall be a normal f16 value.
             valid_mantissa_bits = 10;
-        } else if (abs_result_f64 >= static_cast<double>(f16::kSmallestSubnormal)) {
+        } else if (abs_result_f64 >= static_cast<double>(f16::kSmallestSubnormalValue)) {
             // The result shall be a subnormal f16 value, represented as double.
-            // The smallest positive normal f16 is f16::kSmallest = 2^-14 = 0x1.0p-14, and the
-            //   smallest positive subnormal f16 is f16::kSmallestSubnormal = 2^-24. Thus, the value
-            //   v in range 2^-14 > v >= 2^-24 must be represented as a subnormal f16 number, but
-            //   is still normal double (f64) number, and has a exponent in range -15 to -24,
+            // The smallest positive normal f16 is f16::kSmallestValue = 2^-14 = 0x1.0p-14, and the
+            //   smallest positive subnormal f16 is f16::kSmallestSubnormalValue = 2^-24. Thus, the
+            //   value v in range 2^-14 > v >= 2^-24 must be represented as a subnormal f16 number,
+            //   but is still normal double (f64) number, and has a exponent in range -15 to -24,
             //   inclusive.
             // A value v, if 2^-14 > v >= 2^-15, its binary16 representation will have binary form
             //   s_00000_1xxxxxxxxx, having mantissa of 1 leading 1 bit and 9 arbitrary bits. Since
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index ba70b33..dec4992 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -209,21 +209,20 @@
             } else if constexpr (IsFloatingPoint<UnwrapNumber<TO>>) {
                 // [x -> floating-point] - number not exactly representable
                 // https://www.w3.org/TR/WGSL/#floating-point-conversion
-                constexpr auto kInf = std::numeric_limits<double>::infinity();
                 switch (conv.Failure()) {
                     case ConversionFailure::kExceedsNegativeLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(-kInf));
+                        return builder.create<Element<TO>>(target_ty, -TO::Inf());
                     case ConversionFailure::kExceedsPositiveLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(kInf));
+                        return builder.create<Element<TO>>(target_ty, TO::Inf());
                 }
             } else {
                 // [x -> integer] - number not exactly representable
                 // https://www.w3.org/TR/WGSL/#floating-point-conversion
                 switch (conv.Failure()) {
                     case ConversionFailure::kExceedsNegativeLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(TO::kLowest));
+                        return builder.create<Element<TO>>(target_ty, TO::Lowest());
                     case ConversionFailure::kExceedsPositiveLimit:
-                        return builder.create<Element<TO>>(target_ty, TO(TO::kHighest));
+                        return builder.create<Element<TO>>(target_ty, TO::Highest());
                 }
             }
             return nullptr;  // Expression is not constant.
diff --git a/src/tint/resolver/const_eval_test.cc b/src/tint/resolver/const_eval_test.cc
index 676bda2..3a6c971 100644
--- a/src/tint/resolver/const_eval_test.cc
+++ b/src/tint/resolver/const_eval_test.cc
@@ -30,18 +30,6 @@
 namespace {
 
 template <typename T>
-const auto kHighest = T(T::kHighest);
-
-template <typename T>
-const auto kLowest = T(T::kLowest);
-
-template <typename T>
-const auto kNaN = T(std::numeric_limits<UnwrapNumber<T>>::quiet_NaN());
-
-template <typename T>
-const auto kInf = T(std::numeric_limits<UnwrapNumber<T>>::infinity());
-
-template <typename T>
 const auto kPi = T(UnwrapNumber<T>(3.14159265358979323846));
 
 template <typename T>
@@ -1336,17 +1324,17 @@
     EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), i32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), i32::Highest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(1)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(1)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), i32::kLowest);
+    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), i32::Lowest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), i32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), i32::Highest());
 }
 
 TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_u32) {
@@ -1369,17 +1357,17 @@
     EXPECT_TRUE(sem->ConstantValue()->Index(0)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(0)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), u32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(0)->As<AInt>(), u32::Highest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllEqual());
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AnyZero());
     EXPECT_TRUE(sem->ConstantValue()->Index(1)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), u32::kLowest);
+    EXPECT_EQ(sem->ConstantValue()->Index(1)->As<AInt>(), u32::Lowest());
 
     EXPECT_TRUE(sem->ConstantValue()->Index(2)->AllEqual());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AnyZero());
     EXPECT_FALSE(sem->ConstantValue()->Index(2)->AllZero());
-    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), u32::kHighest);
+    EXPECT_EQ(sem->ConstantValue()->Index(2)->As<AInt>(), u32::Highest());
 }
 
 TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_f16) {
@@ -3071,46 +3059,46 @@
                                               C(-0_a, 0_a),
                                               C(1_a, -1_a),
                                               C(-1_a, 1_a),
-                                              C(kHighest<AInt>, -kHighest<AInt>),
-                                              C(-kHighest<AInt>, kHighest<AInt>),
-                                              C(kLowest<AInt>, Negate(kLowest<AInt>)),
-                                              C(Negate(kLowest<AInt>), kLowest<AInt>),
+                                              C(AInt::Highest(), -AInt::Highest()),
+                                              C(-AInt::Highest(), AInt::Highest()),
+                                              C(AInt::Lowest(), Negate(AInt::Lowest())),
+                                              C(Negate(AInt::Lowest()), AInt::Lowest()),
                                               // i32
                                               C(0_i, -0_i),
                                               C(-0_i, 0_i),
                                               C(1_i, -1_i),
                                               C(-1_i, 1_i),
-                                              C(kHighest<i32>, -kHighest<i32>),
-                                              C(-kHighest<i32>, kHighest<i32>),
-                                              C(kLowest<i32>, Negate(kLowest<i32>)),
-                                              C(Negate(kLowest<i32>), kLowest<i32>),
+                                              C(i32::Highest(), -i32::Highest()),
+                                              C(-i32::Highest(), i32::Highest()),
+                                              C(i32::Lowest(), Negate(i32::Lowest())),
+                                              C(Negate(i32::Lowest()), i32::Lowest()),
                                               // AFloat
                                               C(0.0_a, -0.0_a),
                                               C(-0.0_a, 0.0_a),
                                               C(1.0_a, -1.0_a),
                                               C(-1.0_a, 1.0_a),
-                                              C(kHighest<AFloat>, -kHighest<AFloat>),
-                                              C(-kHighest<AFloat>, kHighest<AFloat>),
-                                              C(kLowest<AFloat>, Negate(kLowest<AFloat>)),
-                                              C(Negate(kLowest<AFloat>), kLowest<AFloat>),
+                                              C(AFloat::Highest(), -AFloat::Highest()),
+                                              C(-AFloat::Highest(), AFloat::Highest()),
+                                              C(AFloat::Lowest(), Negate(AFloat::Lowest())),
+                                              C(Negate(AFloat::Lowest()), AFloat::Lowest()),
                                               // f32
                                               C(0.0_f, -0.0_f),
                                               C(-0.0_f, 0.0_f),
                                               C(1.0_f, -1.0_f),
                                               C(-1.0_f, 1.0_f),
-                                              C(kHighest<f32>, -kHighest<f32>),
-                                              C(-kHighest<f32>, kHighest<f32>),
-                                              C(kLowest<f32>, Negate(kLowest<f32>)),
-                                              C(Negate(kLowest<f32>), kLowest<f32>),
+                                              C(f32::Highest(), -f32::Highest()),
+                                              C(-f32::Highest(), f32::Highest()),
+                                              C(f32::Lowest(), Negate(f32::Lowest())),
+                                              C(Negate(f32::Lowest()), f32::Lowest()),
                                               // f16
                                               C(0.0_h, -0.0_h),
                                               C(-0.0_h, 0.0_h),
                                               C(1.0_h, -1.0_h),
                                               C(-1.0_h, 1.0_h),
-                                              C(kHighest<f16>, -kHighest<f16>),
-                                              C(-kHighest<f16>, kHighest<f16>),
-                                              C(kLowest<f16>, Negate(kLowest<f16>)),
-                                              C(Negate(kLowest<f16>), kLowest<f16>),
+                                              C(f16::Highest(), -f16::Highest()),
+                                              C(-f16::Highest(), f16::Highest()),
+                                              C(f16::Lowest(), Negate(f16::Lowest())),
+                                              C(Negate(f16::Lowest()), f16::Lowest()),
                                           })));
 
 // Make sure UBSan doesn't trip on C++'s undefined behaviour of negating the smallest negative
@@ -3222,33 +3210,33 @@
     if constexpr (!finite_only) {
         std::vector<Case> non_finite_cases = {
             // If y is +/-INF and x is finite, +/-PI/2 is returned
-            C({kInf<T>, T(0.0)}, kPiOver2<T>, true),
-            C({-kInf<T>, T(0.0)}, kPiOver2<T>, true),
+            C({T::Inf(), T(0.0)}, kPiOver2<T>, true),
+            C({-T::Inf(), T(0.0)}, kPiOver2<T>, true),
 
             // If y is +/-INF and x is -INF, +/-3PI/4 is returned
-            C({kInf<T>, -kInf<T>}, k3PiOver4<T>, true),
-            C({-kInf<T>, -kInf<T>}, k3PiOver4<T>, true),
+            C({T::Inf(), -T::Inf()}, k3PiOver4<T>, true),
+            C({-T::Inf(), -T::Inf()}, k3PiOver4<T>, true),
 
             // If y is +/-INF and x is +INF, +/-PI/4 is returned
-            C({kInf<T>, kInf<T>}, kPiOver4<T>, true),
-            C({-kInf<T>, kInf<T>}, kPiOver4<T>, true),
+            C({T::Inf(), T::Inf()}, kPiOver4<T>, true),
+            C({-T::Inf(), T::Inf()}, kPiOver4<T>, true),
 
             // If x is -INF and y is finite and positive, +PI is returned
-            C({T(0.0), -kInf<T>}, kPi<T>),
+            C({T(0.0), -T::Inf()}, kPi<T>),
 
             // If x is -INF and y is finite and negative, -PI is returned
-            C({-T(0.0), -kInf<T>}, -kPi<T>),
+            C({-T(0.0), -T::Inf()}, -kPi<T>),
 
             // If x is +INF and y is finite and positive, +0 is returned
-            C({T(0.0), kInf<T>}, T(0.0)),
+            C({T(0.0), T::Inf()}, T(0.0)),
 
             // If x is +INF and y is finite and negative, -0 is returned
-            C({-T(0.0), kInf<T>}, -T(0.0)),
+            C({-T(0.0), T::Inf()}, -T(0.0)),
 
             // If either x is NaN or y is NaN, NaN is returned
-            C({kNaN<T>, T(0.0)}, kNaN<T>),
-            C({T(0.0), kNaN<T>}, kNaN<T>),
-            C({kNaN<T>, kNaN<T>}, kNaN<T>),
+            C({T::NaN(), T(0.0)}, T::NaN()),
+            C({T(0.0), T::NaN()}, T::NaN()),
+            C({T::NaN(), T::NaN()}, T::NaN()),
         };
 
         cases = Concat(cases, non_finite_cases);
@@ -3269,14 +3257,14 @@
 std::vector<Case> ClampCases() {
     return {
         C({T(0), T(0), T(0)}, T(0)),
-        C({T(0), T(42), kHighest<T>}, T(42)),
-        C({kLowest<T>, T(0), T(42)}, T(0)),
-        C({T(0), kLowest<T>, kHighest<T>}, T(0)),
-        C({T(0), kHighest<T>, kLowest<T>}, kLowest<T>),
-        C({kHighest<T>, kHighest<T>, kHighest<T>}, kHighest<T>),
-        C({kLowest<T>, kLowest<T>, kLowest<T>}, kLowest<T>),
-        C({kHighest<T>, kLowest<T>, kHighest<T>}, kHighest<T>),
-        C({kLowest<T>, kLowest<T>, kHighest<T>}, kLowest<T>),
+        C({T(0), T(42), T::Highest()}, T(42)),
+        C({T::Lowest(), T(0), T(42)}, T(0)),
+        C({T(0), T::Lowest(), T::Highest()}, T(0)),
+        C({T(0), T::Highest(), T::Lowest()}, T::Lowest()),
+        C({T::Highest(), T::Highest(), T::Highest()}, T::Highest()),
+        C({T::Lowest(), T::Lowest(), T::Lowest()}, T::Lowest()),
+        C({T::Highest(), T::Lowest(), T::Highest()}, T::Highest()),
+        C({T::Lowest(), T::Lowest(), T::Highest()}, T::Lowest()),
     };
 }
 
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 56492b0..bd363c1 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -35,14 +35,6 @@
 using f32M = builder::mat<3, 2, f32>;
 using i32Varr = builder::array<3, i32>;
 
-constexpr double kHighestU32 = static_cast<double>(u32::kHighest);
-constexpr double kLowestU32 = static_cast<double>(u32::kLowest);
-constexpr double kHighestI32 = static_cast<double>(i32::kHighest);
-constexpr double kLowestI32 = static_cast<double>(i32::kLowest);
-constexpr double kHighestF32 = static_cast<double>(f32::kHighest);
-constexpr double kLowestF32 = static_cast<double>(f32::kLowest);
-// constexpr double kHighestF16 = static_cast<double>(f16::kHighest);
-// constexpr double kLowestF16 = static_cast<double>(f16::kLowest);
 constexpr double kTooBigF32 = static_cast<double>(3.5e+38);
 // constexpr double kTooBigF16 = static_cast<double>(6.6e+4);
 constexpr double kPiF64 = 3.141592653589793;
@@ -460,142 +452,148 @@
 INSTANTIATE_TEST_SUITE_P(
     MaterializeScalar,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kScalarMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32, AInt>(0_a, 0.0),                                        //
-                         Types<i32, AInt>(1_a, 1.0),                                        //
-                         Types<i32, AInt>(-1_a, -1.0),                                      //
-                         Types<i32, AInt>(AInt(kHighestI32), kHighestI32),                  //
-                         Types<i32, AInt>(AInt(kLowestI32), kLowestI32),                    //
-                         Types<u32, AInt>(0_a, 0.0),                                        //
-                         Types<u32, AInt>(1_a, 1.0),                                        //
-                         Types<u32, AInt>(AInt(kHighestU32), kHighestU32),                  //
-                         Types<u32, AInt>(AInt(kLowestU32), kLowestU32),                    //
-                         Types<f32, AFloat>(0.0_a, 0.0),                                    //
-                         Types<f32, AFloat>(AFloat(kHighestF32), kHighestF32),              //
-                         Types<f32, AFloat>(AFloat(kLowestF32), kLowestF32),                //
-                         Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                        //
-                         Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),          //
-                         Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),        //
-                         /* Types<f16, AFloat>(0.0_a, 0.0),                             */  //
-                         /* Types<f16, AFloat>(1.0_a, 1.0),                             */  //
-                         /* Types<f16, AFloat>(AFloat(kHighestF16), kHighestF16),       */  //
-                         /* Types<f16, AFloat>(AFloat(kLowestF16), kLowestF16),         */  //
-                         /* Types<f16, AFloat>(AFloat(kPiF16), kPiF64),                 */  //
-                         /* Types<f16, AFloat>(AFloat(kSubnormalF16), kSubnormalF16),   */  //
-                         /* Types<f16, AFloat>(AFloat(-kSubnormalF16), -kSubnormalF16), */  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kScalarMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32, AInt>(0_a, 0.0),                                                       //
+            Types<i32, AInt>(1_a, 1.0),                                                       //
+            Types<i32, AInt>(-1_a, -1.0),                                                     //
+            Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<u32, AInt>(0_a, 0.0),                                                       //
+            Types<u32, AInt>(1_a, 1.0),                                                       //
+            Types<u32, AInt>(AInt(u32::Highest()), u32::Highest()),                           //
+            Types<u32, AInt>(AInt(u32::Lowest()), u32::Lowest()),                             //
+            Types<f32, AFloat>(0.0_a, 0.0),                                                   //
+            Types<f32, AFloat>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32, AFloat>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+            /* Types<f16, AFloat>(0.0_a, 0.0),                             */                 //
+            /* Types<f16, AFloat>(1.0_a, 1.0),                             */                 //
+            /* Types<f16, AFloat>(AFloat(kHighestF16), kHighestF16),       */                 //
+            /* Types<f16, AFloat>(AFloat(kLowestF16), kLowestF16),         */                 //
+            /* Types<f16, AFloat>(AFloat(kPiF16), kPiF64),                 */                 //
+            /* Types<f16, AFloat>(AFloat(kSubnormalF16), kSubnormalF16),   */                 //
+            /* Types<f16, AFloat>(AFloat(-kSubnormalF16), -kSubnormalF16), */                 //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeVector,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kVectorMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32V, AIntV>(0_a, 0.0),                                        //
-                         Types<i32V, AIntV>(1_a, 1.0),                                        //
-                         Types<i32V, AIntV>(-1_a, -1.0),                                      //
-                         Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32),                  //
-                         Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32),                    //
-                         Types<u32V, AIntV>(0_a, 0.0),                                        //
-                         Types<u32V, AIntV>(1_a, 1.0),                                        //
-                         Types<u32V, AIntV>(AInt(kHighestU32), kHighestU32),                  //
-                         Types<u32V, AIntV>(AInt(kLowestU32), kLowestU32),                    //
-                         Types<f32V, AFloatV>(0.0_a, 0.0),                                    //
-                         Types<f32V, AFloatV>(1.0_a, 1.0),                                    //
-                         Types<f32V, AFloatV>(-1.0_a, -1.0),                                  //
-                         Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32),              //
-                         Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32),                //
-                         Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                        //
-                         Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),          //
-                         Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),        //
-                         /* Types<f16V, AFloatV>(0.0_a, 0.0),                             */  //
-                         /* Types<f16V, AFloatV>(1.0_a, 1.0),                             */  //
-                         /* Types<f16V, AFloatV>(-1.0_a, -1.0),                           */  //
-                         /* Types<f16V, AFloatV>(AFloat(kHighestF16), kHighestF16),       */  //
-                         /* Types<f16V, AFloatV>(AFloat(kLowestF16), kLowestF16),         */  //
-                         /* Types<f16V, AFloatV>(AFloat(kPiF16), kPiF64),                 */  //
-                         /* Types<f16V, AFloatV>(AFloat(kSubnormalF16), kSubnormalF16),   */  //
-                         /* Types<f16V, AFloatV>(AFloat(-kSubnormalF16), -kSubnormalF16), */  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kVectorMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32V, AIntV>(0_a, 0.0),                                                       //
+            Types<i32V, AIntV>(1_a, 1.0),                                                       //
+            Types<i32V, AIntV>(-1_a, -1.0),                                                     //
+            Types<i32V, AIntV>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32V, AIntV>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<u32V, AIntV>(0_a, 0.0),                                                       //
+            Types<u32V, AIntV>(1_a, 1.0),                                                       //
+            Types<u32V, AIntV>(AInt(u32::Highest()), u32::Highest()),                           //
+            Types<u32V, AIntV>(AInt(u32::Lowest()), u32::Lowest()),                             //
+            Types<f32V, AFloatV>(0.0_a, 0.0),                                                   //
+            Types<f32V, AFloatV>(1.0_a, 1.0),                                                   //
+            Types<f32V, AFloatV>(-1.0_a, -1.0),                                                 //
+            Types<f32V, AFloatV>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32V, AFloatV>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+            /* Types<f16V, AFloatV>(0.0_a, 0.0),                             */                 //
+            /* Types<f16V, AFloatV>(1.0_a, 1.0),                             */                 //
+            /* Types<f16V, AFloatV>(-1.0_a, -1.0),                           */                 //
+            /* Types<f16V, AFloatV>(AFloat(kHighestF16), kHighestF16),       */                 //
+            /* Types<f16V, AFloatV>(AFloat(kLowestF16), kLowestF16),         */                 //
+            /* Types<f16V, AFloatV>(AFloat(kPiF16), kPiF64),                 */                 //
+            /* Types<f16V, AFloatV>(AFloat(kSubnormalF16), kSubnormalF16),   */                 //
+            /* Types<f16V, AFloatV>(AFloat(-kSubnormalF16), -kSubnormalF16), */                 //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeVectorRuntimeIndex,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::Values(Method::kRuntimeIndex),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32V, AIntV>(0_a, 0.0),                                  //
-                         Types<i32V, AIntV>(1_a, 1.0),                                  //
-                         Types<i32V, AIntV>(-1_a, -1.0),                                //
-                         Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32),            //
-                         Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32),              //
-                         Types<f32V, AFloatV>(0.0_a, 0.0),                              //
-                         Types<f32V, AFloatV>(1.0_a, 1.0),                              //
-                         Types<f32V, AFloatV>(-1.0_a, -1.0),                            //
-                         Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::Values(Method::kRuntimeIndex),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32V, AIntV>(0_a, 0.0),                                                       //
+            Types<i32V, AIntV>(1_a, 1.0),                                                       //
+            Types<i32V, AIntV>(-1_a, -1.0),                                                     //
+            Types<i32V, AIntV>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32V, AIntV>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<f32V, AFloatV>(0.0_a, 0.0),                                                   //
+            Types<f32V, AFloatV>(1.0_a, 1.0),                                                   //
+            Types<f32V, AFloatV>(-1.0_a, -1.0),                                                 //
+            Types<f32V, AFloatV>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32V, AFloatV>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeMatrix,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kMatrixMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<f32M, AFloatM>(0.0_a, 0.0),                                    //
-                         Types<f32M, AFloatM>(1.0_a, 1.0),                                    //
-                         Types<f32M, AFloatM>(-1.0_a, -1.0),                                  //
-                         Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32),              //
-                         Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32),                //
-                         Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                        //
-                         Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),          //
-                         Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),        //
-                         /* Types<f16M, AFloatM>(0.0_a, 0.0),                             */  //
-                         /* Types<f16M, AFloatM>(1.0_a, 1.0),                             */  //
-                         /* Types<f16M, AFloatM>(-1.0_a, -1.0),                           */  //
-                         /* Types<f16M, AFloatM>(AFloat(kHighestF16), kHighestF16),       */  //
-                         /* Types<f16M, AFloatM>(AFloat(kLowestF16), kLowestF16),         */  //
-                         /* Types<f16M, AFloatM>(AFloat(kPiF16), kPiF64),                 */  //
-                         /* Types<f16M, AFloatM>(AFloat(kSubnormalF16), kSubnormalF16),   */  //
-                         /* Types<f16M, AFloatM>(AFloat(-kSubnormalF16), -kSubnormalF16), */  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kMatrixMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<f32M, AFloatM>(0.0_a, 0.0),                                                   //
+            Types<f32M, AFloatM>(1.0_a, 1.0),                                                   //
+            Types<f32M, AFloatM>(-1.0_a, -1.0),                                                 //
+            Types<f32M, AFloatM>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32M, AFloatM>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+            /* Types<f16M, AFloatM>(0.0_a, 0.0),                             */                 //
+            /* Types<f16M, AFloatM>(1.0_a, 1.0),                             */                 //
+            /* Types<f16M, AFloatM>(-1.0_a, -1.0),                           */                 //
+            /* Types<f16M, AFloatM>(AFloat(kHighestF16), kHighestF16),       */                 //
+            /* Types<f16M, AFloatM>(AFloat(kLowestF16), kLowestF16),         */                 //
+            /* Types<f16M, AFloatM>(AFloat(kPiF16), kPiF64),                 */                 //
+            /* Types<f16M, AFloatM>(AFloat(kSubnormalF16), kSubnormalF16),   */                 //
+            /* Types<f16M, AFloatM>(AFloat(-kSubnormalF16), -kSubnormalF16), */                 //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeMatrixRuntimeIndex,
     MaterializeAbstractNumericToConcreteType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::Values(Method::kRuntimeIndex),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<f32M, AFloatM>(0.0_a, 0.0),                              //
-                         Types<f32M, AFloatM>(1.0_a, 1.0),                              //
-                         Types<f32M, AFloatM>(-1.0_a, -1.0),                            //
-                         Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::Values(Method::kRuntimeIndex),
+        testing::ValuesIn(std::vector<Data>{
+            Types<f32M, AFloatM>(0.0_a, 0.0),                                                   //
+            Types<f32M, AFloatM>(1.0_a, 1.0),                                                   //
+            Types<f32M, AFloatM>(-1.0_a, -1.0),                                                 //
+            Types<f32M, AFloatM>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32M, AFloatM>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
-INSTANTIATE_TEST_SUITE_P(MaterializeSwitch,
-                         MaterializeAbstractNumericToConcreteType,
-                         testing::Combine(testing::Values(Expectation::kMaterialize),
-                                          testing::ValuesIn(kSwitchMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, 0.0),                        //
-                                              Types<i32, AInt>(1_a, 1.0),                        //
-                                              Types<i32, AInt>(-1_a, -1.0),                      //
-                                              Types<i32, AInt>(AInt(kHighestI32), kHighestI32),  //
-                                              Types<i32, AInt>(AInt(kLowestI32), kLowestI32),    //
-                                              Types<u32, AInt>(0_a, 0.0),                        //
-                                              Types<u32, AInt>(1_a, 1.0),                        //
-                                              Types<u32, AInt>(AInt(kHighestU32), kHighestU32),  //
-                                              Types<u32, AInt>(AInt(kLowestU32), kLowestU32),    //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    MaterializeSwitch,
+    MaterializeAbstractNumericToConcreteType,
+    testing::Combine(testing::Values(Expectation::kMaterialize),
+                     testing::ValuesIn(kSwitchMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, 0.0),                              //
+                         Types<i32, AInt>(1_a, 1.0),                              //
+                         Types<i32, AInt>(-1_a, -1.0),                            //
+                         Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),  //
+                         Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),    //
+                         Types<u32, AInt>(0_a, 0.0),                              //
+                         Types<u32, AInt>(1_a, 1.0),                              //
+                         Types<u32, AInt>(AInt(u32::Highest()), u32::Highest()),  //
+                         Types<u32, AInt>(AInt(u32::Lowest()), u32::Lowest()),    //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize,
                          MaterializeAbstractNumericToConcreteType,
@@ -637,35 +635,37 @@
                                               Types<i32Varr, AFloatV>(),  //
                                           })));
 
-INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented,
-                         MaterializeAbstractNumericToConcreteType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kScalarMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),        //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),         //
-                                              Types<u32, AInt>(0_a, kHighestU32 + 1),        //
-                                              Types<u32, AInt>(0_a, kLowestU32 - 1),         //
-                                              Types<f32, AFloat>(0.0_a, kTooBigF32),         //
-                                              Types<f32, AFloat>(0.0_a, -kTooBigF32),        //
-                                              /* Types<f16, AFloat>(0.0_a, kTooBigF16),  */  //
-                                              /* Types<f16, AFloat>(0.0_a, -kTooBigF16), */  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    ScalarValueCannotBeRepresented,
+    MaterializeAbstractNumericToConcreteType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kScalarMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<u32, AInt>(0_a, static_cast<double>(u32::kHighestValue) + 1),  //
+                         Types<u32, AInt>(0_a, static_cast<double>(u32::kLowestValue) - 1),   //
+                         Types<f32, AFloat>(0.0_a, kTooBigF32),                               //
+                         Types<f32, AFloat>(0.0_a, -kTooBigF32),                              //
+                         /* Types<f16, AFloat>(0.0_a, kTooBigF16),  */                        //
+                         /* Types<f16, AFloat>(0.0_a, -kTooBigF16), */                        //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented,
-                         MaterializeAbstractNumericToConcreteType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kVectorMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32V, AIntV>(0_a, kHighestI32 + 1),        //
-                                              Types<i32V, AIntV>(0_a, kLowestI32 - 1),         //
-                                              Types<u32V, AIntV>(0_a, kHighestU32 + 1),        //
-                                              Types<u32V, AIntV>(0_a, kLowestU32 - 1),         //
-                                              Types<f32V, AFloatV>(0.0_a, kTooBigF32),         //
-                                              Types<f32V, AFloatV>(0.0_a, -kTooBigF32),        //
-                                              /* Types<f16V, AFloatV>(0.0_a, kTooBigF16),  */  //
-                                              /* Types<f16V, AFloatV>(0.0_a, -kTooBigF16), */  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    VectorValueCannotBeRepresented,
+    MaterializeAbstractNumericToConcreteType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kVectorMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<u32V, AIntV>(0_a, static_cast<double>(u32::kHighestValue) + 1),  //
+                         Types<u32V, AIntV>(0_a, static_cast<double>(u32::kLowestValue) - 1),   //
+                         Types<f32V, AFloatV>(0.0_a, kTooBigF32),                               //
+                         Types<f32V, AFloatV>(0.0_a, -kTooBigF32),                              //
+                         /* Types<f16V, AFloatV>(0.0_a, kTooBigF16),  */                        //
+                         /* Types<f16V, AFloatV>(0.0_a, -kTooBigF16), */                        //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented,
                          MaterializeAbstractNumericToConcreteType,
@@ -898,69 +898,73 @@
 INSTANTIATE_TEST_SUITE_P(
     MaterializeScalar,
     MaterializeAbstractNumericToDefaultType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kScalarMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32, AInt>(0_a, 0.0),                                  //
-                         Types<i32, AInt>(1_a, 1.0),                                  //
-                         Types<i32, AInt>(-1_a, -1.0),                                //
-                         Types<i32, AInt>(AInt(kHighestI32), kHighestI32),            //
-                         Types<i32, AInt>(AInt(kLowestI32), kLowestI32),              //
-                         Types<f32, AFloat>(0.0_a, 0.0),                              //
-                         Types<f32, AFloat>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32, AFloat>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kScalarMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32, AInt>(0_a, 0.0),                                                       //
+            Types<i32, AInt>(1_a, 1.0),                                                       //
+            Types<i32, AInt>(-1_a, -1.0),                                                     //
+            Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<f32, AFloat>(0.0_a, 0.0),                                                   //
+            Types<f32, AFloat>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32, AFloat>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32, AFloat>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32, AFloat>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32, AFloat>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeVector,
     MaterializeAbstractNumericToDefaultType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kVectorMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<i32V, AIntV>(0_a, 0.0),                                  //
-                         Types<i32V, AIntV>(1_a, 1.0),                                  //
-                         Types<i32V, AIntV>(-1_a, -1.0),                                //
-                         Types<i32V, AIntV>(AInt(kHighestI32), kHighestI32),            //
-                         Types<i32V, AIntV>(AInt(kLowestI32), kLowestI32),              //
-                         Types<f32V, AFloatV>(0.0_a, 0.0),                              //
-                         Types<f32V, AFloatV>(1.0_a, 1.0),                              //
-                         Types<f32V, AFloatV>(-1.0_a, -1.0),                            //
-                         Types<f32V, AFloatV>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32V, AFloatV>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kVectorMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<i32V, AIntV>(0_a, 0.0),                                                       //
+            Types<i32V, AIntV>(1_a, 1.0),                                                       //
+            Types<i32V, AIntV>(-1_a, -1.0),                                                     //
+            Types<i32V, AIntV>(AInt(i32::Highest()), i32::Highest()),                           //
+            Types<i32V, AIntV>(AInt(i32::Lowest()), i32::Lowest()),                             //
+            Types<f32V, AFloatV>(0.0_a, 0.0),                                                   //
+            Types<f32V, AFloatV>(1.0_a, 1.0),                                                   //
+            Types<f32V, AFloatV>(-1.0_a, -1.0),                                                 //
+            Types<f32V, AFloatV>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32V, AFloatV>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32V, AFloatV>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32V, AFloatV>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32V, AFloatV>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeMatrix,
     MaterializeAbstractNumericToDefaultType,
-    testing::Combine(testing::Values(Expectation::kMaterialize),
-                     testing::ValuesIn(kMatrixMethods),
-                     testing::ValuesIn(std::vector<Data>{
-                         Types<f32M, AFloatM>(0.0_a, 0.0),                              //
-                         Types<f32M, AFloatM>(1.0_a, 1.0),                              //
-                         Types<f32M, AFloatM>(-1.0_a, -1.0),                            //
-                         Types<f32M, AFloatM>(AFloat(kHighestF32), kHighestF32),        //
-                         Types<f32M, AFloatM>(AFloat(kLowestF32), kLowestF32),          //
-                         Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                  //
-                         Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),    //
-                         Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),  //
-                     })));
+    testing::Combine(
+        testing::Values(Expectation::kMaterialize),
+        testing::ValuesIn(kMatrixMethods),
+        testing::ValuesIn(std::vector<Data>{
+            Types<f32M, AFloatM>(0.0_a, 0.0),                                                   //
+            Types<f32M, AFloatM>(1.0_a, 1.0),                                                   //
+            Types<f32M, AFloatM>(-1.0_a, -1.0),                                                 //
+            Types<f32M, AFloatM>(AFloat(f32::Highest()), static_cast<double>(f32::Highest())),  //
+            Types<f32M, AFloatM>(AFloat(f32::Lowest()), static_cast<double>(f32::Lowest())),    //
+            Types<f32M, AFloatM>(AFloat(kPiF32), kPiF64),                                       //
+            Types<f32M, AFloatM>(AFloat(kSubnormalF32), kSubnormalF32),                         //
+            Types<f32M, AFloatM>(AFloat(-kSubnormalF32), -kSubnormalF32),                       //
+        })));
 
-INSTANTIATE_TEST_SUITE_P(MaterializeAInt,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kMaterialize),
-                                          testing::ValuesIn(kAIntMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, 0.0),                        //
-                                              Types<i32, AInt>(10_a, 10.0),                      //
-                                              Types<i32, AInt>(AInt(kHighestI32), kHighestI32),  //
-                                              Types<i32, AInt>(AInt(kLowestI32), kLowestI32),    //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    MaterializeAInt,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kMaterialize),
+                     testing::ValuesIn(kAIntMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, 0.0),                              //
+                         Types<i32, AInt>(10_a, 10.0),                            //
+                         Types<i32, AInt>(AInt(i32::Highest()), i32::Highest()),  //
+                         Types<i32, AInt>(AInt(i32::Lowest()), i32::Lowest()),    //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(
     MaterializeArrayLength,
@@ -971,7 +975,7 @@
                          Types<i32, AInt>(1_a, 1.0),        //
                          Types<i32, AInt>(10_a, 10.0),      //
                          Types<i32, AInt>(1000_a, 1000.0),  //
-                         // Note: kHighestI32 cannot be used due to max-byte-size validation
+                         // Note: i32::Highest() cannot be used due to max-byte-size validation
                      })));
 
 INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize,
@@ -984,28 +988,30 @@
                                               Types<i32, AInt>(65535_a, 65535.0),  //
                                           })));
 
-INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kScalarMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),   //
-                                              Types<f32, AFloat>(0.0_a, kTooBigF32),   //
-                                              Types<f32, AFloat>(0.0_a, -kTooBigF32),  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    ScalarValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kScalarMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<f32, AFloat>(0.0_a, kTooBigF32),                               //
+                         Types<f32, AFloat>(0.0_a, -kTooBigF32),                              //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kVectorMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32V, AIntV>(0_a, kHighestI32 + 1),  //
-                                              Types<i32V, AIntV>(0_a, kLowestI32 - 1),   //
-                                              Types<i32V, AIntV>(0_a, kHighestU32 + 1),  //
-                                              Types<f32V, AFloatV>(0.0_a, kTooBigF32),   //
-                                              Types<f32V, AFloatV>(0.0_a, -kTooBigF32),  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    VectorValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kVectorMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32V, AIntV>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                         Types<i32V, AIntV>(0_a, static_cast<double>(u32::kHighestValue) + 1),  //
+                         Types<f32V, AFloatV>(0.0_a, kTooBigF32),                               //
+                         Types<f32V, AFloatV>(0.0_a, -kTooBigF32),                              //
+                     })));
 
 INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented,
                          MaterializeAbstractNumericToDefaultType,
@@ -1016,31 +1022,34 @@
                                               Types<f32M, AFloatM>(0.0_a, -kTooBigF32),  //
                                           })));
 
-INSTANTIATE_TEST_SUITE_P(AIntValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::ValuesIn(kAIntMethods),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),   //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    AIntValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::ValuesIn(kAIntMethods),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(WorkgroupSizeValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::Values(Method::kWorkgroupSize),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                              Types<i32, AInt>(0_a, kLowestI32 - 1),   //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    WorkgroupSizeValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::Values(Method::kWorkgroupSize),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kLowestValue) - 1),   //
+                     })));
 
-INSTANTIATE_TEST_SUITE_P(ArrayLengthValueCannotBeRepresented,
-                         MaterializeAbstractNumericToDefaultType,
-                         testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
-                                          testing::Values(Method::kArrayLength),
-                                          testing::ValuesIn(std::vector<Data>{
-                                              Types<i32, AInt>(0_a, kHighestI32 + 1),  //
-                                          })));
+INSTANTIATE_TEST_SUITE_P(
+    ArrayLengthValueCannotBeRepresented,
+    MaterializeAbstractNumericToDefaultType,
+    testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
+                     testing::Values(Method::kArrayLength),
+                     testing::ValuesIn(std::vector<Data>{
+                         Types<i32, AInt>(0_a, static_cast<double>(i32::kHighestValue) + 1),  //
+                     })));
 
 }  // namespace materialize_abstract_numeric_to_default_type