From d060f36a1cb56df491820b10bdeb6a3258e7a73c Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Fri, 29 Jul 2022 17:12:01 +0000 Subject: [PATCH] tint: refactor Number constants for highest, lowest, etc. Bug: tint:1581 Change-Id: I3945e8d6021370e5b9837e77d29eeb46fcb97082 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97560 Kokoro: Kokoro Reviewed-by: Ben Clayton Commit-Queue: Antonio Maiorano --- src/tint/number.cc | 30 +- src/tint/number.h | 61 +-- src/tint/number_test.cc | 149 ++++---- src/tint/reader/wgsl/lexer.cc | 29 +- src/tint/resolver/const_eval.cc | 9 +- src/tint/resolver/const_eval_test.cc | 106 +++--- src/tint/resolver/materialize_test.cc | 517 +++++++++++++------------- 7 files changed, 448 insertions(+), 453 deletions(-) diff --git a/src/tint/number.cc b/src/tint/number.cc index 6371442f48..91dbb45f83 100644 --- a/src/tint/number.cc +++ b/src/tint/number.cc @@ -34,10 +34,10 @@ std::ostream& operator<<(std::ostream& out, ConversionFailure failure) { } f16::type f16::Quantize(f16::type value) { - if (value > kHighest) { + if (value > kHighestValue) { return std::numeric_limits::infinity(); } - if (value < kLowest) { + if (value < kLowestValue) { return -std::numeric_limits::infinity(); } // Below value must be within the finite range of a f16. @@ -82,17 +82,17 @@ f16::type f16::Quantize(f16::type value) { // 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 @@ f16::type f16::Quantize(f16::type value) { // 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 32cca596ee..13ba76c535 100644 --- a/src/tint/number.h +++ b/src/tint/number.h @@ -68,26 +68,47 @@ constexpr bool IsInteger = std::is_integral_v; template constexpr bool IsNumeric = IsInteger || IsFloatingPoint; +/// Resolves to the underlying type for a Number. +template +using UnwrapNumber = typename detail::NumberUnwrapper::type; + +/// NumberBase is a CRTP base class for Number +template +struct NumberBase { + /// @returns value of type `Number` with the highest value for that type. + static NumberT Highest() { return NumberT(NumberT::kHighestValue); } + /// @returns value of type `Number` with the lowest value for that type. + static NumberT Lowest() { return NumberT(NumberT::kLowestValue); } + /// @returns value of type `Number` with the smallest value for that type. + static NumberT Smallest() { return NumberT(NumberT::kSmallestValue); } + /// @returns value of type `Number` that represents NaN for that type. + static NumberT NaN() { + return NumberT(std::numeric_limits>::quiet_NaN()); + } + /// @returns value of type `Number` that represents infinity for that type. + static NumberT Inf() { return NumberT(std::numeric_limits>::infinity()); } +}; + /// Number wraps a integer or floating point number, enforcing explicit casting. template -struct Number { +struct Number : NumberBase> { static_assert(IsNumeric, "Number 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::max(); + static constexpr type kHighestValue = std::numeric_limits::max(); /// Lowest finite representable value of this type. - static constexpr type kLowest = std::numeric_limits::lowest(); + static constexpr type kLowestValue = std::numeric_limits::lowest(); /// Smallest positive normal value of this type. - static constexpr type kSmallest = + static constexpr type kSmallestValue = std::is_integral_v ? 0 : std::numeric_limits::min(); /// Smallest positive subnormal value of this type, 0 for integral type. - static constexpr type kSmallestSubnormal = + static constexpr type kSmallestSubnormalValue = std::is_integral_v ? 0 : std::numeric_limits::denorm_min(); /// Constructor. The value is zero-initialized. @@ -123,10 +144,6 @@ struct Number { type value = {}; }; -/// Resolves to the underlying type for a Number. -template -using UnwrapNumber = typename detail::NumberUnwrapper::type; - /// Writes the number to the ostream. /// @param out the std::ostream to write to /// @param num the Number @@ -139,23 +156,23 @@ inline std::ostream& operator<<(std::ostream& out, Number num) { /// The partial specification of Number for f16 type, storing the f16 value as float, /// and enforcing proper explicit casting. template <> -struct Number { +struct Number : NumberBase> { /// 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 @@ utils::Result CheckedConvert(Number num) { using T = std::conditional_t> || IsFloatingPoint, AFloat::type, AInt::type>; const auto value = static_cast(num.value); - if (value > static_cast(TO::kHighest)) { + if (value > static_cast(TO::kHighestValue)) { return ConversionFailure::kExceedsPositiveLimit; } - if (value < static_cast(TO::kLowest)) { + if (value < static_cast(TO::kLowestValue)) { return ConversionFailure::kExceedsNegativeLimit; } return TO(value); // Success @@ -333,11 +350,11 @@ inline std::optional CheckedAdd(AInt a, AInt b) { } #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 @@ inline std::optional CheckedMul(AInt a, AInt b) { #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 eeb31edacd..16925edfc1 100644 --- a/src/tint/number_test.cc +++ b/src/tint/number_test.cc @@ -26,38 +26,19 @@ using namespace tint::number_suffixes; // NOLINT namespace tint { namespace { -constexpr int64_t kHighestI32 = static_cast(std::numeric_limits::max()); -constexpr int64_t kHighestU32 = static_cast(std::numeric_limits::max()); -constexpr int64_t kLowestI32 = static_cast(std::numeric_limits::min()); -constexpr int64_t kLowestU32 = static_cast(std::numeric_limits::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, CheckedConvertIdentity) { } TEST(NumberTest, CheckedConvertLargestValue) { - EXPECT_EQ(CheckedConvert(AInt(kHighestI32)), i32(kHighestI32)); - EXPECT_EQ(CheckedConvert(AInt(kHighestU32)), u32(kHighestU32)); - EXPECT_EQ(CheckedConvert(i32(kHighestI32)), u32(kHighestI32)); - EXPECT_EQ(CheckedConvert(AFloat(kHighestF32)), f32(kHighestF32)); - EXPECT_EQ(CheckedConvert(AFloat(kHighestF16)), f16(kHighestF16)); + EXPECT_EQ(CheckedConvert(AInt(i32::Highest())), i32::Highest()); + EXPECT_EQ(CheckedConvert(AInt(u32::Highest())), u32::Highest()); + EXPECT_EQ(CheckedConvert(i32::Highest()), u32(i32::Highest())); + EXPECT_EQ(CheckedConvert(AFloat(f32::Highest())), f32::Highest()); + EXPECT_EQ(CheckedConvert(AFloat(f16::Highest())), f16::Highest()); } TEST(NumberTest, CheckedConvertLowestValue) { - EXPECT_EQ(CheckedConvert(AInt(kLowestI32)), i32(kLowestI32)); - EXPECT_EQ(CheckedConvert(AInt(kLowestU32)), u32(kLowestU32)); - EXPECT_EQ(CheckedConvert(AFloat(kLowestF32)), f32(kLowestF32)); - EXPECT_EQ(CheckedConvert(AFloat(kLowestF16)), f16(kLowestF16)); + EXPECT_EQ(CheckedConvert(AInt(i32::Lowest())), i32::Lowest()); + EXPECT_EQ(CheckedConvert(AInt(u32::Lowest())), u32::Lowest()); + EXPECT_EQ(CheckedConvert(AFloat(f32::Lowest())), f32::Lowest()); + EXPECT_EQ(CheckedConvert(AFloat(f16::Lowest())), f16::Lowest()); } TEST(NumberTest, CheckedConvertSmallestValue) { EXPECT_EQ(CheckedConvert(AInt(0)), i32(0)); EXPECT_EQ(CheckedConvert(AInt(0)), u32(0)); - EXPECT_EQ(CheckedConvert(AFloat(kSmallestF32)), f32(kSmallestF32)); - EXPECT_EQ(CheckedConvert(AFloat(kSmallestF16)), f16(kSmallestF16)); + EXPECT_EQ(CheckedConvert(AFloat(f32::Smallest())), f32::Smallest()); + EXPECT_EQ(CheckedConvert(AFloat(f16::Smallest())), f16::Smallest()); } TEST(NumberTest, CheckedConvertExceedsPositiveLimit) { - EXPECT_EQ(CheckedConvert(AInt(kHighestI32 + 1)), ConversionFailure::kExceedsPositiveLimit); - EXPECT_EQ(CheckedConvert(AInt(kHighestU32 + 1)), ConversionFailure::kExceedsPositiveLimit); - EXPECT_EQ(CheckedConvert(u32(kHighestU32)), ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(AInt(static_cast(i32::Highest()) + 1)), + ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(AInt(static_cast(u32::Highest()) + 1)), + ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(u32::Highest()), ConversionFailure::kExceedsPositiveLimit); EXPECT_EQ(CheckedConvert(u32(0x80000000)), ConversionFailure::kExceedsPositiveLimit); - EXPECT_EQ(CheckedConvert(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit); - EXPECT_EQ(CheckedConvert(f32(f32::kHighest)), ConversionFailure::kExceedsPositiveLimit); - EXPECT_EQ(CheckedConvert(AFloat(AFloat::kHighest)), - ConversionFailure::kExceedsPositiveLimit); - EXPECT_EQ(CheckedConvert(AFloat(AFloat::kHighest)), - ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(f32::Highest()), ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(f32::Highest()), ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(AFloat::Highest()), ConversionFailure::kExceedsPositiveLimit); + EXPECT_EQ(CheckedConvert(AFloat::Highest()), ConversionFailure::kExceedsPositiveLimit); EXPECT_EQ(CheckedConvert(AFloat(kHighestF32NextULP)), ConversionFailure::kExceedsPositiveLimit); EXPECT_EQ(CheckedConvert(AFloat(kHighestF16NextULP)), @@ -194,16 +175,16 @@ TEST(NumberTest, CheckedConvertExceedsPositiveLimit) { } TEST(NumberTest, CheckedConvertExceedsNegativeLimit) { - EXPECT_EQ(CheckedConvert(AInt(kLowestI32 - 1)), ConversionFailure::kExceedsNegativeLimit); - EXPECT_EQ(CheckedConvert(AInt(kLowestU32 - 1)), ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(AInt(static_cast(i32::Lowest()) - 1)), + ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(AInt(static_cast(u32::Lowest()) - 1)), + ConversionFailure::kExceedsNegativeLimit); EXPECT_EQ(CheckedConvert(i32(-1)), ConversionFailure::kExceedsNegativeLimit); - EXPECT_EQ(CheckedConvert(i32(kLowestI32)), ConversionFailure::kExceedsNegativeLimit); - EXPECT_EQ(CheckedConvert(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit); - EXPECT_EQ(CheckedConvert(f32(f32::kLowest)), ConversionFailure::kExceedsNegativeLimit); - EXPECT_EQ(CheckedConvert(AFloat(AFloat::kLowest)), - ConversionFailure::kExceedsNegativeLimit); - EXPECT_EQ(CheckedConvert(AFloat(AFloat::kLowest)), - ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(i32::Lowest()), ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(f32::Lowest()), ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(f32::Lowest()), ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(AFloat::Lowest()), ConversionFailure::kExceedsNegativeLimit); + EXPECT_EQ(CheckedConvert(AFloat::Lowest()), ConversionFailure::kExceedsNegativeLimit); EXPECT_EQ(CheckedConvert(AFloat(kLowestF32NextULP)), ConversionFailure::kExceedsNegativeLimit); EXPECT_EQ(CheckedConvert(AFloat(kLowestF16NextULP)), @@ -401,19 +382,19 @@ INSTANTIATE_TEST_SUITE_P( {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 @@ INSTANTIATE_TEST_SUITE_P( {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 @@ INSTANTIATE_TEST_SUITE_P( {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 @@ INSTANTIATE_TEST_SUITE_P( {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 c9056e0ab9..778cb3ff82 100644 --- a/src/tint/reader/wgsl/lexer.cc +++ b/src/tint/reader/wgsl/lexer.cc @@ -706,8 +706,8 @@ Token Lexer::try_hex_float() { if (has_f_suffix) { // Check value fits in f32 - if (result_f64 < static_cast(f32::kLowest) || - result_f64 > static_cast(f32::kHighest)) { + if (result_f64 < static_cast(f32::kLowestValue) || + result_f64 > static_cast(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 @@ Token Lexer::try_hex_float() { // 0. int valid_mantissa_bits = 0; double abs_result_f64 = std::fabs(result_f64); - if (abs_result_f64 >= static_cast(f32::kSmallest)) { + if (abs_result_f64 >= static_cast(f32::kSmallestValue)) { // The result shall be a normal f32 value. valid_mantissa_bits = 23; - } else if (abs_result_f64 >= static_cast(f32::kSmallestSubnormal)) { + } else if (abs_result_f64 >= static_cast(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 @@ Token Lexer::try_hex_float() { return {Token::Type::kFloatLiteral_F, source, result_f64}; } else if (has_h_suffix) { // Check value fits in f16 - if (result_f64 < static_cast(f16::kLowest) || - result_f64 > static_cast(f16::kHighest)) { + if (result_f64 < static_cast(f16::kLowestValue) || + result_f64 > static_cast(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 @@ Token Lexer::try_hex_float() { // 0. int valid_mantissa_bits = 0; double abs_result_f64 = std::fabs(result_f64); - if (abs_result_f64 >= static_cast(f16::kSmallest)) { + if (abs_result_f64 >= static_cast(f16::kSmallestValue)) { // The result shall be a normal f16 value. valid_mantissa_bits = 10; - } else if (abs_result_f64 >= static_cast(f16::kSmallestSubnormal)) { + } else if (abs_result_f64 >= static_cast(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 ba70b33068..dec4992527 100644 --- a/src/tint/resolver/const_eval.cc +++ b/src/tint/resolver/const_eval.cc @@ -209,21 +209,20 @@ struct Element : Constant { } else if constexpr (IsFloatingPoint>) { // [x -> floating-point] - number not exactly representable // https://www.w3.org/TR/WGSL/#floating-point-conversion - constexpr auto kInf = std::numeric_limits::infinity(); switch (conv.Failure()) { case ConversionFailure::kExceedsNegativeLimit: - return builder.create>(target_ty, TO(-kInf)); + return builder.create>(target_ty, -TO::Inf()); case ConversionFailure::kExceedsPositiveLimit: - return builder.create>(target_ty, TO(kInf)); + return builder.create>(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>(target_ty, TO(TO::kLowest)); + return builder.create>(target_ty, TO::Lowest()); case ConversionFailure::kExceedsPositiveLimit: - return builder.create>(target_ty, TO(TO::kHighest)); + return builder.create>(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 676bda23c5..3a6c971a88 100644 --- a/src/tint/resolver/const_eval_test.cc +++ b/src/tint/resolver/const_eval_test.cc @@ -29,18 +29,6 @@ using namespace tint::number_suffixes; // NOLINT namespace tint::resolver { namespace { -template -const auto kHighest = T(T::kHighest); - -template -const auto kLowest = T(T::kLowest); - -template -const auto kNaN = T(std::numeric_limits>::quiet_NaN()); - -template -const auto kInf = T(std::numeric_limits>::infinity()); - template const auto kPi = T(UnwrapNumber(3.14159265358979323846)); @@ -1336,17 +1324,17 @@ TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_i32) { 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(), i32::kHighest); + EXPECT_EQ(sem->ConstantValue()->Index(0)->As(), 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(), i32::kLowest); + EXPECT_EQ(sem->ConstantValue()->Index(1)->As(), 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(), i32::kHighest); + EXPECT_EQ(sem->ConstantValue()->Index(2)->As(), i32::Highest()); } TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_u32) { @@ -1369,17 +1357,17 @@ TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_u32) { 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(), u32::kHighest); + EXPECT_EQ(sem->ConstantValue()->Index(0)->As(), 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(), u32::kLowest); + EXPECT_EQ(sem->ConstantValue()->Index(1)->As(), 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(), u32::kHighest); + EXPECT_EQ(sem->ConstantValue()->Index(2)->As(), u32::Highest()); } TEST_F(ResolverConstEvalTest, Vec3_Convert_Large_f32_to_f16) { @@ -3071,46 +3059,46 @@ INSTANTIATE_TEST_SUITE_P(Negation, C(-0_a, 0_a), C(1_a, -1_a), C(-1_a, 1_a), - C(kHighest, -kHighest), - C(-kHighest, kHighest), - C(kLowest, Negate(kLowest)), - C(Negate(kLowest), kLowest), + 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, -kHighest), - C(-kHighest, kHighest), - C(kLowest, Negate(kLowest)), - C(Negate(kLowest), kLowest), + 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, -kHighest), - C(-kHighest, kHighest), - C(kLowest, Negate(kLowest)), - C(Negate(kLowest), kLowest), + 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, -kHighest), - C(-kHighest, kHighest), - C(kLowest, Negate(kLowest)), - C(Negate(kLowest), kLowest), + 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, -kHighest), - C(-kHighest, kHighest), - C(kLowest, Negate(kLowest)), - C(Negate(kLowest), kLowest), + 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 @@ std::vector Atan2Cases() { if constexpr (!finite_only) { std::vector non_finite_cases = { // If y is +/-INF and x is finite, +/-PI/2 is returned - C({kInf, T(0.0)}, kPiOver2, true), - C({-kInf, T(0.0)}, kPiOver2, true), + C({T::Inf(), T(0.0)}, kPiOver2, true), + C({-T::Inf(), T(0.0)}, kPiOver2, true), // If y is +/-INF and x is -INF, +/-3PI/4 is returned - C({kInf, -kInf}, k3PiOver4, true), - C({-kInf, -kInf}, k3PiOver4, true), + C({T::Inf(), -T::Inf()}, k3PiOver4, true), + C({-T::Inf(), -T::Inf()}, k3PiOver4, true), // If y is +/-INF and x is +INF, +/-PI/4 is returned - C({kInf, kInf}, kPiOver4, true), - C({-kInf, kInf}, kPiOver4, true), + C({T::Inf(), T::Inf()}, kPiOver4, true), + C({-T::Inf(), T::Inf()}, kPiOver4, true), // If x is -INF and y is finite and positive, +PI is returned - C({T(0.0), -kInf}, kPi), + C({T(0.0), -T::Inf()}, kPi), // If x is -INF and y is finite and negative, -PI is returned - C({-T(0.0), -kInf}, -kPi), + C({-T(0.0), -T::Inf()}, -kPi), // If x is +INF and y is finite and positive, +0 is returned - C({T(0.0), kInf}, 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(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(0.0)}, kNaN), - C({T(0.0), kNaN}, kNaN), - C({kNaN, kNaN}, kNaN), + 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 @@ template std::vector ClampCases() { return { C({T(0), T(0), T(0)}, T(0)), - C({T(0), T(42), kHighest}, T(42)), - C({kLowest, T(0), T(42)}, T(0)), - C({T(0), kLowest, kHighest}, T(0)), - C({T(0), kHighest, kLowest}, kLowest), - C({kHighest, kHighest, kHighest}, kHighest), - C({kLowest, kLowest, kLowest}, kLowest), - C({kHighest, kLowest, kHighest}, kHighest), - C({kLowest, kLowest, kHighest}, kLowest), + 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 56492b099f..bd363c1904 100644 --- a/src/tint/resolver/materialize_test.cc +++ b/src/tint/resolver/materialize_test.cc @@ -35,14 +35,6 @@ using u32V = builder::vec<3, u32>; using f32M = builder::mat<3, 2, f32>; using i32Varr = builder::array<3, i32>; -constexpr double kHighestU32 = static_cast(u32::kHighest); -constexpr double kLowestU32 = static_cast(u32::kLowest); -constexpr double kHighestI32 = static_cast(i32::kHighest); -constexpr double kLowestI32 = static_cast(i32::kLowest); -constexpr double kHighestF32 = static_cast(f32::kHighest); -constexpr double kLowestF32 = static_cast(f32::kLowest); -// constexpr double kHighestF16 = static_cast(f16::kHighest); -// constexpr double kLowestF16 = static_cast(f16::kLowest); constexpr double kTooBigF32 = static_cast(3.5e+38); // constexpr double kTooBigF16 = static_cast(6.6e+4); constexpr double kPiF64 = 3.141592653589793; @@ -460,142 +452,148 @@ constexpr Method kNoMaterializeMethods[] = { INSTANTIATE_TEST_SUITE_P( MaterializeScalar, MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kScalarMethods), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(-1_a, -1.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(AInt(kHighestU32), kHighestU32), // - Types(AInt(kLowestU32), kLowestU32), // - Types(0.0_a, 0.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - /* Types(0.0_a, 0.0), */ // - /* Types(1.0_a, 1.0), */ // - /* Types(AFloat(kHighestF16), kHighestF16), */ // - /* Types(AFloat(kLowestF16), kLowestF16), */ // - /* Types(AFloat(kPiF16), kPiF64), */ // - /* Types(AFloat(kSubnormalF16), kSubnormalF16), */ // - /* Types(AFloat(-kSubnormalF16), -kSubnormalF16), */ // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(AInt(u32::Highest()), u32::Highest()), // + Types(AInt(u32::Lowest()), u32::Lowest()), // + Types(0.0_a, 0.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + /* Types(0.0_a, 0.0), */ // + /* Types(1.0_a, 1.0), */ // + /* Types(AFloat(kHighestF16), kHighestF16), */ // + /* Types(AFloat(kLowestF16), kLowestF16), */ // + /* Types(AFloat(kPiF16), kPiF64), */ // + /* Types(AFloat(kSubnormalF16), kSubnormalF16), */ // + /* Types(AFloat(-kSubnormalF16), -kSubnormalF16), */ // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeVector, MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kVectorMethods), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(-1_a, -1.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(AInt(kHighestU32), kHighestU32), // - Types(AInt(kLowestU32), kLowestU32), // - Types(0.0_a, 0.0), // - Types(1.0_a, 1.0), // - Types(-1.0_a, -1.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - /* Types(0.0_a, 0.0), */ // - /* Types(1.0_a, 1.0), */ // - /* Types(-1.0_a, -1.0), */ // - /* Types(AFloat(kHighestF16), kHighestF16), */ // - /* Types(AFloat(kLowestF16), kLowestF16), */ // - /* Types(AFloat(kPiF16), kPiF64), */ // - /* Types(AFloat(kSubnormalF16), kSubnormalF16), */ // - /* Types(AFloat(-kSubnormalF16), -kSubnormalF16), */ // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(AInt(u32::Highest()), u32::Highest()), // + Types(AInt(u32::Lowest()), u32::Lowest()), // + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + /* Types(0.0_a, 0.0), */ // + /* Types(1.0_a, 1.0), */ // + /* Types(-1.0_a, -1.0), */ // + /* Types(AFloat(kHighestF16), kHighestF16), */ // + /* Types(AFloat(kLowestF16), kLowestF16), */ // + /* Types(AFloat(kPiF16), kPiF64), */ // + /* Types(AFloat(kSubnormalF16), kSubnormalF16), */ // + /* Types(AFloat(-kSubnormalF16), -kSubnormalF16), */ // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeVectorRuntimeIndex, MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::Values(Method::kRuntimeIndex), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(-1_a, -1.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - Types(0.0_a, 0.0), // - Types(1.0_a, 1.0), // - Types(-1.0_a, -1.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::Values(Method::kRuntimeIndex), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeMatrix, MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kMatrixMethods), - testing::ValuesIn(std::vector{ - Types(0.0_a, 0.0), // - Types(1.0_a, 1.0), // - Types(-1.0_a, -1.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - /* Types(0.0_a, 0.0), */ // - /* Types(1.0_a, 1.0), */ // - /* Types(-1.0_a, -1.0), */ // - /* Types(AFloat(kHighestF16), kHighestF16), */ // - /* Types(AFloat(kLowestF16), kLowestF16), */ // - /* Types(AFloat(kPiF16), kPiF64), */ // - /* Types(AFloat(kSubnormalF16), kSubnormalF16), */ // - /* Types(AFloat(-kSubnormalF16), -kSubnormalF16), */ // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kMatrixMethods), + testing::ValuesIn(std::vector{ + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + /* Types(0.0_a, 0.0), */ // + /* Types(1.0_a, 1.0), */ // + /* Types(-1.0_a, -1.0), */ // + /* Types(AFloat(kHighestF16), kHighestF16), */ // + /* Types(AFloat(kLowestF16), kLowestF16), */ // + /* Types(AFloat(kPiF16), kPiF64), */ // + /* Types(AFloat(kSubnormalF16), kSubnormalF16), */ // + /* Types(AFloat(-kSubnormalF16), -kSubnormalF16), */ // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeMatrixRuntimeIndex, MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::Values(Method::kRuntimeIndex), - testing::ValuesIn(std::vector{ - Types(0.0_a, 0.0), // - Types(1.0_a, 1.0), // - Types(-1.0_a, -1.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::Values(Method::kRuntimeIndex), + testing::ValuesIn(std::vector{ + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); -INSTANTIATE_TEST_SUITE_P(MaterializeSwitch, - MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kSwitchMethods), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(-1_a, -1.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(AInt(kHighestU32), kHighestU32), // - Types(AInt(kLowestU32), kLowestU32), // - }))); +INSTANTIATE_TEST_SUITE_P( + MaterializeSwitch, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kSwitchMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(AInt(u32::Highest()), u32::Highest()), // + Types(AInt(u32::Lowest()), u32::Lowest()), // + }))); INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize, MaterializeAbstractNumericToConcreteType, @@ -637,35 +635,37 @@ INSTANTIATE_TEST_SUITE_P(InvalidConversion, Types(), // }))); -INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented, - MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::ValuesIn(kScalarMethods), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - Types(0_a, kLowestI32 - 1), // - Types(0_a, kHighestU32 + 1), // - Types(0_a, kLowestU32 - 1), // - Types(0.0_a, kTooBigF32), // - Types(0.0_a, -kTooBigF32), // - /* Types(0.0_a, kTooBigF16), */ // - /* Types(0.0_a, -kTooBigF16), */ // - }))); +INSTANTIATE_TEST_SUITE_P( + ScalarValueCannotBeRepresented, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + Types(0_a, static_cast(i32::kLowestValue) - 1), // + Types(0_a, static_cast(u32::kHighestValue) + 1), // + Types(0_a, static_cast(u32::kLowestValue) - 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + /* Types(0.0_a, kTooBigF16), */ // + /* Types(0.0_a, -kTooBigF16), */ // + }))); -INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented, - MaterializeAbstractNumericToConcreteType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::ValuesIn(kVectorMethods), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - Types(0_a, kLowestI32 - 1), // - Types(0_a, kHighestU32 + 1), // - Types(0_a, kLowestU32 - 1), // - Types(0.0_a, kTooBigF32), // - Types(0.0_a, -kTooBigF32), // - /* Types(0.0_a, kTooBigF16), */ // - /* Types(0.0_a, -kTooBigF16), */ // - }))); +INSTANTIATE_TEST_SUITE_P( + VectorValueCannotBeRepresented, + MaterializeAbstractNumericToConcreteType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + Types(0_a, static_cast(i32::kLowestValue) - 1), // + Types(0_a, static_cast(u32::kHighestValue) + 1), // + Types(0_a, static_cast(u32::kLowestValue) - 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + /* Types(0.0_a, kTooBigF16), */ // + /* Types(0.0_a, -kTooBigF16), */ // + }))); INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented, MaterializeAbstractNumericToConcreteType, @@ -898,69 +898,73 @@ constexpr Method kMatrixMethods[] = { INSTANTIATE_TEST_SUITE_P( MaterializeScalar, MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kScalarMethods), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(-1_a, -1.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - Types(0.0_a, 0.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + Types(0.0_a, 0.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeVector, MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kVectorMethods), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(1_a, 1.0), // - Types(-1_a, -1.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - Types(0.0_a, 0.0), // - Types(1.0_a, 1.0), // - Types(-1.0_a, -1.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(1_a, 1.0), // + Types(-1_a, -1.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeMatrix, MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kMatrixMethods), - testing::ValuesIn(std::vector{ - Types(0.0_a, 0.0), // - Types(1.0_a, 1.0), // - Types(-1.0_a, -1.0), // - Types(AFloat(kHighestF32), kHighestF32), // - Types(AFloat(kLowestF32), kLowestF32), // - Types(AFloat(kPiF32), kPiF64), // - Types(AFloat(kSubnormalF32), kSubnormalF32), // - Types(AFloat(-kSubnormalF32), -kSubnormalF32), // - }))); + testing::Combine( + testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kMatrixMethods), + testing::ValuesIn(std::vector{ + Types(0.0_a, 0.0), // + Types(1.0_a, 1.0), // + Types(-1.0_a, -1.0), // + Types(AFloat(f32::Highest()), static_cast(f32::Highest())), // + Types(AFloat(f32::Lowest()), static_cast(f32::Lowest())), // + Types(AFloat(kPiF32), kPiF64), // + Types(AFloat(kSubnormalF32), kSubnormalF32), // + Types(AFloat(-kSubnormalF32), -kSubnormalF32), // + }))); -INSTANTIATE_TEST_SUITE_P(MaterializeAInt, - MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kMaterialize), - testing::ValuesIn(kAIntMethods), - testing::ValuesIn(std::vector{ - Types(0_a, 0.0), // - Types(10_a, 10.0), // - Types(AInt(kHighestI32), kHighestI32), // - Types(AInt(kLowestI32), kLowestI32), // - }))); +INSTANTIATE_TEST_SUITE_P( + MaterializeAInt, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kMaterialize), + testing::ValuesIn(kAIntMethods), + testing::ValuesIn(std::vector{ + Types(0_a, 0.0), // + Types(10_a, 10.0), // + Types(AInt(i32::Highest()), i32::Highest()), // + Types(AInt(i32::Lowest()), i32::Lowest()), // + }))); INSTANTIATE_TEST_SUITE_P( MaterializeArrayLength, @@ -971,7 +975,7 @@ INSTANTIATE_TEST_SUITE_P( Types(1_a, 1.0), // Types(10_a, 10.0), // Types(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 @@ INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize, Types(65535_a, 65535.0), // }))); -INSTANTIATE_TEST_SUITE_P(ScalarValueCannotBeRepresented, - MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::ValuesIn(kScalarMethods), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - Types(0_a, kLowestI32 - 1), // - Types(0.0_a, kTooBigF32), // - Types(0.0_a, -kTooBigF32), // - }))); +INSTANTIATE_TEST_SUITE_P( + ScalarValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kScalarMethods), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + Types(0_a, static_cast(i32::kLowestValue) - 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + }))); -INSTANTIATE_TEST_SUITE_P(VectorValueCannotBeRepresented, - MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::ValuesIn(kVectorMethods), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - Types(0_a, kLowestI32 - 1), // - Types(0_a, kHighestU32 + 1), // - Types(0.0_a, kTooBigF32), // - Types(0.0_a, -kTooBigF32), // - }))); +INSTANTIATE_TEST_SUITE_P( + VectorValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kVectorMethods), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + Types(0_a, static_cast(i32::kLowestValue) - 1), // + Types(0_a, static_cast(u32::kHighestValue) + 1), // + Types(0.0_a, kTooBigF32), // + Types(0.0_a, -kTooBigF32), // + }))); INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented, MaterializeAbstractNumericToDefaultType, @@ -1016,31 +1022,34 @@ INSTANTIATE_TEST_SUITE_P(MatrixValueCannotBeRepresented, Types(0.0_a, -kTooBigF32), // }))); -INSTANTIATE_TEST_SUITE_P(AIntValueCannotBeRepresented, - MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::ValuesIn(kAIntMethods), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - Types(0_a, kLowestI32 - 1), // - }))); +INSTANTIATE_TEST_SUITE_P( + AIntValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::ValuesIn(kAIntMethods), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + Types(0_a, static_cast(i32::kLowestValue) - 1), // + }))); -INSTANTIATE_TEST_SUITE_P(WorkgroupSizeValueCannotBeRepresented, - MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::Values(Method::kWorkgroupSize), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - Types(0_a, kLowestI32 - 1), // - }))); +INSTANTIATE_TEST_SUITE_P( + WorkgroupSizeValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::Values(Method::kWorkgroupSize), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + Types(0_a, static_cast(i32::kLowestValue) - 1), // + }))); -INSTANTIATE_TEST_SUITE_P(ArrayLengthValueCannotBeRepresented, - MaterializeAbstractNumericToDefaultType, - testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), - testing::Values(Method::kArrayLength), - testing::ValuesIn(std::vector{ - Types(0_a, kHighestI32 + 1), // - }))); +INSTANTIATE_TEST_SUITE_P( + ArrayLengthValueCannotBeRepresented, + MaterializeAbstractNumericToDefaultType, + testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented), + testing::Values(Method::kArrayLength), + testing::ValuesIn(std::vector{ + Types(0_a, static_cast(i32::kHighestValue) + 1), // + }))); } // namespace materialize_abstract_numeric_to_default_type