diff --git a/libcudacxx/test/libcudacxx/cuda/numeric/overflow.arithmetic/mul_overflow.pass.cpp b/libcudacxx/test/libcudacxx/cuda/numeric/overflow.arithmetic/mul_overflow.pass.cpp index bd2b1ea2c17..bc0f6950275 100644 --- a/libcudacxx/test/libcudacxx/cuda/numeric/overflow.arithmetic/mul_overflow.pass.cpp +++ b/libcudacxx/test/libcudacxx/cuda/numeric/overflow.arithmetic/mul_overflow.pass.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -83,6 +84,7 @@ TEST_FUNC constexpr bool test_type() test_mul_overflow(17, 14, 238); test_mul_overflow(-254, 127, -32258); test_mul_overflow(1657, -13748, -22780436); + test_mul_overflow(-50000, -50000, 2500000000); test_mul_overflow(-2147483647, 4294967295, -9223372030412324865); if constexpr (cuda::std::is_unsigned_v && cuda::std::is_unsigned_v) { @@ -93,6 +95,44 @@ TEST_FUNC constexpr bool test_type() sizeof(L) >= sizeof(Res)); } + // 5. Test T_MIN * T_MIN and T_MAX * T_MAX + if constexpr (sizeof(L) < sizeof(cuda::std::__cccl_uintmax_t) && sizeof(R) < sizeof(cuda::std::__cccl_uintmax_t)) + { + constexpr auto __max_nbits = cuda::std::max(cuda::std::__num_bits_v, cuda::std::__num_bits_v); + using _Up = cuda::std::__make_nbit_int_t<2 * __max_nbits, cuda::std::is_signed_v || cuda::std::is_signed_v>; + test_mul_overflow(cuda::std::numeric_limits::min(), + cuda::std::numeric_limits::min(), + _Up{cuda::std::numeric_limits::min()} * _Up{cuda::std::numeric_limits::min()}); + test_mul_overflow(cuda::std::numeric_limits::max(), + cuda::std::numeric_limits::max(), + _Up{cuda::std::numeric_limits::max()} * _Up{cuda::std::numeric_limits::max()}); + } + +#if _CCCL_HAS_INT128() + // 6. Test __uint128_t multiplication and overflow cases + if constexpr (cuda::std::is_same_v && cuda::std::is_same_v) + { + if constexpr (cuda::std::is_same_v) + { + test_mul_overflow( + __uint128_t{~0ull}, // 2^64 - 1 + __uint128_t{1ull} << 63, // 2^63 + (__uint128_t{0x7fffffffffffffffULL} << 64) | __uint128_t{0x8000000000000000ULL}, + false); + test_mul_overflow(__uint128_t{1} << 100, __uint128_t{1} << 100, __uint128_t{0}, true); + test_mul_overflow( + cuda::std::numeric_limits<__uint128_t>::max(), + __uint128_t{2}, + cuda::std::numeric_limits<__uint128_t>::max() - 1, + true); + } + else if constexpr (cuda::std::is_same_v) + { + test_mul_overflow( + ~0ull, __uint128_t{5} << 100, __uint128_t{0xffffffb000000000ULL} << 64 | __uint128_t{0}, true); + } + } +#endif // _CCCL_HAS_INT128() return true; } @@ -102,7 +142,7 @@ using TypeList = cuda::std::tuple< short, unsigned short, int, - unsigned long, + unsigned int, long, unsigned long, long long,