From ddbcdab5cf8881a1181ef8f15d434db9766f75d5 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Sat, 19 Sep 2020 03:40:15 +0700 Subject: [PATCH 1/6] enable std::assume_aligned --- stl/inc/memory | 15 +++++-- stl/inc/yvals_core.h | 2 + tests/std/test.lst | 1 + .../std/tests/P1007R3_assume_aligned/env.lst | 4 ++ .../std/tests/P1007R3_assume_aligned/test.cpp | 44 +++++++++++++++++++ .../VSO_0157762_feature_test_macros/test.cpp | 14 ++++++ 6 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 tests/std/tests/P1007R3_assume_aligned/env.lst create mode 100644 tests/std/tests/P1007R3_assume_aligned/test.cpp diff --git a/stl/inc/memory b/stl/inc/memory index 42ad7303c0e..58d8c576099 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3079,15 +3079,24 @@ 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 */ { +#if 1 // TRANSITION, DevCom-1190972 + if (_STD is_constant_evaluated()) { + return _Ptr; + } + (void) __builtin_assume_aligned(_Ptr, _Nx); + + return _Ptr; +#else // this enforces the requirement that _Nx be a power of two - __builtin_assume_aligned(_Ptr, _Nx); + (void) __builtin_assume_aligned(_Ptr, _Nx); return _Ptr; +#endif // TRANSITION, DevCom-1190972 } -#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..dc737430d98 --- /dev/null +++ b/tests/std/tests/P1007R3_assume_aligned/test.cpp @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +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_constexpr_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; +} + +void 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); +} + +constexpr void constexpr_assume_aligned_can_read_value() { + alignas(256) constexpr int arr[3] = {10, 11, 9}; + static_assert(can_read_constexpr_value_via_assume_aligned_and_sum_it(arr, 3) == 30); +} + +void assume_aligned_can_read_value() { + alignas(256) constexpr int arr[3] = {10, 11, 9}; + assert(can_read_constexpr_value_via_assume_aligned_and_sum_it(arr, 3) == 30); +} + +int main() { + assume_aligned_can_change_value(); + constexpr_assume_aligned_can_read_value(); + 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 From 5a15061003a72c5c76cd0cd27541a5d45d1da597 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 19 Sep 2020 00:20:27 -0700 Subject: [PATCH 2/6] Activate workaround for non-Clang, extract non-workaround. --- stl/inc/memory | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 58d8c576099..8caa3cf6238 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3082,19 +3082,16 @@ inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noe #if _HAS_CXX20 template _NODISCARD constexpr _Ty* assume_aligned(_Ty* _Ptr) noexcept /* strengthened */ { -#if 1 // TRANSITION, DevCom-1190972 +#ifndef __clang__ // TRANSITION, DevCom-1190972 if (_STD is_constant_evaluated()) { return _Ptr; } - (void) __builtin_assume_aligned(_Ptr, _Nx); +#endif // ^^^ workaround ^^^ - return _Ptr; -#else // this enforces the requirement that _Nx be a power of two (void) __builtin_assume_aligned(_Ptr, _Nx); return _Ptr; -#endif // TRANSITION, DevCom-1190972 } #endif // _HAS_CXX20 From fe96892d6d7dd1169f9973d6b5a50a166bc92f9c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 19 Sep 2020 00:58:09 -0700 Subject: [PATCH 3/6] Centralize constexpr testing, and test constexpr modification. --- .../std/tests/P1007R3_assume_aligned/test.cpp | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/std/tests/P1007R3_assume_aligned/test.cpp b/tests/std/tests/P1007R3_assume_aligned/test.cpp index dc737430d98..a878589d1fb 100644 --- a/tests/std/tests/P1007R3_assume_aligned/test.cpp +++ b/tests/std/tests/P1007R3_assume_aligned/test.cpp @@ -5,13 +5,13 @@ #include #include -void can_change_value_via_assume_aligned(int* p) { +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_constexpr_value_via_assume_aligned_and_sum_it(int const* p, size_t size) { +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) { @@ -20,25 +20,24 @@ constexpr int can_read_constexpr_value_via_assume_aligned_and_sum_it(int const* return result; } -void assume_aligned_can_change_value() { +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 void constexpr_assume_aligned_can_read_value() { +constexpr bool assume_aligned_can_read_value() { alignas(256) constexpr int arr[3] = {10, 11, 9}; - static_assert(can_read_constexpr_value_via_assume_aligned_and_sum_it(arr, 3) == 30); -} - -void assume_aligned_can_read_value() { - alignas(256) constexpr int arr[3] = {10, 11, 9}; - assert(can_read_constexpr_value_via_assume_aligned_and_sum_it(arr, 3) == 30); + assert(can_read_value_via_assume_aligned_and_sum_it(arr, 3) == 30); + return true; } int main() { assume_aligned_can_change_value(); - constexpr_assume_aligned_can_read_value(); + static_assert(assume_aligned_can_change_value()); + assume_aligned_can_read_value(); + static_assert(assume_aligned_can_read_value()); } From dc528edd2d7b935dc40bab064ef16599f3f8c88d Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sat, 19 Sep 2020 21:56:13 -0700 Subject: [PATCH 4/6] Update stl/inc/memory `assume_aligned` never modifies its parameter. --- stl/inc/memory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/memory b/stl/inc/memory index 8caa3cf6238..133892441c4 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3081,7 +3081,7 @@ inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noe #if _HAS_CXX20 template -_NODISCARD constexpr _Ty* assume_aligned(_Ty* _Ptr) noexcept /* strengthened */ { +_NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthened */ { #ifndef __clang__ // TRANSITION, DevCom-1190972 if (_STD is_constant_evaluated()) { return _Ptr; From 2f9cf9d4d056c725fec29e19b17df62a3c03306b Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Mon, 21 Sep 2020 07:56:12 +0700 Subject: [PATCH 5/6] use return value of __builtin_assume_aligned --- stl/inc/memory | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 133892441c4..c2677fb9673 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3082,16 +3082,11 @@ inline void* align(size_t _Bound, size_t _Size, void*& _Ptr, size_t& _Space) noe #if _HAS_CXX20 template _NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthened */ { -#ifndef __clang__ // TRANSITION, DevCom-1190972 if (_STD is_constant_evaluated()) { return _Ptr; + } else { + return static_cast<_Ty*>(__builtin_assume_aligned(_Ptr, _Nx)); } -#endif // ^^^ workaround ^^^ - - // this enforces the requirement that _Nx be a power of two - (void) __builtin_assume_aligned(_Ptr, _Nx); - - return _Ptr; } #endif // _HAS_CXX20 From 2a22d6127eb17174caeb21fe01a5ebd04d90a5f4 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 20 Sep 2020 18:55:14 -0700 Subject: [PATCH 6/6] Preserve comment. --- stl/inc/memory | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/memory b/stl/inc/memory index c2677fb9673..da4986bcda4 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3085,6 +3085,7 @@ _NODISCARD constexpr _Ty* assume_aligned(_Ty* const _Ptr) noexcept /* strengthen 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)); } }