diff --git a/experimental/bits/simd.h b/experimental/bits/simd.h index 4c893114f..6e40c6512 100644 --- a/experimental/bits/simd.h +++ b/experimental/bits/simd.h @@ -185,6 +185,53 @@ struct vector_aligned_tag } }; +namespace __proposed +{ +namespace { + enum _AlignmentType{ + _Unaligned, + _Vector, + _Element + }; + + template<_AlignmentType at> + struct _alignment_tag_selector{ + static_assert(at!=_Unaligned,"Unaligned reads are undefined behavior."); + }; + template<> + struct _alignment_tag_selector<_Element>{ + using type=element_aligned_tag; + }; + template<> + struct _alignment_tag_selector<_Vector>{ + using type=vector_aligned_tag; + }; +} + +template +struct aligned_tag +{ + template + static constexpr size_t _S_alignment = _Np; + + template + _GLIBCXX_SIMD_INTRINSIC static constexpr _Up* + _S_apply(_Up* __ptr){ + constexpr size_t _expected_vector_alignment=vector_aligned_tag::_S_alignment<_Tp,_Up>; + constexpr size_t _expected_element_alignment=element_aligned_tag::_S_alignment<_Tp,_Up>; + constexpr _AlignmentType _computed_at= + ((_Np % _expected_vector_alignment)==0) ? _Vector : + ((_Np % _expected_element_alignment)==0) ? _Element : _Unaligned; + using _result_tag=typename _alignment_tag_selector<_computed_at>::type; + return _result_tag::template _S_apply<_Tp,_Up>(__ptr); + } +}; + +template + inline constexpr aligned_tag<_Np> aligned = {}; + +} + template struct overaligned_tag { template @@ -193,7 +240,7 @@ template struct overaligned_tag template _GLIBCXX_SIMD_INTRINSIC static constexpr _Up* _S_apply(_Up* __ptr) - { return static_cast<_Up*>(__builtin_assume_aligned(__ptr, _Np)); } + { return __proposed::aligned_tag<_Np>::_S_apply(__ptr); } }; inline constexpr element_aligned_tag element_aligned = {}; @@ -203,6 +250,8 @@ inline constexpr vector_aligned_tag vector_aligned = {}; template inline constexpr overaligned_tag<_Np> overaligned = {}; + + // }}} template using _SizeConstant = integral_constant; diff --git a/tests/simple_tests/CMakeLists.txt b/tests/simple_tests/CMakeLists.txt new file mode 100644 index 000000000..c43e3557b --- /dev/null +++ b/tests/simple_tests/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.14) + +add_executable(alignment_compute alignment_compute.cpp) +target_compile_options(alignment_compute PUBLIC + "$<$:-march=native>" + "$<$:-march=native>" + "$<$:-march=native>" + "$<$:-march=native>" +) +set_target_properties(alignment_compute PROPERTIES + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED ON) + + message(WARNING "${CMAKE_CURRENT_SOURCE_DIR}/../..") +target_include_directories(alignment_compute PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") diff --git a/tests/simple_tests/alignment_compute.cpp b/tests/simple_tests/alignment_compute.cpp new file mode 100644 index 000000000..0a131fd6f --- /dev/null +++ b/tests/simple_tests/alignment_compute.cpp @@ -0,0 +1,28 @@ +#include + +#include +#include +#include +#include +#include + +#include +namespace stdx = std::experimental; + + +using uint8v_t = stdx::native_simd; +using uint8v_mask_t = stdx::native_simd_mask; +//using mask_cpu_t = min_uint_t::size()>; + + + +int main() +{ + std::array data; + uint8v_t hi(&data[0],stdx::__proposed::aligned<3>); + + std::array dataf; + stdx::native_simd vf(&dataf[0],stdx::__proposed::aligned<3>); + return 0; +} +