Closed fepicture closed 1 year ago
the 2 public API are not finish right now.
to_fixed_size/to_native/to_compatible and split/split_by/concat have been implemented.
abi scalar
specific type in short /unsigned short
? ex::simd<unsigned short, ex::simd_abi::scalar> a(static_cast<unsigned short>(42));
ex::simd<unsigned short, ex::simd_abi::scalar> b(static_cast<unsigned short>(4));
a %= b;
experimental/simd:694:
__simd/abi/scalar.h:48:71: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned short' in initializer list [-Wc++11-narrowing]
static _Simd __modulus(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data % __rhs.__data}; }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
experimental/simd:1868:19: note: in instantiation of member function 'std::experimental::__simd_traits<unsigned short, std::experimental::simd_abi::__scalar>::__modulus' requested here
return _Impl::__modulus(__lhs.__s_, __rhs.__s_);
^
experimental/simd:1904:91: note: in instantiation of member function 'std::experimental::operator%' requested here
friend simd& operator%=(simd& __lhs, const simd& __rhs) noexcept { return __lhs = __lhs % __rhs; }
^
libcxx/test/std/experimental/simd/simd.operators/operators.pass.cpp:300:5: note: in instantiation of member function 'std::experimental::operator%=' requested here
a %= b;
^
__simd/abi/scalar.h:48:71: note: insert an explicit cast to silence this issue
static _Simd __modulus(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data % __rhs.__data}; }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
static_cast<unsigned short>( )
1 error generated.
error: command failed with exit status: 1
in short : check + - * / % << >> | & ^ in abi::scalar impl function related things :
static _Simd __bitwise_or(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data | __rhs.__data}; }
* for unsigned short && short
__simd/abi/scalar.h:44:74: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned short' in initializer list [-Wc++11-narrowing]
static _Simd __multiplies(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data * __rhs.__data}; }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
experimental/simd:1860:19: note: in instantiation of member function 'std::experimental::__simd_traits<unsigned short, std::experimental::simd_abi::__scalar>::__multiplies' requested here
return _Impl::__multiplies(__lhs.__s_, __rhs.__s_);
^
experimental/simd:1900:91: note: in instantiation of member function 'std::experimental::operator*' requested here
friend simd& operator*=(simd& __lhs, const simd& __rhs) noexcept { return __lhs = __lhs * __rhs; }
^
% for unsigned short && short && char16_t && unsigned char && signed char
<< for unsigned short && short :
static _Simd __shift_left(_Simd __lhs, int __rhs) noexcept { return {__lhs.__data << __rhs}; }
>> for unsigned short && short
__simd/abi/scalar.h:58:75: error: non-constant-expression cannot be narrowed from type 'int' to 'unsigned short' in initializer list [-Wc++11-narrowing]
static _Simd __shift_right(_Simd __lhs, _Simd __rhs) noexcept { return {__lhs.__data >> __rhs.__data}; }
^ & | for short and unsigned short also
@joy2myself please take a look
the simd_cast
will do make_signed_t
check and call cast
, i am going to test the value_type and whole simd element.
static_assert(std::is_same_v<std::make_signed_t<unsigned long>, std::make_signed_t<long> >);
auto after_cast = ex::simd_cast<long>(ex::simd<unsigned long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};
static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
/llvm-project/libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp:173:1: error: static assertion failed
due to requirement
'std::is_same_v<std::experimental::simd<long, std::experimental::simd_abi::__builtin<1>>,
std::experimental::simd<long, std::experimental::simd_abi::__scalar>>':
static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
error: command failed with exit status: 1
--
current simd_cast work well for other simd_abi and type for simd_abi::scalar work well for same type cast:
auto after_cast = ex::simd_cast<long>(ex::simd< long, ex::simd_abi::scalar>());
auto expected = ex::simd<long, ex::simd_abi::scalar>{};
static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
[simd]simd_cast for abi::scalar && make_signed_t work fail
the
simd_cast
will domake_signed_t
check and callcast
, i am going to test the value_type and whole simd element.reproduce code:
static_assert(std::is_same_v<std::make_signed_t<unsigned long>, std::make_signed_t<long> >); auto after_cast = ex::simd_cast<long>(ex::simd<unsigned long, ex::simd_abi::scalar>()); auto expected = ex::simd<long, ex::simd_abi::scalar>{}; static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
error log:
/llvm-project/libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp:173:1: error: static assertion failed due to requirement 'std::is_same_v<std::experimental::simd<long, std::experimental::simd_abi::__builtin<1>>, std::experimental::simd<long, std::experimental::simd_abi::__scalar>>': static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, ""); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. error: command failed with exit status: 1 --
Additional
current simd_cast work well for other simd_abi and type for simd_abi::scalar work well for same type cast:
auto after_cast = ex::simd_cast<long>(ex::simd< long, ex::simd_abi::scalar>()); auto expected = ex::simd<long, ex::simd_abi::scalar>{}; static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
According to the spec, the static_simd_cast
will do make_signed_t
but simd_cast
will not.
the return type of simd_cast
is as follow:
The return type is — T if is_simd_v
is true; — otherwise, simd<T, Abi> if U is the same type as T; — otherwise, simd<T, simd_abi::fixed_size<simd<U, Abi>::size()>>
Thus, because long and unsigned long are not the same type, use Rule 3.
[simd]simd_cast for abi::scalar && make_signed_t work fail
the
simd_cast
will domake_signed_t
check and callcast
, i am going to test the value_type and whole simd element.reproduce code:
static_assert(std::is_same_v<std::make_signed_t<unsigned long>, std::make_signed_t<long> >); auto after_cast = ex::simd_cast<long>(ex::simd<unsigned long, ex::simd_abi::scalar>()); auto expected = ex::simd<long, ex::simd_abi::scalar>{}; static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
error log:
/llvm-project/libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp:173:1: error: static assertion failed due to requirement 'std::is_same_v<std::experimental::simd<long, std::experimental::simd_abi::__builtin<1>>, std::experimental::simd<long, std::experimental::simd_abi::__scalar>>': static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, ""); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. error: command failed with exit status: 1 --
Additional
current simd_cast work well for other simd_abi and type for simd_abi::scalar work well for same type cast:
auto after_cast = ex::simd_cast<long>(ex::simd< long, ex::simd_abi::scalar>()); auto expected = ex::simd<long, ex::simd_abi::scalar>{}; static_assert(std::is_same_v< decltype(after_cast), decltype(expected) >, "");
I tried to give a fix here https://github.com/joy2myself/llvm-project/commit/3e916c1fdf7ab6940235cbc0939f11e17dc326b4. But I have not tested it. If it works please reply to me. I will push it to this repo.
Here we cannot directly compare with scalar simd and other simd. But simd_mask works well for all abi and type. And without scalar simd, other simd still works well for comparsion.
const auto native_simd = ex::simd<long double, ex::simd_abi::native<long double>>();
const auto deduce_simd = ex::simd<long double, ex::simd_abi::deduce_t<double, 1>>();
const auto scalar_simd = ex::simd<long double, ex::simd_abi::scalar>();
auto equal_sub = native_simd == deduce_simd; // pass ,work well!
auto equal = native_simd == scalar_simd; // fail
# command stderr:
error: invalid operands to binary expression ('const ex::simd<long double, ex::simd_abi::native<long double>>' (aka 'const simd<long double, __builtin<16 / sizeof(long double)>>') and 'const ex::simd<long double, ex::simd_abi::scalar>' (aka 'const simd<long double, std::experimental::simd_abi::__scalar>'))
auto equal = native_simd == scalar_simd; // fail
~~~~~~~~~~~ ^ ~~~~~~~~~~~
build/include/c++/v1/experimental/simd:1863:20: note: candidate function not viable: no known conversion from 'const simd<[...], ex::simd_abi::scalar>' to 'const simd<[...], std::experimental::simd_abi::__builtin<1>>' for 2nd argument
friend mask_type operator==(const simd& __lhs, const simd& __rhs) noexcept {
^
build/include/c++/v1/experimental/simd:1863:20: note: candidate function not viable: no known conversion from 'const simd<[...], ex::simd_abi::native<long double>>' to 'const simd<[...], std::experimental::simd_abi::__scalar>' for 1st argument
1 error generated.
I assume mightbe the ex::concat
implement has some missing function?
Okay, I think here the implementation should assign value to ex::resize_simd::type
or ex::resize_simd_t
which is really one about ex::simd
{
using _Tp = int;
using SimdAbi = ex::simd_abi::native<int>;
constexpr size_t _Np = 2;
std::array<ex::simd<_Tp, SimdAbi>, _Np> arr;
auto temp = ex::concat<_Tp, SimdAbi, _Np>(arr);
std::cout <<TypeName<decltype(temp)>(); // do some thing with temp , even no this line still fail.
}
# command stderr:
In file included from libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp:17:
libcxx/test/std/experimental/simd/simd.casts/../test_utils.h:12:
experimental/simd:1271:7: error: type 'resize_simd<__size * 2UL, simd<int, __builtin<4>>>' does not provide a subscript operator
__s[__i * __size + __j] = __arr[__i][__j];
^~~ ~~~~~~~~~~~~~~~~~~
libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp:193:21: note: in instantiation of function template specialization 'std::experimental::concat<int, std::experimental::simd_abi::__builtin<4>, 2UL>' requested here
auto temp = ex::concat<_Tp, SimdAbi, _Np>(arr);
^
1 error generated.
{
using T = int;
using A = ex::simd_abi::native<int>;
constexpr size_t N = 2;
auto v = ex::simd<T, A>();
auto cur = ex::split_by<N, T, A>(v);
std::cout << cur.size()<<'\n';
}
# command stderr:
In file included from /libcxx/test/std/experimental/simd/simd.casts/split_by.pass.cpp:21:
In file included from /libcxx/test/std/experimental/simd/simd.casts/../test_utils.h:12:
/include/c++/v1/experimental/simd:1222:7: error: type 'value_type' (aka 'std::experimental::resize_simd<2, std::experimental::simd<int, std::experimental::simd_abi::__builtin<4>>>') does not provide a subscript operator
__arr[__i][__j] = __v[__i * __size + __j];
^~~~~~~~~~ ~~~
/libcxx/test/std/experimental/simd/simd.casts/split_by.pass.cpp:80:24: note: in instantiation of function template specialization 'std::experimental::split_by<2UL, int, std::experimental::simd_abi::__builtin<4>>' requested here
auto cur = ex::split_by<N, T, A>(v);
^
1 error generated.
Here we cannot directly compare with scalar simd and other simd.
"operator==" only has been overloaded in class simd & simd_mask. It should be used to compare values between two simd/simd_mask with the same type rather than different types.
And without scalar simd, other simd still works well for comparsion.
This is only because ABIs other than scalar temporarily use the same internal implementation in the current version. This does not mean that "operator==" needs to work between different types of simd.
Hi, I cannot find any sentence refer to this rule, shall we consider to check the vector alignment implementation?
I found there some comments to show the __builtin_assume_aligned
has built-in check for power-of-2
For your reference: https://github.com/plctlab/llvm-project/blob/simd_for_upstream/libcxx/test/libcxx/utilities/memory/ptr.align/assume_aligned.power2.verify.cpp
{
using _Tp = double;
using SimdAbi = ex::simd_abi::fixed_size<12>; // works fail!!
// @@@@@@@@@@@@@@@@@@@@@ here will set the simd size under this `abi`, but only work under `size is power of 2` with `vector_alignment`
// @ 1. generate simd with data by lambda
const ex::simd<_Tp, SimdAbi> origin_simd([](_Tp i) { return static_cast<_Tp>(i + 1); });
constexpr auto array_length = origin_simd.size();
constexpr auto alignas_size = get_next_pow2(ex::memory_alignment_v<ex::simd<_Tp, SimdAbi>, _Tp>);
// @ 2. declare an array with alignas position
alignas(alignas_size) _Tp expected_buffer[array_length]{};
// @ 3. test for copy to, which enable the array'data assignment with origin_simd value
origin_simd.copy_to(expected_buffer, ex::vector_aligned_tag());
for (size_t i = 0; i < origin_simd.size(); i++) assert(expected_buffer[i] == static_cast<_Tp>(i + 1));
// @ 4. test for copy from, using an empty simd to check value correct.
ex::simd<_Tp, SimdAbi> expected_simd;
expected_simd.copy_from(expected_buffer, ex::vector_aligned_tag());
for (size_t i = 0; i < origin_simd.size(); i++) assert(expected_simd[i] == static_cast<_Tp>(i + 1));
}
In file included from /libcxx/test/std/experimental/simd/simd.class/simd_copy.pass.cpp:17:
In file included from /libcxx/test/std/experimental/simd/simd.class/../test_utils.h:12:
/experimental/simd:899:4: error: requested alignment is not a power of 2
__builtin_assume_aligned(__ptr, __alignment<_Tp, _Up>));
^ ~~~~~~~~~~~~~~~~~~~~~
/simd:1753:43: note: in instantiation of function template specialization 'std::experimental::vector_aligned_tag::__apply<std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>, int>' requested here
_Impl::__store(__s_, _Flags::template __apply<simd>(__mem));
^
/simd/simd.class/simd_copy.pass.cpp:168:17: note: in instantiation of function template specialization 'std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>::copy_to<int, std::experimental::vector_aligned_tag>' requested here
origin_simd.copy_to(expected_buffer, ex::vector_aligned_tag());
^
In file included from /simd/simd.class/simd_copy.pass.cpp:17:
In file included from /simd/simd.class/../test_utils.h:12:
/experimental/simd:899:4: error: requested alignment is not a power of 2
__builtin_assume_aligned(__ptr, __alignment<_Tp, _Up>));
^ ~~~~~~~~~~~~~~~~~~~~~
/simd:1747:42: note: in instantiation of function template specialization 'std::experimental::vector_aligned_tag::__apply<std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>, const int>' requested here
_Impl::__load(__s_, _Flags::template __apply<simd>(__mem));
^
/simd/simd.class/simd_copy.pass.cpp:173:19: note: in instantiation of function template specialization 'std::experimental::simd<int, std::experimental::simd_abi::__builtin<12>>::copy_from<int, std::experimental::vector_aligned_tag>' requested here
expected_simd.copy_from(expected_buffer, ex::vector_aligned_tag());
^
2 errors generated.
seems there lack an convertion from ex::simd
to std::array
, mightbe we can try reinterpret_cast
{
ex::simd<int, ex::simd_abi::fixed_size<4>> origin_simd([](int i){return i;});
ex::simd<long , ex::simd_abi::fixed_size<4>> ctor_fail(origin_simd);
std::cout << ctor_fail.size()<<'\n';
return 0;
}
In file included from /libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp:19:
In file included from /libcxx/test/std/experimental/simd/simd.class/../test_utils.h:12:
/build/build/include/c++/v1/experimental/simd:1731:14: error: no matching conversion for static_cast from 'const simd<int, simd_abi::fixed_size<size()>>' (aka 'const simd<int, __builtin<4>>') to 'std::array<int, size()>'
: simd(static_cast<std::array<_Up, size()>>(__v).data(), vector_aligned) {}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/libcxx/test/std/experimental/simd/simd.class/simd_ctor.pass.cpp:225:50: note: in instantiation of function template specialization 'std::experimental::simd<long, std::experimental::simd_abi::__builtin<4>>::simd<int, void>' requested here
ex::simd<long , ex::simd_abi::fixed_size<4>> ctor_fail(origin_simd);
^
/build/build/include/c++/v1/array:150:29: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const simd<int, simd_abi::fixed_size<size()>>' (aka 'const simd<int, __builtin<4>>') to 'const std::array<int, 4>' for 1st argument
struct _LIBCPP_TEMPLATE_VIS array
^
/build/build/include/c++/v1/array:150:29: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'const simd<int, simd_abi::fixed_size<size()>>' (aka 'const simd<int, __builtin<4>>') to 'std::array<int, 4>' for 1st argument
/build/build/include/c++/v1/array:150:29: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
1 error generated.
the scalar
abi works fail , plz check the operator!
implementation
{
using _Tp = int;
using SimdAbi = ex::simd_abi::scalar;
const ex::simd<_Tp, SimdAbi> origin_simd([](_Tp i) { return i; });
const auto origin_mask = origin_simd.operator!();
for (size_t i = 0; i < origin_mask.size(); ++i) {
assert(origin_mask[i] == !origin_simd.operator[](i));
}
}
# command stderr:
In file included from test/std/experimental/simd/simd.class/simd_unary.pass.cpp:23:
In file included from test/std/experimental/simd/simd.class/../test_utils.h:12:
/experimental/simd:1784:49: error: no viable conversion from returned value of type '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to function return type 'mask_type' (aka 'simd_mask<int, std::experimental::simd_abi::__scalar>')
mask_type operator!() const noexcept { return _Impl::__negate(__s_); }
^~~~~~~~~~~~~~~~~~~~~
test/std/experimental/simd/simd.class/simd_unary.pass.cpp:122:44: note: in instantiation of member function 'std::experimental::simd<int, std::experimental::simd_abi::__scalar>::operator!' requested here
const auto origin_mask = origin_simd.operator!();
^
/experimental/simd:1890:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to 'const std::experimental::simd_mask<int, std::experimental::simd_abi::__scalar> &' for 1st argument
class simd_mask {
^
/experimental/simd:1890:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to 'std::experimental::simd_mask<int, std::experimental::simd_abi::__scalar> &&' for 1st argument
class simd_mask {
^
/experimental/simd:1938:3: note: candidate constructor not viable: no known conversion from '_Simd' (aka '__simd_storage<int, simd_abi::__scalar>') to '_Storage' (aka '__mask_storage<int, simd_abi::__scalar>') for 1st argument
simd_mask(_Storage __s) : __s_(__s) {}
^
/experimental/simd:1946:3: note: candidate template ignored: could not match 'simd_mask' against '__simd_storage'
simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>& __v) noexcept
^
/experimental/simd:1941:12: note: explicit constructor is not a candidate
explicit simd_mask(value_type __v) noexcept : __s_(_Impl::__broadcast(__v)) {}
^
1 error generated.
abi scalar with simd::operator!() works fail
Fixed.
simd ctor directly from abi fixed_size not work
Fixed.
vector alignment need simd size to be power of 2
Can not reproduce with https://github.com/fepicture/llvm-project/tree/simd_for_upstream
ex::resize_simd ex::concat(std::array) not work?
Can not reproduce with https://github.com/fepicture/llvm-project/tree/simd_for_upstream
Thank you~ I guess mightbe our compiler different? In my local which is the build-output
"/root/llvm-project/build/build/./bin/clang++" "/root/llvm-project/libcxx/test/std/experimental/simd/simd.casts/concat.pass.cpp"
ex::resize_simd ex::concat(std::array) not work?
I am using latest /llvm-project/.gitlab-ci.yml to test. In my local, it will still report error same as above.
does there exist subscript operator for ex::resize_simd
implement?
{
std::array<ex::simd<int, ex::simd_abi::native<int>>, 2> arr;
const auto temp(ex::concat<int, ex::simd_abi::native<int>, 2>(arr));
}
vector alignment need simd size to be power of 2
still fail
const ex::simd<double, ex::simd_abi::fixed_size<12>> origin_simd([](double i) { return static_cast<double>(i + 1); });
constexpr auto array_length = origin_simd.size();
constexpr auto alignas_size = (ex::memory_alignment_v<ex::simd<double, ex::simd_abi::fixed_size<16>>, double>);
alignas(alignas_size) double expected_buffer[array_length]{};
origin_simd.copy_to(expected_buffer, ex::vector_aligned_tag());
for (size_t i = 0; i < origin_simd.size(); i++) assert(expected_buffer[i] == static_cast<double>(i + 1));
vector alignment need simd size to be power of 2
ex::resize_simd ex::concat(std::array) not work?
There are no such fails turning out from the tests. Have you not submitted the code that triggered the relevant error to the test file or commented out the relevant test codes?
maybe there still exist error in concat
and split_by
?
build/include/c++/v1/experimental/simd:1277:11: error: cannot refer to type member 'type' in 'resize_simd<__size * 1UL, simd<int, __builtin<4>>>' with '.'
__s.type[__i * __size + __j] = __arr[__i][__j];
// simd:1765
template <class _Up,
class = std::enable_if_t<
std::is_same_v<abi_type, simd_abi::fixed_size<size()>> &&
__is_non_narrowing_arithmetic_convertible<_Up, value_type>()>>
simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v)
noexcept { ... skip other code ... }
// utility.h:38
template <class _From, class _To>
constexpr bool __is_non_narrowing_arithmetic_convertible() {
if constexpr(std::is_arithmetic_v<_To> && std::is_arithmetic_v<_From>)
return __is_non_narrowing_convertible_impl<_To>(_From{});
}
template <class _To, class _From>
constexpr decltype(_To{std::declval<_From>()}, true)
__is_non_narrowing_convertible_impl(_From){return true;}
template <class _To>
constexpr bool
__is_non_narrowing_convertible_impl(...) {return false;}
I strongly doubt the weird issue is due to the narrow convert
work not well
and write a small code to test:
{
using _Tp = unsigned long;
std::cout <<"from = char "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<char, _Tp>() <<" is std::converti = "<<std::is_convertible_v<char, _Tp><<"\n";
std::cout <<"from = short "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<short, _Tp>() <<" is std::converti = "<<std::is_convertible_v<short, _Tp><<"\n";
std::cout <<"from = wchar_t "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<wchar_t, _Tp>() <<" is std::converti = "<<std::is_convertible_v<wchar_t, _Tp><<"\n";
std::cout <<"from = char16_t "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<char16_t, _Tp>()<<" is std::converti = "<<std::is_convertible_v<char16_t, _Tp><<"\n";
std::cout <<"from = int "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<int, _Tp>() <<" is std::converti = "<<std::is_convertible_v<int, _Tp><<"\n";
std::cout <<"from = char32_t "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<char32_t, _Tp>()<<" is std::converti = "<<std::is_convertible_v<char32_t, _Tp><<"\n";
std::cout <<"from = long "<< "to = unsigned long "<<" ex::is non_narrow convertible = "<< __is_non_narrowing_arithmetic_convertible<long, _Tp>() <<" is std::converti = "<<std::is_convertible_v<long, _Tp><<"\n";
}
test result shows below:
from = char to = unsigned long ex::is non_narrow convertible = 0 is std::converti = 1
from = short to = unsigned long ex::is non_narrow convertible = 0 is std::converti = 1
from = wchar_t to = unsigned long ex::is non_narrow convertible = 0 is std::converti = 1
from = char16_t to = unsigned long ex::is non_narrow convertible = 1 is std::converti = 1
from = int to = unsigned long ex::is non_narrow convertible = 0 is std::converti = 1
from = char32_t to = unsigned long ex::is non_narrow convertible = 1 is std::converti = 1
from = long to = unsigned long ex::is non_narrow convertible = 0 is std::converti = 1
Hi all, in this open issue, I will point out some missing implementations of ex::simd.
[simd] (under 9.7.5casts)
concat
implement not finishIn the
simd
code comment or wg21 draft, I notice there have four kinds ofconcat
function implemented (with different input/output)code comment: https://github.com/plctlab/llvm-project/blob/simd_for_upstream/libcxx/include/experimental/simd#L121-L131
but there still lack 2 implement with concat(std::array\<nested with ex::simd or ex::simd_mask>) see current implement: https://github.com/plctlab/llvm-project/blob/simd_for_upstream/libcxx/include/experimental/simd#L1268-L1282
code to reproduce
error log