Skip to content
50 changes: 41 additions & 9 deletions tests/std/include/test_vector_algorithms_support.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
#pragma once

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <isa_availability.h>
#include <random>
#include <string>
#include <vector>

inline void initialize_randomness(std::mt19937_64& gen) {
Expand Down Expand Up @@ -41,24 +44,53 @@ inline void initialize_randomness(std::mt19937_64& gen) {
extern "C" long __isa_enabled;

inline void disable_instructions(ISA_AVAILABILITY isa) {
__isa_enabled &= ~(1UL << static_cast<unsigned long>(isa));
const unsigned long as_ulong = static_cast<unsigned long>(isa);

auto has_env_var_escape_hatch = [] {
size_t return_value = 0;
char buffer[2]{};
const errno_t err = ::getenv_s(&return_value, buffer, std::size(buffer), "STL_TEST_DOWNLEVEL_MACHINE");
return err == 0 && buffer == std::string{"1"};
};

if (!has_env_var_escape_hatch()) {
const bool has_feature = (__isa_enabled & (1UL << as_ulong)) != 0;
if (!has_feature) {
std::printf("The feature %lu is not available, the test does not have full coverage!\n"
"You can set the environment variable STL_TEST_DOWNLEVEL_MACHINE to 1,\n"
"if you intentionally test on a machine without all features available.\n",
as_ulong);
}
assert(has_feature);
}

__isa_enabled &= ~(1UL << as_ulong);
}
#endif // (defined(_M_IX86) || defined(_M_X64)) && !defined(_M_CEE_PURE)

constexpr std::size_t dataCount = 1024;

template <class TestFunc>
void run_randomized_tests_with_different_isa_levels(TestFunc tests) {
std::mt19937_64 gen;
initialize_randomness(gen);
void run_tests_with_different_isa_levels(TestFunc tests) {
tests();

tests(gen);
#if (defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))) && !defined(_M_CEE_PURE)
const auto original_isa = __isa_enabled;

#if (defined(_M_IX86) || defined(_M_X64)) && !defined(_M_CEE_PURE)
disable_instructions(__ISA_AVAILABLE_AVX2);
tests(gen);
tests();

disable_instructions(__ISA_AVAILABLE_SSE42);
tests(gen);
#endif // (defined(_M_IX86) || defined(_M_X64)) && !defined(_M_CEE_PURE)
tests();

__isa_enabled = original_isa;
#endif // (defined(_M_IX86) || (defined(_M_X64) && !defined(_M_ARM64EC))) && !defined(_M_CEE_PURE)
}

template <class TestFunc>
void run_randomized_tests_with_different_isa_levels(TestFunc tests) {
std::mt19937_64 gen;
initialize_randomness(gen);

run_tests_with_different_isa_levels([&] { tests(gen); });
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <isa_availability.h>
#include <ranges>

#pragma warning(push) // TRANSITION, OS-23694920
#pragma warning(disable : 4668) // 'MEOW' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
#include <Windows.h>
#pragma warning(pop)

#include "test_vector_algorithms_support.hpp"

using namespace std;

template <class T>
Expand All @@ -31,14 +32,6 @@ void test_impl(void* sv, void* ev) {
}
}

#if defined(_M_IX86) || defined(_M_X64)
extern "C" long __isa_enabled;

void disable_instructions(ISA_AVAILABILITY isa) {
__isa_enabled &= ~(1UL << static_cast<unsigned long>(isa));
}
#endif // defined(_M_IX86) || defined(_M_X64)

void test_all_element_sizes(void* p, size_t page) {
test_impl<char>(p, reinterpret_cast<char*>(p) + page);
test_impl<short>(p, reinterpret_cast<char*>(p) + page);
Expand All @@ -58,13 +51,7 @@ int main() {
void* p2 = VirtualAlloc(p, page, MEM_COMMIT, PAGE_READWRITE);
assert(p2 != nullptr);

test_all_element_sizes(p, page);
#if defined(_M_IX86) || defined(_M_X64)
disable_instructions(__ISA_AVAILABLE_AVX2);
test_all_element_sizes(p, page);
disable_instructions(__ISA_AVAILABLE_SSE42);
test_all_element_sizes(p, page);
#endif // defined(_M_IX86) || defined(_M_X64)
run_tests_with_different_isa_levels([&] { test_all_element_sizes(p, page); });

VirtualFree(p, 0, MEM_RELEASE);
}
16 changes: 2 additions & 14 deletions tests/std/tests/GH_003617_vectorized_meow_element/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@
#ifdef _M_X64

#include <cstddef>
#include <isa_availability.h>
#include <vector>

#include "test_min_max_element_support.hpp"
#include "test_vector_algorithms_support.hpp"

using namespace std;

extern "C" long __isa_enabled;

void disable_instructions(ISA_AVAILABILITY isa) {
__isa_enabled &= ~(1UL << static_cast<unsigned long>(isa));
}

void test_gh_3617() {
// Test GH-3617 "<algorithm>: Silent bad codegen for vectorized meow_element() above 4 GB".
constexpr size_t n = 0x4000'0010;
Expand All @@ -31,13 +25,7 @@ void test_gh_3617() {
}

int main() {
test_gh_3617();

disable_instructions(__ISA_AVAILABLE_AVX2);
test_gh_3617();

disable_instructions(__ISA_AVAILABLE_SSE42);
test_gh_3617();
run_tests_with_different_isa_levels([] { test_gh_3617(); });
}
#else // ^^^ x64 / other architectures vvv
int main() {}
Expand Down
Loading