[tint] Add u64 definition to number.h
Bug: 394291739
Change-Id: I4da1a4800d3b9bc35cfdf54f86930bdf32b3bd5f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/224595
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/number.h b/src/tint/lang/core/number.h
index bdff3ed..820867a 100644
--- a/src/tint/lang/core/number.h
+++ b/src/tint/lang/core/number.h
@@ -286,6 +286,8 @@
using u8 = Number<uint8_t>;
/// `u32` is a type alias to `Number<uint32_t>`.
using u32 = Number<uint32_t>;
+/// `u64` is a type alias to `Number<uint64_t>`.
+using u64 = Number<uint64_t>;
/// `f32` is a type alias to `Number<float>`
using f32 = Number<float>;
/// `f16` is a type alias to `Number<detail::NumberKindF16>`, which should be IEEE 754 binary16.
@@ -365,17 +367,29 @@
// Float to integral conversions clamp to the target range.
// https://gpuweb.github.io/gpuweb/wgsl/#scalar-floating-point-to-integral-conversion
constexpr auto float_to_integral = IsFloatingPoint<FROM> && IsIntegral<UnwrapNumber<TO>>;
- if (value > static_cast<T>(TO::kHighestValue)) {
- if (float_to_integral) {
- return TO(TO::kHighestValue);
+ if constexpr (std::is_same_v<TO, u64>) {
+ // Special case checks for u64 as its range does not fit into an AInt.
+ if (value < 0) {
+ if constexpr (float_to_integral) {
+ return TO(0);
+ }
+ if constexpr (IsSignedIntegral<FROM>) {
+ return ConversionFailure::kExceedsNegativeLimit;
+ }
}
- return ConversionFailure::kExceedsPositiveLimit;
- }
- if (value < static_cast<T>(TO::kLowestValue)) {
- if (float_to_integral) {
- return TO(TO::kLowestValue);
+ } else {
+ if (value > static_cast<T>(TO::kHighestValue)) {
+ if (float_to_integral) {
+ return TO(TO::kHighestValue);
+ }
+ return ConversionFailure::kExceedsPositiveLimit;
}
- return ConversionFailure::kExceedsNegativeLimit;
+ if (value < static_cast<T>(TO::kLowestValue)) {
+ if (float_to_integral) {
+ return TO(TO::kLowestValue);
+ }
+ return ConversionFailure::kExceedsNegativeLimit;
+ }
}
return TO(value); // Success
}
diff --git a/src/tint/lang/core/number_test.cc b/src/tint/lang/core/number_test.cc
index 7662c29..a52a73b 100644
--- a/src/tint/lang/core/number_test.cc
+++ b/src/tint/lang/core/number_test.cc
@@ -156,6 +156,7 @@
EXPECT_EQ(CheckedConvert<i32>(0_i), 0_i);
EXPECT_EQ(CheckedConvert<i8>(i8(0)), i8(0));
EXPECT_EQ(CheckedConvert<u32>(0_u), 0_u);
+ EXPECT_EQ(CheckedConvert<u64>(u64(0)), u64(0));
EXPECT_EQ(CheckedConvert<u8>(u8(0)), u8(0));
EXPECT_EQ(CheckedConvert<f32>(0_f), 0_f);
EXPECT_EQ(CheckedConvert<f16>(0_h), 0_h);
@@ -165,6 +166,7 @@
EXPECT_EQ(CheckedConvert<i32>(1_i), 1_i);
EXPECT_EQ(CheckedConvert<i8>(i8(1)), i8(1));
EXPECT_EQ(CheckedConvert<u32>(1_u), 1_u);
+ EXPECT_EQ(CheckedConvert<u64>(u64(1)), u64(1));
EXPECT_EQ(CheckedConvert<u8>(u8(1)), u8(1));
EXPECT_EQ(CheckedConvert<f32>(1_f), 1_f);
EXPECT_EQ(CheckedConvert<f16>(1_h), 1_h);
@@ -175,6 +177,7 @@
EXPECT_EQ(CheckedConvert<i8>(AInt(i8::Highest())), i8::Highest());
EXPECT_EQ(CheckedConvert<u32>(AInt(u32::Highest())), u32::Highest());
EXPECT_EQ(CheckedConvert<u32>(i32::Highest()), u32(i32::Highest()));
+ EXPECT_EQ(CheckedConvert<u64>(AInt::Highest()), u64(AInt::Highest()));
EXPECT_EQ(CheckedConvert<u8>(AInt(u8::Highest())), u8::Highest());
EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Highest())), f32::Highest());
EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Highest())), f16::Highest());
@@ -184,6 +187,7 @@
EXPECT_EQ(CheckedConvert<i32>(AInt(i32::Lowest())), i32::Lowest());
EXPECT_EQ(CheckedConvert<i8>(AInt(i8::Lowest())), i8::Lowest());
EXPECT_EQ(CheckedConvert<u32>(AInt(u32::Lowest())), u32::Lowest());
+ EXPECT_EQ(CheckedConvert<u64>(AInt(u64::Lowest())), u64::Lowest());
EXPECT_EQ(CheckedConvert<u8>(AInt(u8::Lowest())), u8::Lowest());
EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Lowest())), f32::Lowest());
EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Lowest())), f16::Lowest());
@@ -193,6 +197,7 @@
EXPECT_EQ(CheckedConvert<i32>(AInt(0)), i32(0));
EXPECT_EQ(CheckedConvert<i8>(AInt(0)), i8(0));
EXPECT_EQ(CheckedConvert<u32>(AInt(0)), u32(0));
+ EXPECT_EQ(CheckedConvert<u64>(AInt(0)), u64(0));
EXPECT_EQ(CheckedConvert<u8>(AInt(0)), u8(0));
EXPECT_EQ(CheckedConvert<f32>(AFloat(f32::Smallest())), f32::Smallest());
EXPECT_EQ(CheckedConvert<f16>(AFloat(f16::Smallest())), f16::Smallest());
@@ -232,11 +237,13 @@
ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u32>(AInt(static_cast<uint64_t>(u32::Lowest()) - 1)),
ConversionFailure::kExceedsNegativeLimit);
+ EXPECT_EQ(CheckedConvert<u64>(AInt(-1)), ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u8>(AInt(static_cast<uint64_t>(u8::Lowest()) - 1)),
ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u32>(i32(-1)), ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u32>(i32::Lowest()), ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u32>(f32::Lowest()), u32::Lowest());
+ EXPECT_EQ(CheckedConvert<u64>(f32::Lowest()), u64::Lowest());
EXPECT_EQ(CheckedConvert<u8>(i8(-1)), ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u8>(i8::Lowest()), ConversionFailure::kExceedsNegativeLimit);
EXPECT_EQ(CheckedConvert<u8>(f32::Lowest()), u8::Lowest());