From e2743e5e9f1ed81ec4bce1157e5c49330aabfc5c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 23 Jun 2022 15:17:49 -0700 Subject: [PATCH 1/5] Fix 64-bit casts on x86. Co-authored-by: Alex Guteniev --- stl/src/vector_algorithms.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/src/vector_algorithms.cpp b/stl/src/vector_algorithms.cpp index 65855e9aba..5214349b76 100644 --- a/stl/src/vector_algorithms.cpp +++ b/stl/src/vector_algorithms.cpp @@ -789,8 +789,9 @@ namespace { static _Signed_t _Get_any(const __m128i _Cur) noexcept { #ifdef _M_IX86 - return static_cast<_Signed_t>((static_cast<_Unsigned_t>(_mm_extract_epi32(_Cur, 1)) << 32) - | static_cast<_Unsigned_t>(_mm_cvtsi128_si32(_Cur))); + return static_cast<_Signed_t>( + (static_cast<_Unsigned_t>(static_cast(_mm_extract_epi32(_Cur, 1))) << 32) + | static_cast<_Unsigned_t>(static_cast(_mm_cvtsi128_si32(_Cur)))); #else // ^^^ x86 ^^^ / vvv x64 vvv return static_cast<_Signed_t>(_mm_cvtsi128_si64(_Cur)); #endif // ^^^ x64 ^^^ From 80a4344e72f7e840a19a2bd46826a3c3da025cf1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 23 Jun 2022 18:04:47 -0700 Subject: [PATCH 2/5] Add specific test cases. --- tests/std/tests/VSO_0000000_vector_algorithms/test.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index aaaee36733..7b137d6b84 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -366,6 +366,13 @@ void test_vector_algorithms() { test_min_max_element_special_cases(); // AVX2 vectors test_min_max_element_special_cases(); // AVX512 vectors + // Test VSO-1558536, a regression caused by GH-2447 that was specific to 64-bit types on x86. + test_case_min_max_element(vector{10, 0x8000'0000ULL, 20, 30}); + test_case_min_max_element(vector{10, 20, 0xD000'0000'B000'0000ULL, 30, 0xC000'0000'A000'0000ULL}); + test_case_min_max_element(vector{10, 0x8000'0000LL, 20, 30}); + test_case_min_max_element( + vector{-6604286336755016904, -4365366089374418225, 6104371530830675888, -8582621853879131834}); + test_reverse(gen); test_reverse(gen); test_reverse(gen); From d0cfc911073e3ee3f772ddb856eda94068c8ba1e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 23 Jun 2022 21:58:39 -0700 Subject: [PATCH 3/5] Use randomized, wide-range testing. --- .../VSO_0000000_vector_algorithms/test.cpp | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index 7b137d6b84..866df9f632 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -2,10 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include -#include +#include #include +#include +#include #include +#include #include +#include #include #include #include @@ -13,6 +17,35 @@ using namespace std; +#pragma warning(disable : 4984) // 'if constexpr' is a C++17 language extension +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wc++17-extensions" // constexpr if is a C++17 extension +#endif // __clang__ + +void initialize_randomness(mt19937_64& gen) { + constexpr size_t n = mt19937_64::state_size; + constexpr size_t w = mt19937_64::word_size; + constexpr size_t k = w / 32; + + vector vec(n * k); + + random_device rd; + generate(vec.begin(), vec.end(), ref(rd)); + + printf("This is a randomized test.\n"); + printf("DO NOT IGNORE/RERUN ANY FAILURES.\n"); + printf("You must report them to the STL maintainers.\n\n"); + + printf("Seed vector: "); + for (const auto& e : vec) { + printf("%u,", e); + } + printf("\n"); + + seed_seq seq(vec.cbegin(), vec.cend()); + gen.seed(seq); +} + #if (defined(_M_IX86) || defined(_M_X64)) && !defined(_M_CEE_PURE) extern "C" long __isa_enabled; @@ -164,10 +197,18 @@ void test_case_min_max_element(const vector& input) { template void test_min_max_element(mt19937_64& gen) { - using Distribution = conditional_t, uniform_real_distribution, - conditional_t<(sizeof(T) > 1), uniform_int_distribution, uniform_int_distribution>>; - - Distribution dis(1, 20); + static constexpr T Min = numeric_limits::min(); + static constexpr T Max = numeric_limits::max(); + + auto dis = [] { + if constexpr (is_floating_point_v) { + return uniform_real_distribution{-Max / 2, Max / 2}; + } else if constexpr (sizeof(T) > 1) { + return uniform_int_distribution{Min, Max}; + } else { + return uniform_int_distribution{Min, Max}; + } + }(); vector input; input.reserve(dataCount); @@ -324,9 +365,7 @@ void test_swap_ranges(mt19937_64& gen) { } } -void test_vector_algorithms() { - mt19937_64 gen(1729); - +void test_vector_algorithms(mt19937_64& gen) { test_count(gen); test_count(gen); test_count(gen); @@ -445,18 +484,21 @@ void test_various_containers() { } int main() { - test_vector_algorithms(); + mt19937_64 gen; + initialize_randomness(gen); + + test_vector_algorithms(gen); test_various_containers(); #ifndef _M_CEE_PURE #if defined(_M_IX86) || defined(_M_X64) disable_instructions(__ISA_AVAILABLE_AVX2); - test_vector_algorithms(); + test_vector_algorithms(gen); disable_instructions(__ISA_AVAILABLE_SSE42); - test_vector_algorithms(); + test_vector_algorithms(gen); #endif // defined(_M_IX86) || defined(_M_X64) #if defined(_M_IX86) disable_instructions(__ISA_AVAILABLE_SSE2); - test_vector_algorithms(); + test_vector_algorithms(gen); #endif // defined(_M_IX86) #endif // _M_CEE_PURE } From d824b0d793c9be1564ddba16dc576759bd2d0a96 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 24 Jun 2022 17:00:37 -0700 Subject: [PATCH 4/5] Add static_assert. --- tests/std/tests/VSO_0000000_vector_algorithms/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index 866df9f632..fe70f6541c 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -25,6 +25,7 @@ using namespace std; void initialize_randomness(mt19937_64& gen) { constexpr size_t n = mt19937_64::state_size; constexpr size_t w = mt19937_64::word_size; + static_assert(w % 32 == 0, "w should be evenly divisible by 32"); constexpr size_t k = w / 32; vector vec(n * k); From 351e37cc68741e56a1a35a79ea78820f0f04eb84 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 24 Jun 2022 17:00:53 -0700 Subject: [PATCH 5/5] Floating-point? That doesn't look like anything to me. --- .../VSO_0000000_vector_algorithms/test.cpp | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index fe70f6541c..85f579ecb6 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -198,18 +198,9 @@ void test_case_min_max_element(const vector& input) { template void test_min_max_element(mt19937_64& gen) { - static constexpr T Min = numeric_limits::min(); - static constexpr T Max = numeric_limits::max(); - - auto dis = [] { - if constexpr (is_floating_point_v) { - return uniform_real_distribution{-Max / 2, Max / 2}; - } else if constexpr (sizeof(T) > 1) { - return uniform_int_distribution{Min, Max}; - } else { - return uniform_int_distribution{Min, Max}; - } - }(); + using Limits = numeric_limits; + + uniform_int_distribution> dis(Limits::min(), Limits::max()); vector input; input.reserve(dataCount); @@ -396,9 +387,6 @@ void test_vector_algorithms(mt19937_64& gen) { test_min_max_element(gen); test_min_max_element(gen); test_min_max_element(gen); - test_min_max_element(gen); - test_min_max_element(gen); - test_min_max_element(gen); test_min_max_element_pointers(gen);