diff --git a/stl/inc/memory b/stl/inc/memory index 42ad7303c0e..da4986bcda4 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3079,15 +3079,17 @@ inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noe return _Ptr; } -#if _HAS_CXX20 && 0 +#if _HAS_CXX20 template -_NODISCARD constexpr _Ty* assume_aligned(_Ty* _Ptr) noexcept /* strengthened */ { - // this enforces the requirement that _Nx be a power of two - __builtin_assume_aligned(_Ptr, _Nx); - - return _Ptr; +_NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthened */ { + if (_STD is_constant_evaluated()) { + return _Ptr; + } else { + // this enforces the requirement that _Nx be a power of two + return static_cast<_Ty*>(__builtin_assume_aligned(_Ptr, _Nx)); + } } -#endif // _HAS_CXX20 && 0 +#endif // _HAS_CXX20 // SPIN LOCKS _EXTERN_C diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 0d62a90da3e..9070d737dcd 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -176,6 +176,7 @@ // P0966R1 string::reserve() Should Not Shrink // P1001R2 execution::unseq // P1006R1 constexpr For pointer_traits::pointer_to() +// P1007R3 assume_aligned() // P1023R0 constexpr For std::array Comparisons // P1024R3 Enhancing span Usability // P1032R1 Miscellaneous constexpr @@ -1142,6 +1143,7 @@ #define __cpp_lib_atomic_value_initialization 201911L #if _HAS_CXX20 +#define __cpp_lib_assume_aligned 201811L #define __cpp_lib_atomic_flag_test 201907L #define __cpp_lib_atomic_float 201711L #define __cpp_lib_atomic_lock_free_type_aliases 201907L diff --git a/tests/std/test.lst b/tests/std/test.lst index 2585db8b27f..e16a7b949fe 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -336,6 +336,7 @@ tests\P0898R3_identity tests\P0912R5_coroutine tests\P0919R3_heterogeneous_unordered_lookup tests\P0966R1_string_reserve_should_not_shrink +tests\P1007R3_assume_aligned tests\P1023R0_constexpr_for_array_comparisons tests\P1032R1_miscellaneous_constexpr tests\P1135R6_atomic_flag_test diff --git a/tests/std/tests/P1007R3_assume_aligned/env.lst b/tests/std/tests/P1007R3_assume_aligned/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/P1007R3_assume_aligned/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/P1007R3_assume_aligned/test.cpp b/tests/std/tests/P1007R3_assume_aligned/test.cpp new file mode 100644 index 00000000000..a878589d1fb --- /dev/null +++ b/tests/std/tests/P1007R3_assume_aligned/test.cpp @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +constexpr void can_change_value_via_assume_aligned(int* p) { + int* p1 = std::assume_aligned<256>(p); + p1[0] = 10; + p1[1] = -15; +} + +constexpr int can_read_value_via_assume_aligned_and_sum_it(int const* p, size_t size) { + int const* p1 = std::assume_aligned<256>(p); + int result = 0; + for (size_t i = 0; i < size; ++i) { + result += p1[i]; + } + return result; +} + +constexpr bool assume_aligned_can_change_value() { + alignas(256) int arr[2] = {0, 0}; + can_change_value_via_assume_aligned(&arr[0]); + assert(arr[0] == 10); + assert(arr[1] == -15); + return true; +} + +constexpr bool assume_aligned_can_read_value() { + alignas(256) constexpr int arr[3] = {10, 11, 9}; + assert(can_read_value_via_assume_aligned_and_sum_it(arr, 3) == 30); + return true; +} + +int main() { + assume_aligned_can_change_value(); + static_assert(assume_aligned_can_change_value()); + + assume_aligned_can_read_value(); + static_assert(assume_aligned_can_read_value()); +} diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp index 455494fdd26..e5b414e0895 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.cpp @@ -83,6 +83,20 @@ STATIC_ASSERT(__cpp_lib_array_constexpr == 201803L); STATIC_ASSERT(__cpp_lib_as_const == 201510L); #endif +#if _HAS_CXX20 +#ifndef __cpp_lib_assume_aligned +#error __cpp_lib_assume_aligned is not defined +#elif __cpp_lib_assume_aligned != 201811L +#error __cpp_lib_assume_aligned is not 201811L +#else +STATIC_ASSERT(__cpp_lib_assume_aligned == 201811L); +#endif +#else +#ifdef __cpp_lib_assume_aligned +#error __cpp_lib_assume_aligned is defined +#endif +#endif + #if _HAS_CXX20 #ifndef __cpp_lib_atomic_flag_test #error __cpp_lib_atomic_flag_test is not defined