Skip to content

Commit

Permalink
make stdx::sin work for float
Browse files Browse the repository at this point in the history
  • Loading branch information
iburylov committed May 13, 2020
1 parent 959de34 commit d50057f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
15 changes: 10 additions & 5 deletions experimental/bits/simd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ template <typename _Tp>
struct _VectorTraitsImpl<_Tp, enable_if_t<__is_vector_type_v<_Tp>>>
{
using type = _Tp;
using value_type = decltype(std::declval<_Tp>()[0]);
using value_type = std::remove_reference_t<decltype(std::declval<_Tp>()[0])>;
static constexpr int _S_width = sizeof(_Tp) / sizeof(value_type);
using _Wrapper = _SimdWrapper<value_type, _S_width>;
template <typename _Up, int _W = _S_width>
Expand Down Expand Up @@ -1610,11 +1610,16 @@ __or(_Tp __a, _Tp __b) noexcept

// }}}
// __and{{{
template <typename _Tp, typename _TVT = _VectorTraits<_Tp>, typename... _Dummy>
_GLIBCXX_SIMD_INTRINSIC constexpr _Tp
__and(_Tp __a, typename _TVT::type __b, _Dummy...) noexcept
template <typename _Tp>
constexpr auto __test_and_operator(int) -> decltype(_Tp() & _Tp(), std::true_type{});

template <typename _Tp>
constexpr std::false_type __test_and_operator(...);

template <typename _Tp, typename _TVT = _VectorTraits<_Tp>>
_GLIBCXX_SIMD_INTRINSIC constexpr std::enable_if_t<!decltype(__test_and_operator<_Tp>(0))::value, _Tp>
__and(_Tp __a, typename _TVT::type __b) noexcept

This comment has been minimized.

Copy link
@mattkretz

mattkretz May 14, 2020

Member

Seems like the disambiguation I used only works with GCC. Clang, MSVC, and ICC reject it. So this code might have relied on a bug in GCC.
The same issue is present for __andnot, _or, and __xor.

This comment has been minimized.

Copy link
@mattkretz

This comment has been minimized.

Copy link
@iburyl

iburyl May 14, 2020

That version added one more error in that example.

  using fixed_i32_3 = stdx::simd<int, stdx::simd_abi::_VecBuiltin<12>>;
  fixed_i32_3 i3 = 1;
  where(!(i3 > 0), i3) = 2;

Previously it fired on ! operator. Now it also fires in equal operator:

/std-simd/experimental/bits/simd_x86.h:701:18: error: no matching function for call to '__andnot'
        auto __r = __or(__andnot(__k, __at0), __and(__k, __at1));
                        ^~~~~~~~
/std-simd/experimental/bits/simd_builtin.h:2416:28: note: in instantiation of function template specialization 'std::experimental::parallelism_v2::_CommonImplX86::_S_blend<int, 3>' requested here
      __lhs = _CommonImpl::_S_blend(__k, __lhs,
                           ^
/std-simd/experimental/bits/simd.h:2967:12: note: in instantiation of function template specialization 'std::experimental::parallelism_v2::_SimdImplBuiltin<std::experimental::parallelism_v2::simd_abi::_VecBuiltin<12> >::__masked_assign<int, int, 3>' requested here
    _Impl::__masked_assign(__data(_M_k), __data(_M_value),
           ^
my_test.cpp:82:24: note: in instantiation of function template specialization 'std::experimental::parallelism_v2::where_expression<std::experimental::parallelism_v2::simd_mask<int, std::experimental::parallelism_v2::simd_abi::_VecBuiltin<12> >, std::experimental::parallelism_v2::simd<int, std::experimental::parallelism_v2::simd_abi::_VecBuiltin<12> > >::operator=<int>' requested here
  where(!(i3 > 0), i3) = 2;
                       ^
/std-simd/experimental/bits/simd.h:1746:1: note: candidate template ignored: requirement 'is_floating_point_v<int>' was not satisfied [with _TW = std::experimental::parallelism_v2::_SimdWrapper<int, 3, void>, _TVT = std::experimental::parallelism_v2::_VectorTraitsImpl<std::experimental::parallelism_v2::_SimdWrapper<int, 3, void>, void>, _Tp = int]
__andnot(
^
/std-simd/experimental/bits/simd.h:1773:1: note: candidate template ignored: substitution failure [with _Tp = std::experimental::parallelism_v2::_SimdWrapper<int, 3, void>]: invalid operands to binary expression ('std::experimental::parallelism_v2::_SimdWrapper<int, 3, void>::_BuiltinType' (aka 'std::experimental::parallelism_v2::__vector_type_n<int, 3, void>::type') and 'std::experimental::parallelism_v2::_SimdWrapper<int, 3, void>')
__andnot(_Tp __a, _Tp __b) noexcept
^

This comment has been minimized.

Copy link
@iburyl

iburyl May 14, 2020

And this example no longer working with the same equal sign error (while it worked previously with my workaround):

  using fixed_i32_32 = stdx::fixed_size_simd<int, 32>;
  fixed_i32_32 ia = -2;
  where(!(ia > 0), ia) = 2;

This comment has been minimized.

Copy link
@mattkretz

mattkretz May 14, 2020

Member

Ah, failed to consider _SimdWrapper arguments. Will fix.

This comment has been minimized.

Copy link
@mattkretz

mattkretz May 14, 2020

Member

This comment has been minimized.

Copy link
@mattkretz

mattkretz May 15, 2020

Member

One of the changes in here mattkretz/gcc@944522a is required to compile correctly.

This comment has been minimized.

Copy link
@iburyl

iburyl May 15, 2020

That resolved all issues with __andnot, thanks.

The next thing I'll dive deeper into is issue with long double.

{
static_assert(sizeof...(_Dummy) == 0);
using _Up = typename _TVT::value_type;
using _Ip = make_unsigned_t<__int_for_sizeof_t<_Up>>;
return __vector_bitcast<_Up>(__vector_bitcast<_Ip>(__a)
Expand Down
2 changes: 1 addition & 1 deletion experimental/bits/simd_builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -2116,7 +2116,7 @@ template <typename _Abi> struct _SimdImplBuiltin
const _V __absx = __and(__x, _S_absmask<_V>);
static_assert(CHAR_BIT * sizeof(1ull)
>= std::numeric_limits<value_type>::digits);
constexpr _V __shifter_abs
_GLIBCXX_SIMD_USE_CONSTEXPR _V __shifter_abs
= _V() + (1ull << (std::numeric_limits<value_type>::digits - 1));
const _V __shifter = __or(__and(_S_signmask<_V>, __x), __shifter_abs);
_V __shifted = __x + __shifter;
Expand Down

0 comments on commit d50057f

Please sign in to comment.