tint: add CheckedDiv for abstract numbers
Bug: tint:1581 Change-Id: Iafed168a916ac3a1062bcf53299e8ff17fc389fb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101041 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
5dcdf5d910
commit
1741f4443e
|
@ -479,6 +479,28 @@ inline std::optional<AFloat> CheckedMul(AFloat a, AFloat b) {
|
|||
return AFloat{result};
|
||||
}
|
||||
|
||||
/// @returns a / b, or an empty optional if the resulting value overflowed the AInt
|
||||
inline std::optional<AInt> CheckedDiv(AInt a, AInt b) {
|
||||
if (b == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (b == -1 && a == AInt::Lowest()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return AInt{a.value / b.value};
|
||||
}
|
||||
|
||||
/// @returns a / b, or an empty optional if the resulting value overflowed the AFloat
|
||||
inline std::optional<AFloat> CheckedDiv(AFloat a, AFloat b) {
|
||||
auto result = a.value / b.value;
|
||||
if (!std::isfinite(result)) {
|
||||
return {};
|
||||
}
|
||||
return AFloat{result};
|
||||
}
|
||||
|
||||
/// @returns a * b + c, or an empty optional if the value overflowed the AInt
|
||||
inline std::optional<AInt> CheckedMadd(AInt a, AInt b, AInt c) {
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
|
||||
|
|
|
@ -537,6 +537,60 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
}));
|
||||
|
||||
using CheckedDivTest_AInt = testing::TestWithParam<BinaryCheckedCase_AInt>;
|
||||
TEST_P(CheckedDivTest_AInt, Test) {
|
||||
auto expect = std::get<0>(GetParam());
|
||||
auto a = std::get<1>(GetParam());
|
||||
auto b = std::get<2>(GetParam());
|
||||
EXPECT_EQ(CheckedDiv(a, b), expect) << std::hex << "0x" << a << " - 0x" << b;
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
CheckedDivTest_AInt,
|
||||
CheckedDivTest_AInt,
|
||||
testing::ValuesIn(std::vector<BinaryCheckedCase_AInt>{
|
||||
{AInt(0), AInt(0), AInt(1)},
|
||||
{AInt(1), AInt(1), AInt(1)},
|
||||
{AInt(1), AInt(1), AInt(1)},
|
||||
{AInt(2), AInt(2), AInt(1)},
|
||||
{AInt(2), AInt(4), AInt(2)},
|
||||
{AInt::Highest(), AInt::Highest(), AInt(1)},
|
||||
{AInt::Lowest(), AInt::Lowest(), AInt(1)},
|
||||
{AInt(1), AInt::Highest(), AInt::Highest()},
|
||||
{AInt(0), AInt(0), AInt::Highest()},
|
||||
{AInt(0), AInt(0), AInt::Lowest()},
|
||||
{OVERFLOW, AInt(123), AInt(0)},
|
||||
{OVERFLOW, AInt(-123), AInt(0)},
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
}));
|
||||
|
||||
using CheckedDivTest_AFloat = testing::TestWithParam<BinaryCheckedCase_AFloat>;
|
||||
TEST_P(CheckedDivTest_AFloat, Test) {
|
||||
auto expect = std::get<0>(GetParam());
|
||||
auto a = std::get<1>(GetParam());
|
||||
auto b = std::get<2>(GetParam());
|
||||
EXPECT_EQ(CheckedDiv(a, b), expect) << std::hex << "0x" << a << " - 0x" << b;
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
CheckedDivTest_AFloat,
|
||||
CheckedDivTest_AFloat,
|
||||
testing::ValuesIn(std::vector<BinaryCheckedCase_AFloat>{
|
||||
{AFloat(0), AFloat(0), AFloat(1)},
|
||||
{AFloat(1), AFloat(1), AFloat(1)},
|
||||
{AFloat(1), AFloat(1), AFloat(1)},
|
||||
{AFloat(2), AFloat(2), AFloat(1)},
|
||||
{AFloat(2), AFloat(4), AFloat(2)},
|
||||
{AFloat::Highest(), AFloat::Highest(), AFloat(1)},
|
||||
{AFloat::Lowest(), AFloat::Lowest(), AFloat(1)},
|
||||
{AFloat(1), AFloat::Highest(), AFloat::Highest()},
|
||||
{AFloat(0), AFloat(0), AFloat::Highest()},
|
||||
{-AFloat(0), AFloat(0), AFloat::Lowest()},
|
||||
{OVERFLOW, AFloat(123), AFloat(0)},
|
||||
{OVERFLOW, AFloat(123), AFloat(-0)},
|
||||
{OVERFLOW, AFloat(-123), AFloat(0)},
|
||||
{OVERFLOW, AFloat(-123), AFloat(-0)},
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
}));
|
||||
|
||||
using TernaryCheckedCase = std::tuple<std::optional<AInt>, AInt, AInt, AInt>;
|
||||
|
||||
using CheckedMaddTest_AInt = testing::TestWithParam<TernaryCheckedCase>;
|
||||
|
|
Loading…
Reference in New Issue