[PATCH] D79515: [CUDA] Enable existing builtins for PTX7.0 as well.

2020-05-06 Thread Tim Shen via Phabricator via cfe-commits
timshen accepted this revision.
timshen added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/test/CodeGen/builtins-nvptx-ptx60.cu:6
 // RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_80 \
-// RUN:-fcuda-is-device -target-feature +ptx65 \
+// RUN:-fcuda-is-device -target-feature +ptx70 \
 // RUN:-S -emit-llvm -o - -x cuda %s \

Keep ptx65 as well?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79515/new/

https://reviews.llvm.org/D79515



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73237: [CUDA] Fix order of memcpy arguments in __shfl_*(<64-bit type>).

2020-01-23 Thread Tim Shen via Phabricator via cfe-commits
timshen accepted this revision.
timshen added a comment.
This revision is now accepted and ready to land.

What's the test situation for these headers?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73237/new/

https://reviews.llvm.org/D73237



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41412: [libcxx] implement concat() and split()

2019-07-18 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

Tobias,

I spoke to @EricWF who is willing to take a look at all these patches. However, 
I don't know when exactly will the review starts.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D41412/new/

https://reviews.llvm.org/D41412



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41412: [libcxx] implement concat() and split()

2019-07-16 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

In D41412#1586966 , @grosser wrote:

> Hi @timshen,
>
> I am very interested in these patches. Any chance you can take up the 
> upstreaming process again?


I'm glad to spend time upstreaming these patches. Now we just need a libc++ 
maintainer to take on the reviews. I'll try to contact mclow, but I'm not sure 
how exactly to reach Marshall.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D41412/new/

https://reviews.llvm.org/D41412



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60279: [CUDA] Implemented _[bi]mma* builtins.

2019-04-05 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:12884
+// Helper classes for mapping MMA builtins to particular LLVM intrinsic 
variant.
+class NVPTXMmaLdstInfo {
+public:

How about having a simple struct and a function?
```
struct NvptxMmaLdstInfo {
  unsigned NumResults;
  unsigned IID_col;
  unsigned IID_row;
};

NvptxMmaLdstInfo getNvptxMmaLdstInfo(unsigned BuiltinID) { ... }
```

I don't see the need for classes here.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:13020
+
+class NVPTXMmaInfo {
+private:

ditto (struct + function)?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60279/new/

https://reviews.llvm.org/D60279



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51354: Fix the -print-multi-directory flag to print the selected multilib.

2018-09-04 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

> The test fails on my system like so:

I also observed the same failure.

Bots also fail: 
http://lab.llvm.org:8011/builders/clang-x86_64-linux-selfhost-modules/builds/19509/steps/check-all/logs/FAIL%3A%20Clang%3A%3Aprint-multi-directory.c

I'm going to revert this patch.


Repository:
  rC Clang

https://reviews.llvm.org/D51354



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50534: [libc++] Fix handling of negated character classes in regex

2018-08-10 Thread Tim Shen via Phabricator via cfe-commits
timshen accepted this revision.
timshen added a comment.
This revision is now accepted and ready to land.

That looks more correct to me, thanks! Although I'm still puzzled by the empty 
check at all, it's clearly an improvement.


Repository:
  rCXX libc++

https://reviews.llvm.org/D50534



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50534: [libc++] Fix handling of negated character classes in regex

2018-08-09 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

I'm not fully equipped with the context right now, but something doesn't add 
up. if `__neg_chars_.empty()` check is removed, the `(__neg_mask_ == 0)` above 
should be removed too. They have to be consistent.

However, there is more weirdness in it. The comment above describes the 
intention:

  union(complement(union(__neg_chars_, __neg_mask_)), other cases...)

With the `__neg_chars_.empty()` and `(__neg_mask_ == 0)` removed, I believe 
that the code exactly matches the comment. Let's see what happens when users 
don't specify any negative class or chars. __neg_chars_ and __neg_mask_ will be 
empty sets, and `union(complement(union(__neg_chars_, __neg_mask_)), other 
cases...)` always evaluate to true, which means it always matches all 
characters. This can't be right.

It's likely that the comment description doesn't fully describe the intended 
behavior. I think we need to figure that out first.


Repository:
  rCXX libc++

https://reviews.llvm.org/D50534



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41412: [libcxx] implement concat() and split()

2018-07-30 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

A note on test cases: I only used simds ints to test split() and concat(), as 
both functions don't specialize on the element type, unlike the constructors.




Comment at: libcxx/include/experimental/simd:1491
 
-  template 
+  template 
   static constexpr decltype(

mclow.lists wrote:
> I see no change here other than fixing a typo - correct?
That is correct.



Comment at: libcxx/include/experimental/simd:1630
+
+#if !defined(_LIBCPP_HAS_NO_VECTOR_EXTENSION) && 
defined(_LIBCPP_COMPILER_CLANG)
+  template 

mclow.lists wrote:
> In general, we try to keep all the compiler-specific bits in `<__config>`. 
> They tend to grow/mutate over time, and so it's nice to have them all in one 
> place.
> 
> Better to define something like `_LIBCPP_HAS_BUILTIN_SHUFFLEVECTOR` and use 
> that; then if GCC gets religion and adds it, you will only have to update a 
> single place.  Also, it makes the reading easier - no more looking at this 
> and wondering "Why are you requiring clang here?"
> 
> Is this the only place you plan on using `__simd_shuffle`? If so, why not a 
> member function.
GCC already got religion and had it, but in a radically different interface. 
There is little chance that they will merge the interface in the future.

The GCC one is called __builtin_shuffle 
(https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html). I haven't added it 
only because I don't care about the performance on GCC.

It's rather non-trivial to eliminate the difference between them, certainly 
more than a macro like _LIBCPP_HAS_BUILTIN_SHUFFLEVECTOR.

Do you have any other way to improve the readability?


https://reviews.llvm.org/D41412



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41412: [libcxx] implement concat() and split()

2018-07-30 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 158092.
timshen marked 2 inline comments as done.
timshen edited the summary of this revision.
timshen added a comment.

Update based on comments.


https://reviews.llvm.org/D41412

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -0,0 +1,128 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// tuple>...> split(const simd&);
+//
+// template 
+// tuple>...> split(const simd_mask&);
+//
+// template 
+// array / V::size()> split(
+// const simd&);
+//
+// template 
+// array / V::size()> split(
+// const simd_mask&);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd& x);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd_mask& x);
+
+#include 
+#include 
+#include 
+
+namespace ex = std::experimental::parallelism_v2;
+
+void test_split() {
+  auto t =
+  ex::split<1, 2, 3>(ex::fixed_size_simd([](int i) { return i; }));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0] == 0);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0] == 1);
+  assert(std::get<1>(t)[1] == 2);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0] == 3);
+  assert(std::get<2>(t)[1] == 4);
+  assert(std::get<2>(t)[2] == 5);
+}
+
+void test_split_array() {
+  {
+auto arr =
+ex::split_by<2>(ex::fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+  {
+auto arr = ex::split>(
+ex::fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+}
+
+void compile_split_propagate_abi() {
+  using compatible_simd_half =
+  ex::simd::size() / 2,
+ ex::simd_abi::compatible>>;
+  using native_simd_half =
+  ex::simd::size() / 2,
+ ex::simd_abi::native>>;
+
+  static_assert(
+  std::is_same<
+  decltype(ex::split::size() / 2,
+ ex::simd::size() / 2>(ex::simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same::size() / 2,
+  ex::native_simd::size() / 2>(
+   ex::native_simd())),
+   std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(ex::simd())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(ex::native_simd())),
+ std::array>::value,
+"");
+}
+
+int main() {
+  test_split();
+  test_split_array();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
@@ -0,0 +1,99 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// simd + ...)>>
+// concat(const simd&...);
+//
+// template 
+// simd, Abi>>
+// concat(const std::array, N>& __v);
+//
+// template 
+// simd_mask + ...)>>
+// concat(const simd_mask&...);
+//
+// template 
+// simd_mask, Abi>>
+// concat(const std::array, N>&);
+
+#include 
+#include 
+#include 
+
+namespace ex = std::experimental::parallelism_v2;
+
+void test_concat() {
+  auto v = ex::concat(ex::fixed_size_simd([](int i) { return i; }),
+  ex::fixed_size_simd([](int i) { 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-30 Thread Tim Shen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL338309: [libcxx] implement simd ABI for Clang/GCC 
vector extension, constructors… (authored by timshen, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D41376?vs=158038=158071#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41376

Files:
  libcxx/trunk/include/__config
  libcxx/trunk/include/experimental/__config
  libcxx/trunk/include/experimental/simd
  libcxx/trunk/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.cons/generator.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.mem/store.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/trunk/include/experimental/__config
===
--- libcxx/trunk/include/experimental/__config
+++ libcxx/trunk/include/experimental/__config
@@ -64,4 +64,11 @@
 #define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD_ABI \
 } _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
 
+// TODO: support more targets
+#if defined(__AVX__)
+#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32
+#else
+#define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16
+#endif
+
 #endif
Index: libcxx/trunk/include/experimental/simd
===
--- libcxx/trunk/include/experimental/simd
+++ libcxx/trunk/include/experimental/simd
@@ -651,6 +651,7 @@
 */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -664,23 +665,241 @@
 enum class _StorageKind {
   _Scalar,
   _Array,
+  _VecExt,
 };
 
 template <_StorageKind __kind, int _Np>
 struct __simd_abi {};
 
 template 
-struct __simd_storage_traits {};
+class __simd_storage {};
 
 template 
-struct __simd_storage_traits<_Tp,
- __simd_abi<_StorageKind::_Array, __num_element>> {
-  using type = std::array<_Tp, __num_element>;
+class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> {
+  std::array<_Tp, __num_element> __storage_;
+
+  template 
+  friend struct simd;
+
+  template 
+  friend struct simd_mask;
+
+public:
+  _Tp __get(size_t __index) const noexcept { return __storage_[__index]; };
+  void __set(size_t __index, _Tp __val) noexcept {
+__storage_[__index] = __val;
+  }
 };
 
 template 
-struct __simd_storage_traits<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
-  using type = _Tp;
+class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> {
+  _Tp __storage_;
+
+  template 
+  friend struct simd;
+
+  template 
+  friend struct simd_mask;
+
+public:
+  _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; };
+  void __set(size_t __index, _Tp __val) noexcept {
+(&__storage_)[__index] = __val;
+  }
+};
+
+#ifndef _LIBCPP_HAS_NO_VECTOR_EXTENSION
+
+constexpr size_t __floor_pow_of_2(size_t __val) {
+  return ((__val - 1) & __val) == 0 ? __val
+: __floor_pow_of_2((__val - 1) & __val);
+}
+
+constexpr size_t __ceil_pow_of_2(size_t __val) {
+  return __val == 1 ? 1 : __floor_pow_of_2(__val - 1) << 1;
+}
+
+template 
+struct __vec_ext_traits {
+#if !defined(_LIBCPP_COMPILER_CLANG)
+  typedef _Tp type __attribute__((vector_size(__ceil_pow_of_2(__bytes;
+#endif
+};
+
+#if defined(_LIBCPP_COMPILER_CLANG)
+#define _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT)\
+  template <>  \
+  struct __vec_ext_traits<_TYPE, sizeof(_TYPE) * _NUM_ELEMENT> {   \
+using type =   \
+_TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT)));  \
+  }
+
+#define _LIBCPP_SPECIALIZE_VEC_EXT_32(_TYPE)   \
+  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 1);\
+  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 2);\
+  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 3);\
+  _LIBCPP_SPECIALIZE_VEC_EXT(_TYPE, 4); 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-30 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: libcxx/include/experimental/simd:703
+public:
+  _Tp __get(size_t __index) const { return (&__storage_)[__index]; };
+  void __set(size_t __index, _Tp __val) { (&__storage_)[__index] = __val; }

mclow.lists wrote:
> Can these (`__get` and `__set`) be noexcept? Obviously, it depends on `_Tp`.
Currently _Tp is always a subset of arithmetic type, so it's safe to say 
noexcept. Added them, as they may help with -O0 performance.



Comment at: libcxx/include/experimental/simd:811
+class __simd_reference {
+  static_assert(std::is_same<_Vp, _Tp>::value, "");
+

mclow.lists wrote:
> If `_Vp` and `_Tp` have to name the same type, why have two of them?
> What is the difference, and when would you use each one internally?
> 
> __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index);
> vs.
> __simd_reference operator=(_Vp __value) &&;
> 
> If _Vp and _Tp have to name the same type, why have two of them?

Currently there is no difference. It's going to be different when simd_mask is 
implemented (_Vp can be bool, but _Tp may not be).

> What is the difference, and when would you use each one internally?

This is not an internal class. This is part of the interface. IIRC since 
P0214R9 opreator=() is changed to something. In a later patch operator=() 
should be implemented as R9 specified.


https://reviews.llvm.org/D41376



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-30 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 158038.
timshen marked 2 inline comments as done.
timshen added a comment.

Update based on comments.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/generator.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -7,127 +7,146 @@
 //
 //===--===//
 
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
 
 // 
 //
 // [simd.traits]
-// template  struct is_simd_mask;
-// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+// template  struct ex::is_simd_mask;
+// template  inline constexpr bool ex::is_simd_mask_v =
+// ex::is_simd_mask::value;
 
 #include 
 #include 
 #include "test_macros.h"
 
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
 
 struct UserType {};
 
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert(!is_simd_mask::value, "");
-static_assert(!is_simd_mask::value, "");
-static_assert(!is_simd_mask::value, "");
-static_assert(!is_simd_mask>::value, "");
-static_assert(!is_simd_mask>::value, "");
-static_assert(!is_simd_mask::value, "");
-
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
-
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-27 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: libcxx/include/experimental/simd:1341
 // [simd.class]
 // TODO: implement simd
 template 

timshen wrote:
> mclow.lists wrote:
> > Is this TODO still necessary?
> I think so, as some operations are still not implemented, for example 
> operator++().
For test coverage I turned many of the tests into templates, in the hope not to 
duplicate the text and increase the coverage. I'm not sure if you like the idea.


https://reviews.llvm.org/D41376



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-27 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

I'm not going to rebase all the succeeding patches immediately onto this one, 
as it is painful and spamming emails. Rather, I'll only rebase the next patch 
in the line. So if you review more than one patch ahead (as you already did), 
you may see some stale patch context.


https://reviews.llvm.org/D41376



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-27 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: libcxx/include/experimental/simd:726
+#if defined(_LIBCPP_COMPILER_CLANG)
+#define _SPECIALIZE_VEC_EXT(_TYPE, _NUM_ELEMENT)   
\
+  template <>  
\

mclow.lists wrote:
> When we define user-visible macros in libc++, we prepend them with _LIBCPP_ 
> to avoid collisions.
> Accordingly, `_SPECIALIZE_VEC_EXT` should be named 
> `_LIBCPP_SPECIALIZE_VEC_EXT`
> 
Well _SPECIALIZE_VEC_EXT and _SPECIALIZE_VEC_EXT_32 are not user-visible, as 
they are (1) '#undef'ed after all uses, and (2) they start with underscore, so 
don't collide with existing user-defined macros.



Comment at: libcxx/include/experimental/simd:1341
 // [simd.class]
 // TODO: implement simd
 template 

mclow.lists wrote:
> Is this TODO still necessary?
I think so, as some operations are still not implemented, for example 
operator++().



Comment at: libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp:21
+using namespace std::experimental::parallelism_v2;
+
+int main() { (void)native_simd(); }

mclow.lists wrote:
> Do we need any other ctors tested here? `fixed_size_simd` for 
> example?
> Are there any post-conditions on the object created?
> 
> calling `size()` for example?
> 
Yes. Added more.

The test space is large and it's hard to test everything. I went "every line of 
the implementation should be covered" standard with myself, and only had 
native_simd's default ctor. fixed_size_simd<>'s ctor is exactly implemented by 
the same line, so I didn't bother.

But now the attention is already raised, it doesn't hurt to add more tests.



Comment at: libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp:21
+using namespace std::experimental::parallelism_v2;
+
+int main() { (void)native_simd(); }

timshen wrote:
> mclow.lists wrote:
> > Do we need any other ctors tested here? `fixed_size_simd` for 
> > example?
> > Are there any post-conditions on the object created?
> > 
> > calling `size()` for example?
> > 
> Yes. Added more.
> 
> The test space is large and it's hard to test everything. I went "every line 
> of the implementation should be covered" standard with myself, and only had 
> native_simd's default ctor. fixed_size_simd<>'s ctor is exactly implemented 
> by the same line, so I didn't bother.
> 
> But now the attention is already raised, it doesn't hurt to add more tests.
Yes, size() is the post-condition. There is not much beyond that - the elements 
are not even value initialized.


https://reviews.llvm.org/D41376



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-07-27 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 157751.
timshen marked 6 inline comments as done.
timshen added a comment.

Update based on the comments.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/generator.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -7,127 +7,146 @@
 //
 //===--===//
 
-// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: c++98, c++03, c++11, c++14
 
 // 
 //
 // [simd.traits]
-// template  struct is_simd_mask;
-// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+// template  struct ex::is_simd_mask;
+// template  inline constexpr bool ex::is_simd_mask_v =
+// ex::is_simd_mask::value;
 
 #include 
 #include 
 #include "test_macros.h"
 
-using namespace std::experimental::parallelism_v2;
+namespace ex = std::experimental::parallelism_v2;
 
 struct UserType {};
 
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-static_assert( is_simd_mask>::value, "");
-
-static_assert(!is_simd_mask::value, "");
-static_assert(!is_simd_mask::value, "");
-static_assert(!is_simd_mask::value, "");
-static_assert(!is_simd_mask>::value, "");
-static_assert(!is_simd_mask>::value, "");
-static_assert(!is_simd_mask::value, "");
-
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
-
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");
-static_assert( is_simd_mask_v>, "");

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-05-22 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 148062.
timshen added a comment.
Herald added a subscriber: bixia.

Chatted with Marshall a bit, we thought that it's bad for toolchain portability 
to support a C++17 library in C++11, especially with modifications w.r.t 
std::plus<>.

Remove the backport of std::integer_sequence to C++11.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/generator.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,92 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,118 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-04-23 Thread Tim Shen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL330627: [libcxx] implement experimental/simd 
declarations based on P0214R7. (authored by timshen, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D41148?vs=143610=143611#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41148

Files:
  libcxx/trunk/include/experimental/__config
  libcxx/trunk/include/experimental/simd
  libcxx/trunk/include/module.modulemap
  libcxx/trunk/test/libcxx/double_include.sh.cpp
  libcxx/trunk/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.cons/genertor.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/trunk/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/trunk/include/module.modulemap
===
--- libcxx/trunk/include/module.modulemap
+++ libcxx/trunk/include/module.modulemap
@@ -550,6 +550,10 @@
   header "experimental/regex"
   export *
 }
+module simd {
+  header "experimental/simd"
+  export *
+}
 module set {
   header "experimental/set"
   export *
Index: libcxx/trunk/include/experimental/simd
===
--- libcxx/trunk/include/experimental/simd
+++ libcxx/trunk/include/experimental/simd
@@ -0,0 +1,1285 @@
+// -*- C++ -*-
+//===--- simd -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+#ifndef _LIBCPP_EXPERIMENTAL_SIMD
+#define _LIBCPP_EXPERIMENTAL_SIMD
+
+/*
+experimental/simd synopsis
+
+namespace std::experimental {
+
+inline namespace parallelism_v2 {
+
+namespace simd_abi {
+
+struct scalar {};
+template  struct fixed_size {};
+template  inline constexpr int max_fixed_size = implementation-defined;
+template  using compatible = implementation-defined;
+template  using native = implementation-defined;
+
+} // simd_abi
+
+struct element_aligned_tag {};
+struct vector_aligned_tag {};
+template  struct overaligned_tag {};
+inline constexpr element_aligned_tag element_aligned{};
+inline constexpr vector_aligned_tag vector_aligned{};
+template  inline constexpr overaligned_tag overaligned{};
+
+// traits [simd.traits]
+template  struct is_abi_tag;
+template  inline constexpr bool is_abi_tag_v = is_abi_tag::value;
+
+template  struct is_simd;
+template  inline constexpr bool is_simd_v = is_simd::value;
+
+template  struct is_simd_mask;
+template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+template  struct is_simd_flag_type;
+template  inline constexpr bool is_simd_flag_type_v = is_simd_flag_type::value;
+
+template  struct abi_for_size { using type = see below; };
+template  using abi_for_size_t = typename abi_for_size::type;
+
+template > struct simd_size;
+template >
+inline constexpr size_t simd_size_v = simd_size::value;
+
+template  struct memory_alignment;
+template 
+inline constexpr size_t memory_alignment_v = memory_alignment::value;
+
+// class template simd [simd.class]
+template > class simd;
+template  using native_simd = simd;
+template  using fixed_size_simd = simd;
+
+// class template simd_mask [simd.mask.class]
+template > class simd_mask;
+template  using native_simd_mask = simd_mask;
+template  using fixed_size_simd_mask = simd_mask;
+
+// casts [simd.casts]
+template  see below simd_cast(const simd&);
+template  see below static_simd_cast(const simd&);
+
+template 
+fixed_size_simd> to_fixed_size(const simd&) noexcept;
+template 
+fixed_size_simd_mask> to_fixed_size(const simd_mask&) noexcept;
+template  native_simd to_native(const fixed_size_simd&) noexcept;
+template 
+native_simd_mask to_native(const fixed_size_simd_mask> &) noexcept;
+template  simd to_compatible(const fixed_size_simd&) noexcept;
+template  simd_mask to_compatible(const fixed_size_simd_mask&) noexcept;
+
+template 
+tuple...> split(const simd&);

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-04-23 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 143610.
timshen added a comment.

Update formatting on static_asserts.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/module.modulemap
  libcxx/test/libcxx/double_include.sh.cpp
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/genertor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,133 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+struct UserType {};
+
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+static_assert( is_simd_mask::value, "");
+
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+static_assert( is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-04-06 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 141436.
timshen marked an inline comment as done.
timshen added a comment.

Update file comments copy-paste error.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/module.modulemap
  libcxx/test/libcxx/double_include.sh.cpp
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/genertor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,133 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+struct UserType {};
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");

[PATCH] D44659: [libcxx] Optimize -O0 performance for operators

2018-04-05 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 141189.
timshen added a comment.

Also optimize -O0 load and stores by using memcpy.


https://reviews.llvm.org/D44659

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
@@ -64,136 +64,138 @@
 
 using namespace std::experimental::parallelism_v2;
 
+template 
 void test_pure_operators() {
   {
-native_simd a(42), b(4);
+SimdType a(42), b(4);
 
-assert(all_of(~a == native_simd(~42)));
+assert(all_of(~a == SimdType(~42)));
 assert(all_of(+a == a));
-assert(all_of(-a == native_simd(-42)));
-assert(all_of(a + b == native_simd(42 + 4)));
-assert(all_of(a - b == native_simd(42 - 4)));
-assert(all_of(a * b == native_simd(42 * 4)));
-assert(all_of(a / b == native_simd(42 / 4)));
-assert(all_of(a % b == native_simd(42 % 4)));
-assert(all_of((a & b) == native_simd(42 & 4)));
-assert(all_of((a | b) == native_simd(42 | 4)));
-assert(all_of((a ^ b) == native_simd(42 ^ 4)));
-assert(all_of((a << b) == native_simd(42 << 4)));
-assert(all_of((a >> b) == native_simd(42 >> 4)));
-assert(all_of((a << 4) == native_simd(42 << 4)));
-assert(all_of((a >> 4) == native_simd(42 >> 4)));
+assert(all_of(-a == SimdType(-42)));
+assert(all_of(a + b == SimdType(42 + 4)));
+assert(all_of(a - b == SimdType(42 - 4)));
+assert(all_of(a * b == SimdType(42 * 4)));
+assert(all_of(a / b == SimdType(42 / 4)));
+assert(all_of(a % b == SimdType(42 % 4)));
+assert(all_of((a & b) == SimdType(42 & 4)));
+assert(all_of((a | b) == SimdType(42 | 4)));
+assert(all_of((a ^ b) == SimdType(42 ^ 4)));
+assert(all_of((a << b) == SimdType(42 << 4)));
+assert(all_of((a >> b) == SimdType(42 >> 4)));
+assert(all_of((a << 4) == SimdType(42 << 4)));
+assert(all_of((a >> 4) == SimdType(42 >> 4)));
   }
   {
-native_simd a([](int i) { return 2 * i + 1; }),
-b([](int i) { return i + 1; });
+SimdType a([](int i) { return 2 * i + 1; }), b([](int i) { return i + 1; });
 
-assert(all_of(~a == native_simd([](int i) { return ~(2 * i + 1); })));
+assert(all_of(~a == SimdType([](int i) { return ~(2 * i + 1); })));
 assert(all_of(+a == a));
-assert(all_of(-a == native_simd([](int i) { return -(2 * i + 1); })));
-assert(all_of(a + b == native_simd([](int i) { return 3 * i + 2; })));
-assert(all_of(a - b == native_simd([](int i) { return i; })));
-assert(all_of(a * b == native_simd(
-   [](int i) { return (2 * i + 1) * (i + 1); })));
-assert(all_of(a / b == native_simd(
-   [](int i) { return (2 * i + 1) / (i + 1); })));
-assert(all_of(a % b == native_simd(
-   [](int i) { return (2 * i + 1) % (i + 1); })));
-assert(all_of((a & b) == native_simd(
- [](int i) { return (2 * i + 1) & (i + 1); })));
-assert(all_of((a | b) == native_simd(
- [](int i) { return (2 * i + 1) | (i + 1); })));
-assert(all_of((a ^ b) == native_simd(
- [](int i) { return (2 * i + 1) ^ (i + 1); })));
+assert(all_of(-a == SimdType([](int i) { return -(2 * i + 1); })));
+assert(all_of(a + b == SimdType([](int i) { return 3 * i + 2; })));
+assert(all_of(a - b == SimdType([](int i) { return i; })));
+assert(
+all_of(a * b == SimdType([](int i) { return (2 * i + 1) * (i + 1); })));
+assert(
+all_of(a / b == SimdType([](int i) { return (2 * i + 1) / (i + 1); })));
+assert(
+all_of(a % b == SimdType([](int i) { return (2 * i + 1) % (i + 1); })));
+assert(all_of((a & b) ==
+  SimdType([](int i) { return (2 * i + 1) & (i + 1); })));
+assert(all_of((a | b) ==
+  SimdType([](int i) { return (2 * i + 1) | (i + 1); })));
+assert(all_of((a ^ b) ==
+  SimdType([](int i) { return (2 * i + 1) ^ (i + 1); })));
   }
 }
 
+template 
 void test_mutating_opreators() {
-  native_simd b(4);
+  SimdType b(4);
   {
-native_simd a(42);
-assert(all_of(++a == native_simd(43)));
-assert(all_of(a == native_simd(43)));
+SimdType a(42);
+assert(all_of(++a == SimdType(43)));
+assert(all_of(a == SimdType(43)));
   }
   {
-native_simd a(42);
-assert(all_of(a++ == native_simd(42)));
-assert(all_of(a == native_simd(43)));
+SimdType a(42);
+assert(all_of(a++ == SimdType(42)));
+assert(all_of(a == SimdType(43)));
   }
   {
-native_simd a(42);
-assert(all_of(--a == native_simd(41)));
-assert(all_of(a == native_simd(41)));
+SimdType 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-04-05 Thread Tim Shen via Phabricator via cfe-commits
timshen marked 5 inline comments as done.
timshen added inline comments.



Comment at: 
libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp:68
+
+static_assert(!is_simd_mask::value, "");
+

mclow.lists wrote:
> How about a couple more negative tests here?
> You've got `int`, how about `float`, and `std::string` and a few of the simd 
> types?
> 
I used "UserType" instead of std::string, as I don't want to pull in the whole 
 header. I figured that UserType should serve the same purpose.


https://reviews.llvm.org/D41148



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-04-05 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 141188.
timshen added a comment.

Addressed comments.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/module.modulemap
  libcxx/test/libcxx/double_include.sh.cpp
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/genertor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,133 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+struct UserType {};
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+static_assert(!is_simd_mask::value, "");
+
+#if 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-03-21 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139393.
timshen marked 7 inline comments as done.
timshen added a comment.

Address comments.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,121 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
+!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-03-21 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: libcxx/include/experimental/simd:669
+
+#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+template 

mclow.lists wrote:
> Isn't the parallelism TS based on C++17?
> 
I intended to have a C++11 (and C++14) compatible implementation.


https://reviews.llvm.org/D41148



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44663: [libcxx] Update with R9 changes

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

- change the uses of abi_for_size to simd_abi::deduce.
- remove the const in const_where_expression's template.


https://reviews.llvm.org/D44663

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
@@ -43,25 +43,23 @@
 void compile_const_where() {
   {
 const native_simd a{};
-static_assert(
-std::is_same>::value,
-"");
+static_assert(std::is_same>::value,
+  "");
   }
   {
 const native_simd_mask a{};
 static_assert(
-std::is_same<
-decltype(where(a, a)),
-const_where_expression>::value,
+std::is_same>::value,
 "");
   }
   {
 const bool b = true;
 static_assert(std::is_same>::value,
+   const_where_expression>::value,
   "");
   }
 }
Index: libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp
@@ -20,11 +20,12 @@
 
 using namespace std::experimental::parallelism_v2;
 
-static_assert(std::is_same::type,
+static_assert(std::is_same::type,
simd_abi::fixed_size<4>>::value,
   "");
 
 static_assert(
-std::is_same, simd_abi::fixed_size<4>>::value, "");
+std::is_same, simd_abi::fixed_size<4>>::value,
+"");
 
 int main() {}
Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -26,11 +26,11 @@
 // const simd_mask&);
 //
 // template 
-// array / n, A>>, n> split_by(
+// array / n, A>>, n> split_by(
 // const simd& x);
 //
 // template 
-// array / n, A>>, n> split_by(
+// array / n, A>>, n> split_by(
 // const simd_mask& x);
 
 #include 
@@ -138,11 +138,11 @@
 
 void compile_split_simd_propagate_abi() {
   using compatible_simd_half =
-  simd>;
+  simd>;
   using native_simd_half =
-  simd>;
+  simd>;
 
   static_assert(
   std::is_same<
@@ -169,11 +169,11 @@
 
 void compile_split_simd_mask_propagate_abi() {
   using compatible_simd_mask_half =
-  simd_mask>;
+  simd_mask>;
   using native_simd_mask_half =
-  simd_mask

[PATCH] D44665: [libcxx] Update synopsis to P0214R9

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.
Herald added a reviewer: EricWF.

https://reviews.llvm.org/D44665

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/minmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp
  
libcxx/test/std/experimental/simd/simd.whereexpr/const_where_expression.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
@@ -15,24 +15,23 @@
 // template 
 // class where_expression : public const_where_expression {
 // public:
-//   where_expression(const where_expression&) = delete;
-//   where_expression& operator=(const where_expression&) = delete;
-//   template  void operator=(U&& x);
-//   template  void operator+=(U&& x);
-//   template  void operator-=(U&& x);
-//   template  void operator*=(U&& x);
-//   template  void operator/=(U&& x);
-//   template  void operator%=(U&& x);
-//   template  void operator&=(U&& x);
-//   template  void operator|=(U&& x);
-//   template  void operator^=(U&& x);
-//   template  void operator<<=(U&& x);
-//   template  void operator>>=(U&& x);
-//   void operator++();
-//   void operator++(int);
-//   void operator--();
-//   void operator--(int);
-//   template  void copy_from(const U* mem, Flags);
+//  template  void operator=(U&& x) &&;
+//  template  void operator+=(U&& x) &&;
+//  template  void operator-=(U&& x) &&;
+//  template  void operator*=(U&& x) &&;
+//  template  void operator/=(U&& x) &&;
+//  template  void operator%=(U&& x) &&;
+//  template  void operator&=(U&& x) &&;
+//  template  void operator|=(U&& x) &&;
+//  template  void operator^=(U&& x) &&;
+//  template  void operator<<=(U&& x) &&;
+//  template  void operator>>=(U&& x) &&;
+//  void operator++() &&;
+//  void operator++(int) &&;
+//  void operator--() &&;
+//  void operator--(int) &&;
+//
+//  template  void copy_from(const U* mem, Flags) &&;
 // };
 
 #include 
Index: libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
@@ -17,21 +17,21 @@
 // where(const typename simd::mask_type&, simd&) noexcept;
 //
 // template 
-// const_where_expression, const simd>
+// const_where_expression, simd>
 // where(const typename simd::mask_type&, const simd&) noexcept;
 //
 // template 
 // where_expression, simd_mask>
 // where(const nodeduce_t>&, simd_mask&) noexcept;
 //
 // template 
-// const_where_expression, const simd_mask>
+// const_where_expression, simd_mask>
 // where(const nodeduce_t>&, const simd_mask&) noexcept;
 //
 // template  where_expression where(see below k, T& d) noexcept;
 //
 // template 
-// const_where_expression where(see below k, const T& d) noexcept;
+// const_where_expression where(see below k, const T& d) noexcept;
 
 #include 
 #include 
Index: libcxx/test/std/experimental/simd/simd.whereexpr/const_where_expression.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.whereexpr/const_where_expression.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.whereexpr/const_where_expression.pass.cpp
@@ -14,12 +14,17 @@
 // // [simd.whereexpr]
 // template 
 // class const_where_expression {
-//   const M& mask; // exposition only
+//   const M mask; // exposition only
 //   T& data; // exposition only
+//
 // public:
 //   const_where_expression(const const_where_expression&) = delete;
 //   const_where_expression& operator=(const const_where_expression&) = delete;
-//   remove_const_t operator-() const &&;
+//
+//   T 

[PATCH] D44660: [libcxx] unroll the loops in for Clang, until LLVM bugs are fixed

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

https://reviews.llvm.org/D44660

Files:
  libcxx/include/experimental/simd


Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -611,6 +611,13 @@
 #pragma GCC system_header
 #endif
 
+#if !defined(_LIBCPP_COMPILER_CLANG)
+#define _LIBCPP_UNROLL
+#else
+// See LLVM PR/36359 for context of this workaround.
+#define _LIBCPP_UNROLL _Pragma("unroll")
+#endif
+
 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
 
 enum class _StorageKind {
@@ -2109,20 +2116,22 @@
 
 // algorithms [simd.alg]
 template 
-simd<_Tp, _Abi> min(const simd<_Tp, _Abi>& __a,
-const simd<_Tp, _Abi>& __b) noexcept {
+// Add `inline` keyword until LLVM PR/36495 is fixed
+inline simd<_Tp, _Abi> min(const simd<_Tp, _Abi>& __a,
+   const simd<_Tp, _Abi>& __b) noexcept {
   simd<_Tp, _Abi> __v;
-  for (size_t __i = 0; __i < __v.size(); __i++) {
+  _LIBCPP_UNROLL for (size_t __i = 0; __i < __v.size(); __i++) {
 __v[__i] = std::min(__a[__i], __b[__i]);
   }
   return __v;
 }
 
 template 
-simd<_Tp, _Abi> max(const simd<_Tp, _Abi>& __a,
-const simd<_Tp, _Abi>& __b) noexcept {
+// Add `inline` keyword until LLVM PR/36495 is fixed
+inline simd<_Tp, _Abi> max(const simd<_Tp, _Abi>& __a,
+   const simd<_Tp, _Abi>& __b) noexcept {
   simd<_Tp, _Abi> __v;
-  for (size_t __i = 0; __i < __v.size(); __i++) {
+  _LIBCPP_UNROLL for (size_t __i = 0; __i < __v.size(); __i++) {
 __v[__i] = std::max(__a[__i], __b[__i]);
   }
   return __v;
@@ -3060,4 +3069,6 @@
 
 _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
 
+#undef _LIBCPP_UNROLL
+
 #endif /* _LIBCPP_EXPERIMENTAL_SIMD */


Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -611,6 +611,13 @@
 #pragma GCC system_header
 #endif
 
+#if !defined(_LIBCPP_COMPILER_CLANG)
+#define _LIBCPP_UNROLL
+#else
+// See LLVM PR/36359 for context of this workaround.
+#define _LIBCPP_UNROLL _Pragma("unroll")
+#endif
+
 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD
 
 enum class _StorageKind {
@@ -2109,20 +2116,22 @@
 
 // algorithms [simd.alg]
 template 
-simd<_Tp, _Abi> min(const simd<_Tp, _Abi>& __a,
-const simd<_Tp, _Abi>& __b) noexcept {
+// Add `inline` keyword until LLVM PR/36495 is fixed
+inline simd<_Tp, _Abi> min(const simd<_Tp, _Abi>& __a,
+   const simd<_Tp, _Abi>& __b) noexcept {
   simd<_Tp, _Abi> __v;
-  for (size_t __i = 0; __i < __v.size(); __i++) {
+  _LIBCPP_UNROLL for (size_t __i = 0; __i < __v.size(); __i++) {
 __v[__i] = std::min(__a[__i], __b[__i]);
   }
   return __v;
 }
 
 template 
-simd<_Tp, _Abi> max(const simd<_Tp, _Abi>& __a,
-const simd<_Tp, _Abi>& __b) noexcept {
+// Add `inline` keyword until LLVM PR/36495 is fixed
+inline simd<_Tp, _Abi> max(const simd<_Tp, _Abi>& __a,
+   const simd<_Tp, _Abi>& __b) noexcept {
   simd<_Tp, _Abi> __v;
-  for (size_t __i = 0; __i < __v.size(); __i++) {
+  _LIBCPP_UNROLL for (size_t __i = 0; __i < __v.size(); __i++) {
 __v[__i] = std::max(__a[__i], __b[__i]);
   }
   return __v;
@@ -3060,4 +3069,6 @@
 
 _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
 
+#undef _LIBCPP_UNROLL
+
 #endif /* _LIBCPP_EXPERIMENTAL_SIMD */
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44664: [libcxx] Add missing __simd_reference pieces based on R9.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

https://reviews.llvm.org/D44664

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
@@ -76,6 +76,12 @@
   assert(bool(c[1]) == false);
 }
 
+{
+  auto c = a;
+  c[0] = b[0];
+  assert(bool(c[0]) == true);
+  assert(bool(c[1]) == false);
+}
 {
   auto c = a;
   c[0] += b[0];
@@ -136,6 +142,30 @@
   assert(bool(c[0]) == true);
   assert(bool(c[1]) == false);
 }
+{
+  auto aa = a, bb = b;
+  swap(aa[0], bb[0]);
+  assert(aa[0] == true);
+  assert(bb[0] == false);
+  assert(aa[1] == false);
+  assert(bb[1] == true);
+}
+{
+  auto c = a;
+  bool d = true;
+  swap(c[0], d);
+  assert(c[0] == true);
+  assert(d == false);
+  assert(c[1] == false);
+}
+{
+  auto c = a;
+  bool d = true;
+  swap(d, c[0]);
+  assert(c[0] == true);
+  assert(d == false);
+  assert(c[1] == false);
+}
 
 {
   auto c = a;
Index: libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
@@ -77,6 +77,12 @@
   assert(c[1] == 42);
 }
 
+{
+  auto c = a;
+  c[0] = b[0];
+  assert(c[0] == 4);
+  assert(c[1] == 42);
+}
 {
   auto c = a;
   c[0] += b[0];
@@ -137,7 +143,30 @@
   assert(c[0] == (42 ^ 4));
   assert(c[1] == 42);
 }
-
+{
+  auto aa = a, bb = b;
+  swap(aa[0], bb[0]);
+  assert(aa[0] == 4);
+  assert(bb[0] == 42);
+  assert(aa[1] == 42);
+  assert(bb[1] == 4);
+}
+{
+  auto c = a;
+  int d = 4;
+  swap(c[0], d);
+  assert(c[0] == 4);
+  assert(d == 42);
+  assert(c[1] == 42);
+}
+{
+  auto c = a;
+  int d = 4;
+  swap(d, c[0]);
+  assert(c[0] == 4);
+  assert(d == 42);
+  assert(c[1] == 42);
+}
 {
   auto c = a;
   (void)(a[0] + (c[0] += a[0]));
Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -1219,6 +1219,11 @@
 return *this;
   }
 
+  template 
+  __simd_reference operator=(__simd_reference<_Vp, _Up, _Abi>&& __ref) && {
+return std::move(*this) = _Vp(__ref);
+  }
+
   __simd_reference operator++() && {
 return std::move(*this) = __ptr_->__get(__index_) + 1;
   }
@@ -1288,6 +1293,22 @@
 return std::move(*this) =
__from_value_type(__ptr_->__get(__index_) ^ __val);
   }
+
+  friend void swap(__simd_reference&& a, __simd_reference&& b) noexcept {
+_Vp __val = std::move(b);
+std::move(b) = std::move(a);
+std::move(a) = __val;
+  }
+
+  friend void swap(_Vp& a, __simd_reference&& b) noexcept {
+swap(std::move(b), a);
+  }
+
+  friend void swap(__simd_reference&& a, _Vp& b) noexcept {
+_Vp __val = b;
+b = std::move(a);
+std::move(a) = __val;
+  }
 };
 
 template 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D44659: [libcxx] Optimize -O0 performance for operators

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

When vector extension (__attribute__((vector_size(... is available
use its operators, instead of generating loops of scalar operations.


https://reviews.llvm.org/D44659

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
@@ -64,136 +64,138 @@
 
 using namespace std::experimental::parallelism_v2;
 
+template 
 void test_pure_operators() {
   {
-native_simd a(42), b(4);
+SimdType a(42), b(4);
 
-assert(all_of(~a == native_simd(~42)));
+assert(all_of(~a == SimdType(~42)));
 assert(all_of(+a == a));
-assert(all_of(-a == native_simd(-42)));
-assert(all_of(a + b == native_simd(42 + 4)));
-assert(all_of(a - b == native_simd(42 - 4)));
-assert(all_of(a * b == native_simd(42 * 4)));
-assert(all_of(a / b == native_simd(42 / 4)));
-assert(all_of(a % b == native_simd(42 % 4)));
-assert(all_of((a & b) == native_simd(42 & 4)));
-assert(all_of((a | b) == native_simd(42 | 4)));
-assert(all_of((a ^ b) == native_simd(42 ^ 4)));
-assert(all_of((a << b) == native_simd(42 << 4)));
-assert(all_of((a >> b) == native_simd(42 >> 4)));
-assert(all_of((a << 4) == native_simd(42 << 4)));
-assert(all_of((a >> 4) == native_simd(42 >> 4)));
+assert(all_of(-a == SimdType(-42)));
+assert(all_of(a + b == SimdType(42 + 4)));
+assert(all_of(a - b == SimdType(42 - 4)));
+assert(all_of(a * b == SimdType(42 * 4)));
+assert(all_of(a / b == SimdType(42 / 4)));
+assert(all_of(a % b == SimdType(42 % 4)));
+assert(all_of((a & b) == SimdType(42 & 4)));
+assert(all_of((a | b) == SimdType(42 | 4)));
+assert(all_of((a ^ b) == SimdType(42 ^ 4)));
+assert(all_of((a << b) == SimdType(42 << 4)));
+assert(all_of((a >> b) == SimdType(42 >> 4)));
+assert(all_of((a << 4) == SimdType(42 << 4)));
+assert(all_of((a >> 4) == SimdType(42 >> 4)));
   }
   {
-native_simd a([](int i) { return 2 * i + 1; }),
-b([](int i) { return i + 1; });
+SimdType a([](int i) { return 2 * i + 1; }), b([](int i) { return i + 1; });
 
-assert(all_of(~a == native_simd([](int i) { return ~(2 * i + 1); })));
+assert(all_of(~a == SimdType([](int i) { return ~(2 * i + 1); })));
 assert(all_of(+a == a));
-assert(all_of(-a == native_simd([](int i) { return -(2 * i + 1); })));
-assert(all_of(a + b == native_simd([](int i) { return 3 * i + 2; })));
-assert(all_of(a - b == native_simd([](int i) { return i; })));
-assert(all_of(a * b == native_simd(
-   [](int i) { return (2 * i + 1) * (i + 1); })));
-assert(all_of(a / b == native_simd(
-   [](int i) { return (2 * i + 1) / (i + 1); })));
-assert(all_of(a % b == native_simd(
-   [](int i) { return (2 * i + 1) % (i + 1); })));
-assert(all_of((a & b) == native_simd(
- [](int i) { return (2 * i + 1) & (i + 1); })));
-assert(all_of((a | b) == native_simd(
- [](int i) { return (2 * i + 1) | (i + 1); })));
-assert(all_of((a ^ b) == native_simd(
- [](int i) { return (2 * i + 1) ^ (i + 1); })));
+assert(all_of(-a == SimdType([](int i) { return -(2 * i + 1); })));
+assert(all_of(a + b == SimdType([](int i) { return 3 * i + 2; })));
+assert(all_of(a - b == SimdType([](int i) { return i; })));
+assert(
+all_of(a * b == SimdType([](int i) { return (2 * i + 1) * (i + 1); })));
+assert(
+all_of(a / b == SimdType([](int i) { return (2 * i + 1) / (i + 1); })));
+assert(
+all_of(a % b == SimdType([](int i) { return (2 * i + 1) % (i + 1); })));
+assert(all_of((a & b) ==
+  SimdType([](int i) { return (2 * i + 1) & (i + 1); })));
+assert(all_of((a | b) ==
+  SimdType([](int i) { return (2 * i + 1) | (i + 1); })));
+assert(all_of((a ^ b) ==
+  SimdType([](int i) { return (2 * i + 1) ^ (i + 1); })));
   }
 }
 
+template 
 void test_mutating_opreators() {
-  native_simd b(4);
+  SimdType b(4);
   {
-native_simd a(42);
-assert(all_of(++a == native_simd(43)));
-assert(all_of(a == native_simd(43)));
+SimdType a(42);
+assert(all_of(++a == SimdType(43)));
+assert(all_of(a == SimdType(43)));
   }
   {
-native_simd a(42);
-assert(all_of(a++ == native_simd(42)));
-assert(all_of(a == native_simd(43)));
+SimdType a(42);
+assert(all_of(a++ == SimdType(42)));
+

[PATCH] D44661: [libcxx] optimize reduce(), hmin(), hmax() by reordering the operations.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

Also change std::plus<_Tp> to std::plus<>/__simd_plus_op, so that the
optimization can transparently use the simd<> overloading.


https://reviews.llvm.org/D44661

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
@@ -38,52 +38,64 @@
 #include 
 #include 
 
+#include "test_macros.h"
+
 using namespace std::experimental::parallelism_v2;
 
 inline int factorial(int n) { return n == 1 ? 1 : n * factorial(n - 1); }
 
+template 
 void test_reduce_simd() {
-  int n = (int)native_simd::size();
-  assert(reduce(native_simd([](int i) { return i; })) == n * (n - 1) / 2);
-  assert(reduce(native_simd([](int i) { return i; }), std::plus()) ==
+  int n = (int)SimdType::size();
+  assert(reduce(SimdType([](int i) { return i; })) == n * (n - 1) / 2);
+
+#if TEST_STD_VER >= 14
+  assert(reduce(SimdType([](int i) { return i; }), std::plus<>()) ==
  n * (n - 1) / 2);
-  assert(reduce(native_simd([](int i) { return i + 1; }),
-std::multiplies()) == factorial(n));
+  assert(reduce(SimdType([](int i) { return i + 1; }), std::multiplies<>()) ==
+ factorial(n));
+#endif
 }
 
 void test_reduce_mask() {
   {
 fixed_size_simd a([](int i) { return i; });
-assert(reduce(where(a < 2, a), 0, std::plus()) == 0 + 1);
-assert(reduce(where(a >= 2, a), 1, std::multiplies()) == 2 * 3);
 assert(reduce(where(a >= 2, a)) == 2 + 3);
-assert(reduce(where(a >= 2, a), std::plus()) == 2 + 3);
-assert(reduce(where(a >= 2, a), std::multiplies()) == 2 * 3);
-assert(reduce(where(a >= 2, a), std::bit_and()) == (2 & 3));
-assert(reduce(where(a >= 2, a), std::bit_or()) == (2 | 3));
-assert(reduce(where(a >= 2, a), std::bit_xor()) == (2 ^ 3));
+#if TEST_STD_VER >= 14
+assert(reduce(where(a < 2, a), 0, std::plus<>()) == 0 + 1);
+assert(reduce(where(a >= 2, a), 1, std::multiplies<>()) == 2 * 3);
+assert(reduce(where(a >= 2, a), std::plus<>()) == 2 + 3);
+assert(reduce(where(a >= 2, a), std::multiplies<>()) == 2 * 3);
+assert(reduce(where(a >= 2, a), std::bit_and<>()) == (2 & 3));
+assert(reduce(where(a >= 2, a), std::bit_or<>()) == (2 | 3));
+assert(reduce(where(a >= 2, a), std::bit_xor<>()) == (2 ^ 3));
+#endif
   }
   {
 fixed_size_simd_mask a;
 a[0] = false;
 a[1] = true;
 a[2] = true;
 a[3] = false;
 assert(reduce(where(fixed_size_simd_mask(true), a)) == true);
+#if TEST_STD_VER >= 14
 assert(reduce(where(fixed_size_simd_mask(true), a),
-  std::plus()) == true);
+  std::plus<>()) == true);
 assert(reduce(where(fixed_size_simd_mask(true), a),
-  std::multiplies()) == false);
+  std::multiplies<>()) == false);
 assert(reduce(where(fixed_size_simd_mask(true), a),
-  std::bit_and()) == false);
+  std::bit_and<>()) == false);
 assert(reduce(where(fixed_size_simd_mask(true), a),
-  std::bit_or()) == true);
+  std::bit_or<>()) == true);
 assert(reduce(where(fixed_size_simd_mask(true), a),
-  std::bit_xor()) == false);
+  std::bit_xor<>()) == false);
+#endif
   }
 }
 
 int main() {
-  test_reduce_simd();
+  test_reduce_simd();
+  test_reduce_simd>();
+  test_reduce_simd>();
   test_reduce_mask();
 }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
@@ -20,22 +20,47 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_hmin_simd() {
+template 
+void test_hmin_simd_power_of_2() {
   {
 int a[] = {2, 5, -4, 6};
-assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+assert(hmin(SimdType(a, element_aligned_tag())) == -4);
   }
   {
 int a[] = {6, 2, 5, -4};
-assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+assert(hmin(SimdType(a, element_aligned_tag())) == -4);
   }
   {
 int a[] = {-4, 6, 2, 5};
-assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+assert(hmin(SimdType(a, element_aligned_tag())) == -4);
   }
 

[PATCH] D44662: [libcxx] In , optimize masked div and rem.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

This optimization is allowed by the semantics, as users shouldn't pass
in values that may cause undefined behavior even those values are masked.


https://reviews.llvm.org/D44662

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp


Index: 
libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
@@ -123,15 +123,6 @@
 assert(a[2] == 3);
 assert(a[3] == 4);
   }
-  {
-fixed_size_simd a([](int i) { return i; });
-where(a % 2 == 1, a) /=
-fixed_size_simd([](int i) { return i % 2 * 2; });
-assert(a[0] == 0);
-assert(a[1] == 0);
-assert(a[2] == 2);
-assert(a[3] == 1);
-  }
   {
 fixed_size_simd a([](int i) { return 3 * i; });
 where(a >= 6, a) %= 2;
@@ -148,15 +139,6 @@
 assert(a[2] == 0);
 assert(a[3] == 1);
   }
-  {
-fixed_size_simd a([](int i) { return i; });
-where(a % 2 == 1, a) %=
-fixed_size_simd([](int i) { return i % 2 * 2; });
-assert(a[0] == 0);
-assert(a[1] == 1);
-assert(a[2] == 2);
-assert(a[3] == 1);
-  }
   {
 fixed_size_simd a([](int i) { return i; });
 where(a > -2, a) &= 1;
Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -2491,8 +2491,7 @@
   }
 
   // binary operators [simd.binary]
-  // TODO: regarding NOTE 9, the implementationn chooses not to SFINAE,
-  // but causes a hard error when the operator can't work on _Tp.
+  // TODO: currently the operators are not SFINAEed. Fix it.
   friend simd operator+(const simd& __a, const simd& __b) {
 return __from_storage(__simd_storage<_Tp, _Abi>::__add(__a.__s_, 
__b.__s_));
   }
@@ -2999,21 +2998,13 @@
   template 
   auto operator/=(_Up&& __u)
   -> decltype(this->__v_ / std::forward<_Up>(__u), void()) {
-this->__v_ =
-this->__v_ /
-__simd_mask_friend::__simd_select(
-_ValueType(1), _ValueType(std::forward<_Up>(__u)), this->__m_);
+*this = this->__v_ / std::forward<_Up>(__u);
   }
 
   template 
   auto operator%=(_Up&& __u)
   -> decltype(this->__v_ % std::forward<_Up>(__u), void()) {
-this->__v_ = __simd_mask_friend::__simd_select(
-this->__v_,
-this->__v_ %
-__simd_mask_friend::__simd_select(
-_ValueType(1), _ValueType(std::forward<_Up>(__u)), this->__m_),
-this->__m_);
+*this = this->__v_ % std::forward<_Up>(__u);
   }
 
   template 


Index: libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
@@ -123,15 +123,6 @@
 assert(a[2] == 3);
 assert(a[3] == 4);
   }
-  {
-fixed_size_simd a([](int i) { return i; });
-where(a % 2 == 1, a) /=
-fixed_size_simd([](int i) { return i % 2 * 2; });
-assert(a[0] == 0);
-assert(a[1] == 0);
-assert(a[2] == 2);
-assert(a[3] == 1);
-  }
   {
 fixed_size_simd a([](int i) { return 3 * i; });
 where(a >= 6, a) %= 2;
@@ -148,15 +139,6 @@
 assert(a[2] == 0);
 assert(a[3] == 1);
   }
-  {
-fixed_size_simd a([](int i) { return i; });
-where(a % 2 == 1, a) %=
-fixed_size_simd([](int i) { return i % 2 * 2; });
-assert(a[0] == 0);
-assert(a[1] == 1);
-assert(a[2] == 2);
-assert(a[3] == 1);
-  }
   {
 fixed_size_simd a([](int i) { return i; });
 where(a > -2, a) &= 1;
Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -2491,8 +2491,7 @@
   }
 
   // binary operators [simd.binary]
-  // TODO: regarding NOTE 9, the implementationn chooses not to SFINAE,
-  // but causes a hard error when the operator can't work on _Tp.
+  // TODO: currently the operators are not SFINAEed. Fix it.
   friend simd operator+(const simd& __a, const simd& __b) {
 return __from_storage(__simd_storage<_Tp, _Abi>::__add(__a.__s_, __b.__s_));
   }
@@ -2999,21 +2998,13 @@
   template 
   auto operator/=(_Up&& __u)
   -> decltype(this->__v_ / std::forward<_Up>(__u), void()) {
-this->__v_ =
-this->__v_ /
-__simd_mask_friend::__simd_select(
-_ValueType(1), 

[PATCH] D44658: [libcxx] Implement aligned load and store when compiled with Clang.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.

Simply use __attribute__((align_value(...))).


https://reviews.llvm.org/D44658

Files:
  libcxx/include/experimental/simd

Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -1238,25 +1238,36 @@
   "Element type should be vectorizable");
 };
 
-template 
-struct memory_alignment;
+template 
+struct __memory_alignment_impl : std::integral_constant {
+};
 
-// TODO: May extend this after implementing vector_aligned.
 template 
-struct memory_alignment, _Up>
+struct __memory_alignment_impl, _Up, vector_aligned_tag>
 : std::integral_constant)> {};
 
-template 
-struct memory_alignment, bool>
-: std::integral_constant)> {};
+// TODO: Figure out a useful alignment based on simd_mask load and store
+// implementation. Currently, make sure that the buffer is suitable for aligned
+// SIMD load.
+template 
+struct __memory_alignment_impl, _Up, vector_aligned_tag>
+: std::integral_constant)> {};
+
+template 
+struct __memory_alignment_impl<_ValueType, _Up, overaligned_tag<__alignment>>
+: std::integral_constant {};
+
+template 
+struct memory_alignment
+: __memory_alignment_impl<_SimdType, _Up, vector_aligned_tag> {};
 
 #if _LIBCPP_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 template >
 _LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
 
-template 
+template 
 _LIBCPP_INLINE_VAR constexpr size_t memory_alignment_v =
-memory_alignment<_Tp, _Up>::value;
+memory_alignment<_SimdType, _Up>::value;
 #endif
 
 // class template simd [simd.class]
@@ -1932,6 +1943,22 @@
 (void)__unused;
   }
 
+  template 
+  void __copy_from_impl(const _Up* __buffer
+__attribute__((align_value(__alignment {
+for (size_t __i = 0; __i < size(); __i++) {
+  (*this)[__i] = static_cast<_Tp>(__buffer[__i]);
+}
+  }
+
+  template 
+  void __copy_to_impl(_Up* __buffer
+  __attribute__((align_value(__alignment const {
+for (size_t __i = 0; __i < size(); __i++) {
+  __buffer[__i] = static_cast<_Up>((*this)[__i]);
+}
+  }
+
 public:
   // implicit type conversion constructor
   template ()>::type,
   class = typename std::enable_if::value>::type>
   simd(const _Up* __buffer, _Flags) {
-// TODO: optimize for overaligned flags
-for (size_t __i = 0; __i < size(); __i++) {
-  (*this)[__i] = static_cast<_Tp>(__buffer[__i]);
-}
+__copy_from_impl<__memory_alignment_impl::value>(
+__buffer);
   }
 
   // loads [simd.load]
@@ -2008,10 +2033,7 @@
   typename std::enable_if<__vectorizable<_Up>() &&
   is_simd_flag_type<_Flags>::value>::type
   copy_to(_Up* __buffer, _Flags) const {
-// TODO: optimize for overaligned flags
-for (size_t __i = 0; __i < size(); __i++) {
-  __buffer[__i] = static_cast<_Up>((*this)[__i]);
-}
+__copy_to_impl<__memory_alignment_impl::value>(__buffer);
   }
 
   // scalar access [simd.subscr]
@@ -2265,6 +2287,24 @@
 
   friend struct __simd_mask_friend;
 
+  // Use a non-member function, only because Clang 3.8 crashes with a member function.
+  template 
+  static void __copy_from_impl(simd_mask* __mask, const bool* __buffer
+   __attribute__((align_value(__alignment {
+for (size_t __i = 0; __i < size(); __i++) {
+  (*__mask)[__i] = __buffer[__i];
+}
+  }
+
+  // Use a non-member function, only because Clang 3.8 crashes with a member function.
+  template 
+  static void __copy_to_impl(const simd_mask* __mask, bool* __buffer
+ __attribute__((align_value(__alignment {
+for (size_t __i = 0; __i < size(); __i++) {
+  __buffer[__i] = (*__mask)[__i];
+}
+  }
+
 public:
   using value_type = bool;
   using reference = __simd_reference;
@@ -2300,10 +2340,8 @@
   template ::value>::type>
   simd_mask(const value_type* __buffer, _Flags) {
-// TODO: optimize for overaligned flags
-for (size_t __i = 0; __i < size(); __i++) {
-  (*this)[__i] = __buffer[__i];
-}
+__copy_from_impl<__memory_alignment_impl::value>(
+this, __buffer);
   }
 
   template 
@@ -2336,10 +2374,8 @@
   template 
   typename std::enable_if::value>::type
   copy_to(value_type* __buffer, _Flags) const {
-// TODO: optimize for overaligned flags
-for (size_t __i = 0; __i < size(); __i++) {
-

[PATCH] D44657: [libcxx] fix a sanitizer-reported bug in

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, sanjoy.
Herald added a reviewer: EricWF.
Herald added a reviewer: EricWF.

In __simd_reference, the conversion between bool and mask integer is
in wrong place.


https://reviews.llvm.org/D44657

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
@@ -159,11 +159,11 @@
 }
 {
   auto c = a;
-  (void)(a[0] + (c[0] >>= a[0]));
+  (void)(a[0] + (c[0] >>= b[0]));
 }
 {
   auto c = a;
-  (void)(a[0] + (c[0] <<= a[0]));
+  (void)(a[0] + (c[0] <<= b[0]));
 }
 {
   auto c = a;
Index: libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
@@ -160,11 +160,11 @@
 }
 {
   auto c = a;
-  (void)(a[0] + (c[0] >>= a[0]));
+  (void)(a[0] + (c[0] >>= b[0]));
 }
 {
   auto c = a;
-  (void)(a[0] + (c[0] <<= a[0]));
+  (void)(a[0] + (c[0] <<= b[0]));
 }
 {
   auto c = a;
Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -978,52 +978,52 @@
 
   __simd_reference operator+=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) + __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) + __val);
   }
 
   __simd_reference operator-=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) - __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) - __val);
   }
 
   __simd_reference operator*=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) * __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) * __val);
   }
 
   __simd_reference operator/=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) / __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) / __val);
   }
 
   __simd_reference operator%=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) % __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) % __val);
   }
 
   __simd_reference operator>>=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) >> __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) >> __val);
   }
 
   __simd_reference operator<<=(_Vp __val) && {
-return std::move(*this) = __ptr_->__get(__index_)
-  << __from_value_type(__val);
+return std::move(*this) =
+   __from_value_type(__ptr_->__get(__index_) << __val);
   }
 
   __simd_reference operator&=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) & __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) & __val);
   }
 
   __simd_reference operator|=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) | __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) | __val);
   }
 
   __simd_reference operator^=(_Vp __val) && {
 return std::move(*this) =
-   __ptr_->__get(__index_) ^ __from_value_type(__val);
+   __from_value_type(__ptr_->__get(__index_) ^ __val);
   }
 };
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41843: [libcxx] implement where expressions.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139043.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41843

Files:
  libcxx/include/experimental/simd
  
libcxx/test/std/experimental/simd/simd.whereexpr/const_where_expression.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
@@ -0,0 +1,366 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // [simd.whereexpr]
+// template 
+// class where_expression : public const_where_expression {
+// public:
+//   where_expression(const where_expression&) = delete;
+//   where_expression& operator=(const where_expression&) = delete;
+//   template  void operator=(U&& x);
+//   template  void operator+=(U&& x);
+//   template  void operator-=(U&& x);
+//   template  void operator*=(U&& x);
+//   template  void operator/=(U&& x);
+//   template  void operator%=(U&& x);
+//   template  void operator&=(U&& x);
+//   template  void operator|=(U&& x);
+//   template  void operator^=(U&& x);
+//   template  void operator<<=(U&& x);
+//   template  void operator>>=(U&& x);
+//   void operator++();
+//   void operator++(int);
+//   void operator--();
+//   void operator--(int);
+//   template  void copy_from(const U* mem, Flags);
+// };
+
+#include 
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_operators_simd() {
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) = -1;
+assert(a[0] == -1);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) = fixed_size_simd(-1);
+assert(a[0] == -1);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) += -1;
+assert(a[0] == -1);
+assert(a[1] == 0);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) += fixed_size_simd(-1);
+assert(a[0] == -1);
+assert(a[1] == 0);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) -= -1;
+assert(a[0] == 1);
+assert(a[1] == 2);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) -= fixed_size_simd(-1);
+assert(a[0] == 1);
+assert(a[1] == 2);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) *= -1;
+assert(a[0] == 0);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) *= fixed_size_simd(-1);
+assert(a[0] == 0);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) /= 2;
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 3);
+assert(a[3] == 4);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) /= fixed_size_simd(2);
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 3);
+assert(a[3] == 4);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a % 2 == 1, a) /=
+fixed_size_simd([](int i) { return i % 2 * 2; });
+assert(a[0] == 0);
+assert(a[1] == 0);
+assert(a[2] == 2);
+assert(a[3] == 1);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) %= 2;
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 0);
+assert(a[3] == 1);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) %= fixed_size_simd(2);
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 0);
+assert(a[3] == 1);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a % 2 == 1, a) %=
+fixed_size_simd([](int i) { return i % 2 * 2; });
+assert(a[0] == 0);
+assert(a[1] == 

[PATCH] D41845: [libcxx] clean up and complete

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139045.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41845

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp
@@ -0,0 +1,67 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct memory_alignment;
+// template 
+// inline constexpr size_t memory_alignment_v = memory_alignment::value;
+
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(std::is_same>::value)>::value,
+  "");
+static_assert(
+std::is_same, int>::value)>::value,
+"");
+static_assert(
+std::is_same<
+const size_t,
+decltype(memory_alignment::value)>::value,
+"");
+static_assert(
+std::is_same>::value)>::value,
+"");
+static_assert(
+std::is_same,
+ bool>::value)>::value,
+"");
+
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+
+static_assert(
+std::is_same>)>::value,
+"");
+static_assert(std::is_same, int>)>::value,
+  "");
+static_assert(
+std::is_same, unsigned int>)>::value,
+"");
+static_assert(std::is_same>)>::value,
+  "");
+static_assert(
+std::is_same, bool>)>::value,
+"");
+
+#endif
+
+int main() {}
Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -67,8 +67,7 @@
 
 static_assert(!is_simd_mask::value, "");
 
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 
 static_assert(is_simd_mask_v, "");
 static_assert(is_simd_mask_v, "");
Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
@@ -26,8 +26,7 @@
 static_assert(is_simd_flag_type>::value, "");
 static_assert(is_simd_flag_type>::value, "");
 
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 
 static_assert(is_simd_flag_type_v, "");
 static_assert(is_simd_flag_type_v, "");
Index: libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
@@ -67,8 +67,7 @@
 
 static_assert(!is_simd::value, "");
 
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 
 static_assert(is_simd_v, "");
 static_assert(is_simd_v, "");
Index: libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
+++ 

[PATCH] D44656: [libcxx] Add conversions between underlying non-portable types and simd/simd_mask types.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added subscribers: christof, kristof.beyls, sanjoy.
Herald added a reviewer: EricWF.

Currently x86, PowerPC, and ARM are supported.


https://reviews.llvm.org/D44656

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.abi/raw.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.abi/raw.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.abi/raw.pass.cpp
@@ -0,0 +1,122 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.abi]
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+void compile_raw() {
+  static_assert(std::is_same::value,
+"");
+  (void)SimdType(ExpectedRawType());
+  (void)static_cast(SimdType());
+}
+
+int main() {
+#if defined(__AVX__)
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+#elif defined(__SSE2__)
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+#elif defined(__ALTIVEC__) || defined(__VSX__)
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+#elif defined(__ARM_NEON)
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+  compile_raw();
+
+  compile_raw(native_simd())[0])>::type,
+  int8x8_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  int16x4_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  int32x2_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  int64x1_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  uint8x8_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  uint16x4_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  uint32x2_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  uint64x1_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  float32x2_t>();
+
+  compile_raw(native_simd())[0])>::type,
+  float64x1_t>();
+#endif
+}
Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -596,6 +596,17 @@
 #include 
 #include 
 
+#if defined(_LIBCPP_MICROARCH_SSE2)
+#include 
+#if defined(_LIBCPP_MICROARCH_AVX)
+#include 
+#endif
+#elif defined(_LIBCPP_MICROARCH_ALTIVEC)
+#include 
+#elif defined(_LIBCPP_MICROARCH_NEON)
+#include 
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -680,59 +691,91 @@
 _TYPE __attribute__((vector_size(sizeof(_TYPE) * _NUM_ELEMENT)));  \
   }
 
-#define _SPECIALIZE_VEC_EXT_32(_TYPE)   

[PATCH] D41844: [libcxx] implement mask reductions

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139044.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41844

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
@@ -42,13 +42,48 @@
 
 inline int factorial(int n) { return n == 1 ? 1 : n * factorial(n - 1); }
 
-void test_reduce() {
+void test_reduce_simd() {
   int n = (int)native_simd::size();
   assert(reduce(native_simd([](int i) { return i; })) == n * (n - 1) / 2);
   assert(reduce(native_simd([](int i) { return i; }), std::plus()) ==
  n * (n - 1) / 2);
   assert(reduce(native_simd([](int i) { return i + 1; }),
 std::multiplies()) == factorial(n));
 }
 
-int main() { test_reduce(); }
+void test_reduce_mask() {
+  {
+fixed_size_simd a([](int i) { return i; });
+assert(reduce(where(a < 2, a), 0, std::plus()) == 0 + 1);
+assert(reduce(where(a >= 2, a), 1, std::multiplies()) == 2 * 3);
+assert(reduce(where(a >= 2, a)) == 2 + 3);
+assert(reduce(where(a >= 2, a), std::plus()) == 2 + 3);
+assert(reduce(where(a >= 2, a), std::multiplies()) == 2 * 3);
+assert(reduce(where(a >= 2, a), std::bit_and()) == (2 & 3));
+assert(reduce(where(a >= 2, a), std::bit_or()) == (2 | 3));
+assert(reduce(where(a >= 2, a), std::bit_xor()) == (2 ^ 3));
+  }
+  {
+fixed_size_simd_mask a;
+a[0] = false;
+a[1] = true;
+a[2] = true;
+a[3] = false;
+assert(reduce(where(fixed_size_simd_mask(true), a)) == true);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::plus()) == true);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::multiplies()) == false);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::bit_and()) == false);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::bit_or()) == true);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::bit_xor()) == false);
+  }
+}
+
+int main() {
+  test_reduce_simd();
+  test_reduce_mask();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
@@ -20,7 +20,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_hmin() {
+void test_hmin_simd() {
   {
 int a[] = {2, 5, -4, 6};
 assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
@@ -39,4 +39,27 @@
   }
 }
 
-int main() { test_hmin(); }
+void test_hmin_mask() {
+  assert(hmin(where(native_simd_mask(false), native_simd())) ==
+ std::numeric_limits::max());
+  {
+int buffer[] = {2, 5, -4, 6};
+fixed_size_simd a(buffer, element_aligned_tag());
+assert(hmin(where(a >= -4, a)) == -4);
+assert(hmin(where(a > -4, a)) == 2);
+assert(hmin(where(a > 2, a)) == 5);
+assert(hmin(where(a > 5, a)) == 6);
+assert(hmin(where(a > 6, a)) == std::numeric_limits::max());
+  }
+  {
+bool buffer[] = {false, true, true, false};
+fixed_size_simd_mask a(buffer, element_aligned_tag());
+assert(hmin(where(fixed_size_simd_mask(true), a)) == false);
+assert(hmin(where(a, a)) == true);
+  }
+}
+
+int main() {
+  test_hmin_simd();
+  test_hmin_mask();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
@@ -20,7 +20,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_hmax() {
+void test_hmax_simd() {
   {
 int a[] = {2, 5, -4, 6};
 assert(hmax(fixed_size_simd(a, element_aligned_tag())) == 6);
@@ -39,4 +39,34 @@
   }
 }
 
-int main() { test_hmax(); }
+void test_hmax_mask() {
+  assert(hmax(where(native_simd_mask(false), native_simd())) ==
+ std::numeric_limits::min());
+  {
+int buffer[] = {2, 5, -4, 6};
+fixed_size_simd a(buffer, element_aligned_tag());
+assert(hmax(where(a <= 6, a)) == 6);
+assert(hmax(where(a < 6, a)) == 5);
+assert(hmax(where(a < 5, a)) == 2);
+assert(hmax(where(a < 2, a)) == -4);
+assert(hmax(where(a < -4, a)) == std::numeric_limits::min());
+  }
+  {
+bool buffer[] = 

[PATCH] D41756: [libcxx] implement simd_mask<> casts and some horizontal operations.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139042.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41756

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/clamp.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/max.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/min.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/minmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
@@ -50,6 +50,10 @@
 (simd_mask(false) ^ simd_mask(true;
   assert(all_of(simd_mask(false) ==
 (simd_mask(true) ^ simd_mask(true;
+  assert(all_of(!simd(0)));
+  assert(all_of(!simd(0) == simd_mask(true)));
+  assert(none_of(!simd(42)));
+  assert(all_of(!simd(42) == simd_mask(false)));
 }
 
 void test_mutating_opreators() {
Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -39,7 +39,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_split() {
+void test_split_simd() {
   auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
   static_assert(std::tuple_size::value == 3, "");
 
@@ -56,7 +56,24 @@
   assert(std::get<2>(t)[2] == 5);
 }
 
-void test_split_array() {
+void test_split_mask() {
+  auto t = split<1, 2, 3>(fixed_size_simd_mask(true));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0]);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0]);
+  assert(std::get<1>(t)[1]);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0]);
+  assert(std::get<2>(t)[1]);
+  assert(std::get<2>(t)[2]);
+}
+
+void test_split_array_simd() {
   {
 auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
 static_assert(arr.size() == 2, "");
@@ -88,7 +105,38 @@
   }
 }
 
-void compile_split_propagate_abi() {
+void test_split_array_mask() {
+  {
+auto arr = split_by<2>(fixed_size_simd_mask(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+  {
+auto arr = split>(fixed_size_simd(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+}
+
+void compile_split_simd_propagate_abi() {
   using compatible_simd_half =
   simd>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask>;
+  using native_simd_mask_half =
+  simd_mask>;
+
+  static_assert(std::is_same(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split(
+  native_simd_mask())),
+  std::tuple>::value,
+  "");
+
+  

[PATCH] D41422: [libcxx] implement operators and reduction.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139040.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41422

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/clamp.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/max.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/min.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/minmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
@@ -0,0 +1,54 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // reductions [simd.reductions]
+// template >
+// T reduce(const simd&, BinaryOperation = BinaryOperation());
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x,
+// typename V::value_type neutral_element, BinaryOperation binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, plus<> binary_op = plus<>());
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, multiplies<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_and<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_or<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_xor<> binary_op);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+inline int factorial(int n) { return n == 1 ? 1 : n * factorial(n - 1); }
+
+void test_reduce() {
+  int n = (int)native_simd::size();
+  assert(reduce(native_simd([](int i) { return i; })) == n * (n - 1) / 2);
+  assert(reduce(native_simd([](int i) { return i; }), std::plus()) ==
+ n * (n - 1) / 2);
+  assert(reduce(native_simd([](int i) { return i + 1; }),
+std::multiplies()) == factorial(n));
+}
+
+int main() { test_reduce(); }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template  T hmin(const simd&);
+// template  T hmin(const const_where_expression&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_hmin() {
+  {
+int a[] = {2, 5, -4, 6};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {6, 2, 5, -4};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {-4, 6, 2, 5};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {5, -4, 6, 2};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+}
+
+int main() { test_hmin(); }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template  T hmax(const simd&);
+// template  T hmax(const const_where_expression&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void 

[PATCH] D41412: [libcxx] implement concat() and split()

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139038.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41412

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -0,0 +1,125 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// tuple...> split(const simd&);
+//
+// template 
+// tuple...> split(const simd_mask&);
+//
+// template 
+// array split(
+// const simd&);
+//
+// template 
+// array split(
+// const simd_mask&);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd& x);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd_mask& x);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_split() {
+  auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0] == 0);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0] == 1);
+  assert(std::get<1>(t)[1] == 2);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0] == 3);
+  assert(std::get<2>(t)[1] == 4);
+  assert(std::get<2>(t)[2] == 5);
+}
+
+void test_split_array() {
+  {
+auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+  {
+auto arr = split>(
+fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+}
+
+void compile_split_propagate_abi() {
+  using compatible_simd_half =
+  simd>;
+  using native_simd_half =
+  simd>;
+
+  static_assert(
+  std::is_same<
+  decltype(
+  split(simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same(native_simd())),
+   std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(simd())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(native_simd())),
+ std::array>::value,
+"");
+}
+
+int main() {
+  test_split();
+  test_split_array();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
@@ -0,0 +1,97 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// simd + ...)>>
+// concat(const simd&...);
+//
+// template 
+// simd, Abi>>
+// 

[PATCH] D41747: [libcxx] implement simd_mask<> and operators.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139041.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41747

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/default.pass.cpp
  
libcxx/test/std/experimental/simd/simd.mask.cons/fixed_size_conversion.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
@@ -0,0 +1,82 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_to(value_type* mem, Flags) const;
+
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd_mask a;
+  a[0] = false;
+  a[1] = true;
+  a[2] = true;
+  a[3] = false;
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+#endif
+}
+
+int main() { test_store(); }
Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
@@ -0,0 +1,105 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_from(const value_type* mem, Flags);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+
+  not_supported_load((bool*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) bool buffer[] = {false, true, true, false};
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, element_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, vector_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+

[PATCH] D41415: [libcxx] implement casts.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139039.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41415

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
@@ -0,0 +1,56 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// native_simd to_native(const fixed_size_simd&) noexcept;
+//
+// template 
+// native_simd_mask to_native(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_native() {
+  auto v = to_native(
+  fixed_size_simd([](int i) { return i; }));
+  native_simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_native_extension() {
+  auto arr = split_by<32 / native_simd::size()>(
+  to_native(fixed_size_simd([](int i) { return i; })));
+  static_assert(
+  std::is_same::value, "");
+  int v = 0;
+  for (size_t i = 0; i < arr.size(); i++) {
+for (size_t j = 0; j < arr[0].size(); j++) {
+  assert(arr[i][j] == v);
+  v++;
+}
+  }
+}
+
+int main() {
+  test_to_native();
+  test_to_native_extension();
+}
Index: libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
@@ -0,0 +1,40 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// fixed_size_simd>
+// to_fixed_size(const simd&) noexcept;
+//
+// template 
+// fixed_size_simd_mask>
+// to_fixed_size(const simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_fixed_size() {
+  auto v = to_fixed_size(native_simd([](int i) { return i; }));
+  static_assert(std::is_same,
+ decltype(v)>::value,
+"");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == (int)i);
+  }
+}
+
+int main() { test_to_fixed_size(); }
Index: libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
@@ -0,0 +1,55 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template  simd
+// to_compatible(const fixed_size_simd&) noexcept;
+//
+// template  simd_mask
+// to_compatible(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_compatible() {
+  auto v = to_compatible(
+  fixed_size_simd([](int i) { return i; }));
+  simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_compatible_extension() {
+  auto arr = split_by<32 / simd::size()>(
+  to_compatible(fixed_size_simd([](int i) { return i; 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139037.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,92 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,118 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_supported_load((int*)nullptr, int());

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-03-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 139036.
timshen added a comment.
Herald added a subscriber: christof.

Rebase.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,121 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
+!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");

[PATCH] D42983: [clang-tidy] Add readability-simd-intrinsics check.

2018-02-07 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:75
+  // libcxx implementation of std::experimental::simd requires at least C++11.
+  if (!Result.Context->getLangOpts().CPlusPlus11)
+return;

MaskRay wrote:
> lebedev.ri wrote:
> > Is it reasonable to suggest to use ``?
> > I would guess it should be `CPlusPlus2a`
> Added a check-specific option `readability-simd-intrinsics.Experiment`.
> 
> 
> Is it reasonable to suggest to use ?

I think there are two approaches to proceed:
1) We just warn the users, but don't suggest  fixes.
2) We warn and suggest  fixes, but only when a flag is 
turned on (off by default). The flag documentation should clearly include 
"suggest  API".

I'm not sure which one fits better.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42983



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42983: [clang-tidy] Add readability-simd-intrinsics check.

2018-02-06 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:34
+// [simd.binary]
+{"add", "std::experimental::simd::operator+"},
+{"sub", "std::experimental::simd::operator-"},

Technically, std::experimental::simd::operator+ (an all other binary operators) 
don't exist, as they are free functions, not member functions. `operator+ for 
std::experimental::simd objects` do exist.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42983



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42983: [clang-tidy] Add readability-simd-intrinsics check.

2018-02-06 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:24
+  if (Name.startswith("vec_"))
+Name = Name.substr(4);
+  else

timshen wrote:
> Can you either find or create a wrapper for this?
> 
>   bool StripPrefix(StringRef Prefix, StringRef& S) {
> if (S.startwith(Prefix)) {
>   S = S.substr(Prefix.size());
>   return true;
> }
> return false;
>   }
> 
> Which is a huge readability boost and DRY.
Found it: StringRef::consume_front()


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42983



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42983: [clang-tidy] Add readability-simd-intrinsics check.

2018-02-06 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:24
+  if (Name.startswith("vec_"))
+Name = Name.substr(4);
+  else

Can you either find or create a wrapper for this?

  bool StripPrefix(StringRef Prefix, StringRef& S) {
if (S.startwith(Prefix)) {
  S = S.substr(Prefix.size());
  return true;
}
return false;
  }

Which is a huge readability boost and DRY.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42983



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42983: [clang-tidy] Add readability-simd-intrinsics check.

2018-02-06 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: clang-tidy/readability/SIMDIntrinsicsCheck.cpp:22
+
+static StringRef CheckPPC(StringRef Name) {
+  if (Name.startswith("vec_"))

"Check" usually indicates to return a bool, but what it actually returns is a 
possible mapped result based on the input. Maybe some name like "TrySuggestPPC"?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D42983



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42510: [libcxx] Always allow temporary binding when __reference_binds_to_temporary doesn't exist

2018-01-24 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: EricWF, rsmith.
Herald added a subscriber: sanjoy.

This is a follow-up to https://reviews.llvm.org/D41977.


https://reviews.llvm.org/D42510

Files:
  libcxx/include/tuple


Index: libcxx/include/tuple
===
--- libcxx/include/tuple
+++ libcxx/include/tuple
@@ -175,6 +175,8 @@
 static constexpr bool __can_bind_reference() {
 #if __has_keyword(__reference_binds_to_temporary)
   return !__reference_binds_to_temporary(_Hp, _Tp);
+#else
+  return true;
 #endif
 }
 


Index: libcxx/include/tuple
===
--- libcxx/include/tuple
+++ libcxx/include/tuple
@@ -175,6 +175,8 @@
 static constexpr bool __can_bind_reference() {
 #if __has_keyword(__reference_binds_to_temporary)
   return !__reference_binds_to_temporary(_Hp, _Tp);
+#else
+  return true;
 #endif
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41977: [libc++] Fix PR20855 -- libc++ incorrectly diagnoses illegal reference binding in std::tuple.

2018-01-24 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

Created https://reviews.llvm.org/D42510 for discussion. I'm not sure if it's a 
good idea, though.


Repository:
  rCXX libc++

https://reviews.llvm.org/D41977



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41977: [libc++] Fix PR20855 -- libc++ incorrectly diagnoses illegal reference binding in std::tuple.

2018-01-24 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

`__can_bind_reference()` doesn't return anything when 
__reference_binds_to_temporary doesn't exist. This causes builds break with old 
compilers.

Should it just return true if __reference_binds_to_temporary doesn't exist?


Repository:
  rCXX libc++

https://reviews.llvm.org/D41977



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41845: [libcxx] clean up and complete

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129017.
timshen added a comment.

Update on template variable #ifdefs in tests.


https://reviews.llvm.org/D41845

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/memory_alignment.pass.cpp
@@ -0,0 +1,67 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct memory_alignment;
+// template 
+// inline constexpr size_t memory_alignment_v = memory_alignment::value;
+
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(std::is_same>::value)>::value,
+  "");
+static_assert(
+std::is_same, int>::value)>::value,
+"");
+static_assert(
+std::is_same<
+const size_t,
+decltype(memory_alignment::value)>::value,
+"");
+static_assert(
+std::is_same>::value)>::value,
+"");
+static_assert(
+std::is_same,
+ bool>::value)>::value,
+"");
+
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
+
+static_assert(
+std::is_same>)>::value,
+"");
+static_assert(std::is_same, int>)>::value,
+  "");
+static_assert(
+std::is_same, unsigned int>)>::value,
+"");
+static_assert(std::is_same>)>::value,
+  "");
+static_assert(
+std::is_same, bool>)>::value,
+"");
+
+#endif
+
+int main() {}
Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -67,8 +67,7 @@
 
 static_assert(!is_simd_mask::value, "");
 
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 
 static_assert(is_simd_mask_v, "");
 static_assert(is_simd_mask_v, "");
Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
@@ -26,8 +26,7 @@
 static_assert(is_simd_flag_type>::value, "");
 static_assert(is_simd_flag_type>::value, "");
 
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 
 static_assert(is_simd_flag_type_v, "");
 static_assert(is_simd_flag_type_v, "");
Index: libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
@@ -67,8 +67,7 @@
 
 static_assert(!is_simd::value, "");
 
-#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
-!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+#if TEST_STD_VER >= 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 
 static_assert(is_simd_v, "");
 static_assert(is_simd_v, "");
Index: libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
+++ 

[PATCH] D41756: [libcxx] implement simd_mask<> casts and some horizontal operations.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129013.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41756

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -39,7 +39,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_split() {
+void test_split_simd() {
   auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
   static_assert(std::tuple_size::value == 3, "");
 
@@ -56,7 +56,24 @@
   assert(std::get<2>(t)[2] == 5);
 }
 
-void test_split_array() {
+void test_split_mask() {
+  auto t = split<1, 2, 3>(fixed_size_simd_mask(true));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0]);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0]);
+  assert(std::get<1>(t)[1]);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0]);
+  assert(std::get<2>(t)[1]);
+  assert(std::get<2>(t)[2]);
+}
+
+void test_split_array_simd() {
   {
 auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
 static_assert(arr.size() == 2, "");
@@ -88,7 +105,38 @@
   }
 }
 
-void compile_split_propagate_abi() {
+void test_split_array_mask() {
+  {
+auto arr = split_by<2>(fixed_size_simd_mask(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+  {
+auto arr = split>(fixed_size_simd(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+}
+
+void compile_split_simd_propagate_abi() {
   using compatible_simd_half =
   simd>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask>;
+  using native_simd_mask_half =
+  simd_mask>;
+
+  static_assert(std::is_same(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split(
+  native_simd_mask())),
+  std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(simd_mask())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(native_simd_mask())),
+ std::array>::value,
+"");
+}
+
 int main() {
-  test_split();
-  test_split_array();
+  test_split_simd();
+  test_split_mask();
+  test_split_array_simd();
+  test_split_array_mask();
 }
Index: libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
@@ -0,0 +1,189 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // reductions [simd.mask.reductions]

[PATCH] D41747: [libcxx] implement simd_mask<> and operators.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129012.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41747

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/default.pass.cpp
  
libcxx/test/std/experimental/simd/simd.mask.cons/fixed_size_conversion.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
@@ -0,0 +1,82 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_to(value_type* mem, Flags) const;
+
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd_mask a;
+  a[0] = false;
+  a[1] = true;
+  a[2] = true;
+  a[3] = false;
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+#endif
+}
+
+int main() { test_store(); }
Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
@@ -0,0 +1,105 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_from(const value_type* mem, Flags);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+
+  not_supported_load((bool*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) bool buffer[] = {false, true, true, false};
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, element_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, vector_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+assert(!a[3]);
+  }
+ 

[PATCH] D41422: [libcxx] implement operators and reduction.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129011.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41422

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/clamp.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/max.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/min.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/minmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
@@ -0,0 +1,54 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // reductions [simd.reductions]
+// template >
+// T reduce(const simd&, BinaryOperation = BinaryOperation());
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x,
+// typename V::value_type neutral_element, BinaryOperation binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, plus<> binary_op = plus<>());
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, multiplies<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_and<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_or<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_xor<> binary_op);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+inline int factorial(int n) { return n == 1 ? 1 : n * factorial(n - 1); }
+
+void test_reduce() {
+  int n = (int)native_simd::size();
+  assert(reduce(native_simd([](int i) { return i; })) == n * (n - 1) / 2);
+  assert(reduce(native_simd([](int i) { return i; }), std::plus()) ==
+ n * (n - 1) / 2);
+  assert(reduce(native_simd([](int i) { return i + 1; }),
+std::multiplies()) == factorial(n));
+}
+
+int main() { test_reduce(); }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template  T hmin(const simd&);
+// template  T hmin(const const_where_expression&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_hmin() {
+  {
+int a[] = {2, 5, -4, 6};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {6, 2, 5, -4};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {-4, 6, 2, 5};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {5, -4, 6, 2};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+}
+
+int main() { test_hmin(); }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template  T hmax(const simd&);
+// template  T hmax(const const_where_expression&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_hmax() {
+  {
+int a[] = {2, 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129007.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,121 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
+!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");

[PATCH] D41415: [libcxx] implement casts.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129010.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41415

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
@@ -0,0 +1,56 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// native_simd to_native(const fixed_size_simd&) noexcept;
+//
+// template 
+// native_simd_mask to_native(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_native() {
+  auto v = to_native(
+  fixed_size_simd([](int i) { return i; }));
+  native_simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_native_extension() {
+  auto arr = split_by<32 / native_simd::size()>(
+  to_native(fixed_size_simd([](int i) { return i; })));
+  static_assert(
+  std::is_same::value, "");
+  int v = 0;
+  for (size_t i = 0; i < arr.size(); i++) {
+for (size_t j = 0; j < arr[0].size(); j++) {
+  assert(arr[i][j] == v);
+  v++;
+}
+  }
+}
+
+int main() {
+  test_to_native();
+  test_to_native_extension();
+}
Index: libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
@@ -0,0 +1,40 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// fixed_size_simd>
+// to_fixed_size(const simd&) noexcept;
+//
+// template 
+// fixed_size_simd_mask>
+// to_fixed_size(const simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_fixed_size() {
+  auto v = to_fixed_size(native_simd([](int i) { return i; }));
+  static_assert(std::is_same,
+ decltype(v)>::value,
+"");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == (int)i);
+  }
+}
+
+int main() { test_to_fixed_size(); }
Index: libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
@@ -0,0 +1,55 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template  simd
+// to_compatible(const fixed_size_simd&) noexcept;
+//
+// template  simd_mask
+// to_compatible(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_compatible() {
+  auto v = to_compatible(
+  fixed_size_simd([](int i) { return i; }));
+  simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_compatible_extension() {
+  auto arr = split_by<32 / simd::size()>(
+  to_compatible(fixed_size_simd([](int i) { return i; })));
+  

[PATCH] D41412: [libcxx] implement concat() and split()

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129009.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41412

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -0,0 +1,125 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// tuple...> split(const simd&);
+//
+// template 
+// tuple...> split(const simd_mask&);
+//
+// template 
+// array split(
+// const simd&);
+//
+// template 
+// array split(
+// const simd_mask&);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd& x);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd_mask& x);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_split() {
+  auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0] == 0);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0] == 1);
+  assert(std::get<1>(t)[1] == 2);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0] == 3);
+  assert(std::get<2>(t)[1] == 4);
+  assert(std::get<2>(t)[2] == 5);
+}
+
+void test_split_array() {
+  {
+auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+  {
+auto arr = split>(
+fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+}
+
+void compile_split_propagate_abi() {
+  using compatible_simd_half =
+  simd>;
+  using native_simd_half =
+  simd>;
+
+  static_assert(
+  std::is_same<
+  decltype(
+  split(simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same(native_simd())),
+   std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(simd())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(native_simd())),
+ std::array>::value,
+"");
+}
+
+int main() {
+  test_split();
+  test_split_array();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
@@ -0,0 +1,80 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// simd + ...)>>
+// concat(const simd&...);
+//
+// template 
+// simd, Abi>>
+// concat(const std::array, N>& 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129008.
timshen added a comment.

Rebased.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,92 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,118 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_supported_load((int*)nullptr, int());
+}
+
+void test_load() {
+  

[PATCH] D41845: [libcxx] clean up and complete

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 129006.
timshen added a comment.

Implement memory_alignment.


https://reviews.llvm.org/D41845

Files:
  libcxx/include/experimental/simd

Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -1061,10 +1061,18 @@
   "Element type should be vectorizable");
 };
 
-// TODO: implement it.
-template 
+template 
 struct memory_alignment;
 
+// TODO: May extend this after implementing vector_aligned.
+template 
+struct memory_alignment, _Up>
+: std::integral_constant)> {};
+
+template 
+struct memory_alignment, bool>
+: std::integral_constant)> {};
+
 #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 template >
 _LIBCPP_INLINE_VAR constexpr size_t simd_size_v = simd_size<_Tp, _Abi>::value;
@@ -1522,11 +1530,11 @@
   return __m.size();
 }
 
-bool all_of(bool __v) noexcept { return __v; }
-bool any_of(bool __v) noexcept { return __v; }
-bool none_of(bool __v) noexcept { return !__v; }
+bool all_of(bool __val) noexcept { return __val; }
+bool any_of(bool __val) noexcept { return __val; }
+bool none_of(bool __val) noexcept { return !__val; }
 bool some_of(bool) noexcept { return false; }
-int popcount(bool __v) noexcept { return __v; }
+int popcount(bool __val) noexcept { return __val; }
 int find_first_set(bool) noexcept { return 0; }
 int find_last_set(bool) noexcept { return 0; }
 
@@ -1681,9 +1689,9 @@
   template ()>::type>
   simd(_Up&& __rv) {
-auto __v = static_cast<_Tp>(__rv);
+auto __val = static_cast<_Tp>(__rv);
 for (size_t __i = 0; __i < size(); __i++) {
-  (*this)[__i] = __v;
+  (*this)[__i] = __val;
 }
   }
 
@@ -1987,9 +1995,9 @@
   simd_mask() = default;
 
   // broadcast constructor
-  explicit simd_mask(value_type __value) noexcept {
+  explicit simd_mask(value_type __val) noexcept {
 for (size_t __i = 0; __i < size(); __i++) {
-  (*this)[__i] = __value;
+  (*this)[__i] = __val;
 }
   }
 
@@ -2009,6 +2017,7 @@
   template ::value>::type>
   simd_mask(const value_type* __buffer, _Flags) {
+// TODO: optimize for overaligned flags
 for (size_t __i = 0; __i < size(); __i++) {
   (*this)[__i] = __buffer[__i];
 }
@@ -2024,6 +2033,7 @@
   template 
   typename std::enable_if::value>::type
   copy_to(value_type* __buffer, _Flags) const {
+// TODO: optimize for overaligned flags
 for (size_t __i = 0; __i < size(); __i++) {
   __buffer[__i] = (*this)[__i];
 }
@@ -2093,6 +2103,7 @@
 template 
 void __mask_copy_to(const simd<_Tp, _Abi>& __v, const simd_mask<_Tp, _Abi>& __m,
 _Up* __buffer, _Flags) {
+  // TODO: optimize for overaligned flags
   for (size_t __i = 0; __i < __v.size(); __i++) {
 if (__m[__i]) {
   __buffer[__i] = static_cast<_Up>(__v[__i]);
@@ -2103,17 +2114,18 @@
 template 
 void __mask_copy_to(const simd_mask<_Tp, _Abi>& __v,
 const simd_mask<_Tp, _Abi>& __m, _Up* __buffer, _Flags) {
+  // TODO: optimize based on bool's bit pattern.
   for (size_t __i = 0; __i < __v.size(); __i++) {
 if (__m[__i]) {
   __buffer[__i] = static_cast<_Up>(__v[__i]);
 }
   }
 }
 
 template 
-void __mask_copy_to(_Tp __v, bool __m, _Up* __buffer, _Flags) {
+void __mask_copy_to(_Tp __val, bool __m, _Up* __buffer, _Flags) {
   if (__m) {
-*__buffer = static_cast<_Up>(__v);
+*__buffer = static_cast<_Up>(__val);
   }
 }
 
@@ -2141,9 +2153,9 @@
 }
 
 template 
-void __mask_copy_from(_Tp& __v, bool __m, const _Up* __buffer, _Flags) {
+void __mask_copy_from(_Tp& __val, bool __m, const _Up* __buffer, _Flags) {
   if (__m) {
-__v = static_cast<_Tp>(*__buffer);
+__val = static_cast<_Tp>(*__buffer);
   }
 }
 
@@ -2493,6 +2505,8 @@
   __w.__v_, __w.__m_));
 }
 
+// TODO: Implement  functions for simd.
+
 _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
 
 #endif /* _LIBCPP_EXPERIMENTAL_SIMD */
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41845: [libcxx] clean up and complete

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

The cleanup patch adds sevreal TODOs for the following unimplemented
features:
*) aligned load
*) simd<> version of  functions

This patch declares the completion of my implementation of
.


https://reviews.llvm.org/D41845

Files:
  libcxx/include/experimental/simd

Index: libcxx/include/experimental/simd
===
--- libcxx/include/experimental/simd
+++ libcxx/include/experimental/simd
@@ -1522,11 +1522,11 @@
   return __m.size();
 }
 
-bool all_of(bool __v) noexcept { return __v; }
-bool any_of(bool __v) noexcept { return __v; }
-bool none_of(bool __v) noexcept { return !__v; }
+bool all_of(bool __val) noexcept { return __val; }
+bool any_of(bool __val) noexcept { return __val; }
+bool none_of(bool __val) noexcept { return !__val; }
 bool some_of(bool) noexcept { return false; }
-int popcount(bool __v) noexcept { return __v; }
+int popcount(bool __val) noexcept { return __val; }
 int find_first_set(bool) noexcept { return 0; }
 int find_last_set(bool) noexcept { return 0; }
 
@@ -1681,9 +1681,9 @@
   template ()>::type>
   simd(_Up&& __rv) {
-auto __v = static_cast<_Tp>(__rv);
+auto __val = static_cast<_Tp>(__rv);
 for (size_t __i = 0; __i < size(); __i++) {
-  (*this)[__i] = __v;
+  (*this)[__i] = __val;
 }
   }
 
@@ -1987,9 +1987,9 @@
   simd_mask() = default;
 
   // broadcast constructor
-  explicit simd_mask(value_type __value) noexcept {
+  explicit simd_mask(value_type __val) noexcept {
 for (size_t __i = 0; __i < size(); __i++) {
-  (*this)[__i] = __value;
+  (*this)[__i] = __val;
 }
   }
 
@@ -2009,6 +2009,7 @@
   template ::value>::type>
   simd_mask(const value_type* __buffer, _Flags) {
+// TODO: optimize for overaligned flags
 for (size_t __i = 0; __i < size(); __i++) {
   (*this)[__i] = __buffer[__i];
 }
@@ -2024,6 +2025,7 @@
   template 
   typename std::enable_if::value>::type
   copy_to(value_type* __buffer, _Flags) const {
+// TODO: optimize for overaligned flags
 for (size_t __i = 0; __i < size(); __i++) {
   __buffer[__i] = (*this)[__i];
 }
@@ -2093,6 +2095,7 @@
 template 
 void __mask_copy_to(const simd<_Tp, _Abi>& __v, const simd_mask<_Tp, _Abi>& __m,
 _Up* __buffer, _Flags) {
+  // TODO: optimize for overaligned flags
   for (size_t __i = 0; __i < __v.size(); __i++) {
 if (__m[__i]) {
   __buffer[__i] = static_cast<_Up>(__v[__i]);
@@ -2103,17 +2106,18 @@
 template 
 void __mask_copy_to(const simd_mask<_Tp, _Abi>& __v,
 const simd_mask<_Tp, _Abi>& __m, _Up* __buffer, _Flags) {
+  // TODO: optimize based on bool's bit pattern.
   for (size_t __i = 0; __i < __v.size(); __i++) {
 if (__m[__i]) {
   __buffer[__i] = static_cast<_Up>(__v[__i]);
 }
   }
 }
 
 template 
-void __mask_copy_to(_Tp __v, bool __m, _Up* __buffer, _Flags) {
+void __mask_copy_to(_Tp __val, bool __m, _Up* __buffer, _Flags) {
   if (__m) {
-*__buffer = static_cast<_Up>(__v);
+*__buffer = static_cast<_Up>(__val);
   }
 }
 
@@ -2141,9 +2145,9 @@
 }
 
 template 
-void __mask_copy_from(_Tp& __v, bool __m, const _Up* __buffer, _Flags) {
+void __mask_copy_from(_Tp& __val, bool __m, const _Up* __buffer, _Flags) {
   if (__m) {
-__v = static_cast<_Tp>(*__buffer);
+__val = static_cast<_Tp>(*__buffer);
   }
 }
 
@@ -2493,6 +2497,8 @@
   __w.__v_, __w.__m_));
 }
 
+// TODO: Implement  functions for simd.
+
 _LIBCPP_END_NAMESPACE_EXPERIMENTAL_SIMD
 
 #endif /* _LIBCPP_EXPERIMENTAL_SIMD */
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41844: [libcxx] implement mask reductions

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

This is not efficiently implemented

  typename V::value_type
  reduce(const const_where_expression ,
 typename V::value_type neutral_element, BinaryOperation binary_op);

as we don't know the "identity value" of binary_op, where "identity
value" id has the following characteristic:

  binary_op(id, x) == binary_op(x, id) == x, for all x.

The best we can do is to compile-time dispatch BinaryOperation for
binary std:: operations.

To make it efficient, users need to provide the identity value for their
binary_op. We can add this library extension in the future.


https://reviews.llvm.org/D41844

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
@@ -42,13 +42,48 @@
 
 inline int factorial(int n) { return n == 1 ? 1 : n * factorial(n - 1); }
 
-void test_reduce() {
+void test_reduce_simd() {
   int n = (int)native_simd::size();
   assert(reduce(native_simd([](int i) { return i; })) == n * (n - 1) / 2);
   assert(reduce(native_simd([](int i) { return i; }), std::plus()) ==
  n * (n - 1) / 2);
   assert(reduce(native_simd([](int i) { return i + 1; }),
 std::multiplies()) == factorial(n));
 }
 
-int main() { test_reduce(); }
+void test_reduce_mask() {
+  {
+fixed_size_simd a([](int i) { return i; });
+assert(reduce(where(a < 2, a), 42, std::plus()) == 42 + 0 + 1);
+assert(reduce(where(a >= 2, a), 42, std::multiplies()) == 42 * 2 * 3);
+assert(reduce(where(a >= 2, a)) == 2 + 3);
+assert(reduce(where(a >= 2, a), std::plus()) == 2 + 3);
+assert(reduce(where(a >= 2, a), std::multiplies()) == 2 * 3);
+assert(reduce(where(a >= 2, a), std::bit_and()) == (2 & 3));
+assert(reduce(where(a >= 2, a), std::bit_or()) == (2 | 3));
+assert(reduce(where(a >= 2, a), std::bit_xor()) == (2 ^ 3));
+  }
+  {
+fixed_size_simd_mask a;
+a[0] = false;
+a[1] = true;
+a[2] = true;
+a[3] = false;
+assert(reduce(where(fixed_size_simd_mask(true), a)) == true);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::plus()) == true);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::multiplies()) == false);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::bit_and()) == false);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::bit_or()) == true);
+assert(reduce(where(fixed_size_simd_mask(true), a),
+  std::bit_xor()) == false);
+  }
+}
+
+int main() {
+  test_reduce_simd();
+  test_reduce_mask();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
@@ -20,7 +20,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_hmin() {
+void test_hmin_simd() {
   {
 int a[] = {2, 5, -4, 6};
 assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
@@ -39,4 +39,27 @@
   }
 }
 
-int main() { test_hmin(); }
+void test_hmin_mask() {
+  assert(hmin(where(native_simd_mask(false), native_simd())) ==
+ std::numeric_limits::max());
+  {
+int buffer[] = {2, 5, -4, 6};
+fixed_size_simd a(buffer, element_aligned_tag());
+assert(hmin(where(a >= -4, a)) == -4);
+assert(hmin(where(a > -4, a)) == 2);
+assert(hmin(where(a > 2, a)) == 5);
+assert(hmin(where(a > 5, a)) == 6);
+assert(hmin(where(a > 6, a)) == std::numeric_limits::max());
+  }
+  {
+bool buffer[] = {false, true, true, false};
+fixed_size_simd_mask a(buffer, element_aligned_tag());
+assert(hmin(where(fixed_size_simd_mask(true), a)) == false);
+assert(hmin(where(a, a)) == true);
+  }
+}
+
+int main() {
+  test_hmin_simd();
+  test_hmin_mask();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
@@ -20,7 +20,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_hmax() {
+void test_hmax_simd() {
   {
 int a[] = {2, 5, -4, 6};
 assert(hmax(fixed_size_simd

[PATCH] D41843: [libcxx] implement where expressions.

2018-01-08 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

Where expressions have three cases:
*) const_where_expression, simd<...>>, we store two
references to the mask and the simd<> value.
*) const_where_expression, simd_mask<...>>, we store two
references to the mask and the simd_mask<> value.
*) const_where_expression, we store a bool by value, and _Tp
by reference.


https://reviews.llvm.org/D41843

Files:
  libcxx/include/experimental/simd
  
libcxx/test/std/experimental/simd/simd.whereexpr/const_where_expression.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where.pass.cpp
  libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.whereexpr/where_expression.pass.cpp
@@ -0,0 +1,366 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // [simd.whereexpr]
+// template 
+// class where_expression : public const_where_expression {
+// public:
+//   where_expression(const where_expression&) = delete;
+//   where_expression& operator=(const where_expression&) = delete;
+//   template  void operator=(U&& x);
+//   template  void operator+=(U&& x);
+//   template  void operator-=(U&& x);
+//   template  void operator*=(U&& x);
+//   template  void operator/=(U&& x);
+//   template  void operator%=(U&& x);
+//   template  void operator&=(U&& x);
+//   template  void operator|=(U&& x);
+//   template  void operator^=(U&& x);
+//   template  void operator<<=(U&& x);
+//   template  void operator>>=(U&& x);
+//   void operator++();
+//   void operator++(int);
+//   void operator--();
+//   void operator--(int);
+//   template  void copy_from(const U* mem, Flags);
+// };
+
+#include 
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_operators_simd() {
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) = -1;
+assert(a[0] == -1);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) = fixed_size_simd(-1);
+assert(a[0] == -1);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) += -1;
+assert(a[0] == -1);
+assert(a[1] == 0);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) += fixed_size_simd(-1);
+assert(a[0] == -1);
+assert(a[1] == 0);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) -= -1;
+assert(a[0] == 1);
+assert(a[1] == 2);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) -= fixed_size_simd(-1);
+assert(a[0] == 1);
+assert(a[1] == 2);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) *= -1;
+assert(a[0] == 0);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a < 2, a) *= fixed_size_simd(-1);
+assert(a[0] == 0);
+assert(a[1] == -1);
+assert(a[2] == 2);
+assert(a[3] == 3);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) /= 2;
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 3);
+assert(a[3] == 4);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) /= fixed_size_simd(2);
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 3);
+assert(a[3] == 4);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a % 2 == 1, a) /=
+fixed_size_simd([](int i) { return i % 2 * 2; });
+assert(a[0] == 0);
+assert(a[1] == 0);
+assert(a[2] == 2);
+assert(a[3] == 1);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+where(a >= 6, a) %= 2;
+assert(a[0] == 0);
+assert(a[1] == 3);
+assert(a[2] == 0);
+assert(a[3] == 1);
+  }
+  {
+fixed_size_simd a([](int i) { return 3 * i; });
+

[PATCH] D41756: [libcxx] implement simd_mask<> casts and some horizontal operations.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128706.
timshen added a comment.

Add tests to boolean version of the horizontal operations.


https://reviews.llvm.org/D41756

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -39,7 +39,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_split() {
+void test_split_simd() {
   auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
   static_assert(std::tuple_size::value == 3, "");
 
@@ -56,7 +56,24 @@
   assert(std::get<2>(t)[2] == 5);
 }
 
-void test_split_array() {
+void test_split_mask() {
+  auto t = split<1, 2, 3>(fixed_size_simd_mask(true));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0]);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0]);
+  assert(std::get<1>(t)[1]);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0]);
+  assert(std::get<2>(t)[1]);
+  assert(std::get<2>(t)[2]);
+}
+
+void test_split_array_simd() {
   {
 auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
 static_assert(arr.size() == 2, "");
@@ -88,7 +105,38 @@
   }
 }
 
-void compile_split_propagate_abi() {
+void test_split_array_mask() {
+  {
+auto arr = split_by<2>(fixed_size_simd_mask(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+  {
+auto arr = split>(fixed_size_simd(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+}
+
+void compile_split_simd_propagate_abi() {
   using compatible_simd_half =
   simd>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask>;
+  using native_simd_mask_half =
+  simd_mask>;
+
+  static_assert(std::is_same(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split(
+  native_simd_mask())),
+  std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(simd_mask())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(native_simd_mask())),
+ std::array>::value,
+"");
+}
+
 int main() {
-  test_split();
-  test_split_array();
+  test_split_simd();
+  test_split_mask();
+  test_split_array_simd();
+  test_split_array_mask();
 }
Index: libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
@@ -0,0 +1,189 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+

[PATCH] D41756: [libcxx] implement simd_mask<> casts and some horizontal operations.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

popcount is implemented in terms of for loop. On x86, it can be specialized to 
_mm_movemask_* + __builtin_popcountll() in the future.


https://reviews.llvm.org/D41756

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -39,7 +39,7 @@
 
 using namespace std::experimental::parallelism_v2;
 
-void test_split() {
+void test_split_simd() {
   auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
   static_assert(std::tuple_size::value == 3, "");
 
@@ -56,7 +56,24 @@
   assert(std::get<2>(t)[2] == 5);
 }
 
-void test_split_array() {
+void test_split_mask() {
+  auto t = split<1, 2, 3>(fixed_size_simd_mask(true));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0]);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0]);
+  assert(std::get<1>(t)[1]);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0]);
+  assert(std::get<2>(t)[1]);
+  assert(std::get<2>(t)[2]);
+}
+
+void test_split_array_simd() {
   {
 auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
 static_assert(arr.size() == 2, "");
@@ -88,7 +105,38 @@
   }
 }
 
-void compile_split_propagate_abi() {
+void test_split_array_mask() {
+  {
+auto arr = split_by<2>(fixed_size_simd_mask(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+  {
+auto arr = split>(fixed_size_simd(true));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0]);
+assert(arr[0][1]);
+assert(arr[0][2]);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0]);
+assert(arr[1][1]);
+assert(arr[1][2]);
+  }
+}
+
+void compile_split_simd_propagate_abi() {
   using compatible_simd_half =
   simd>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask>;
+  using native_simd_mask_half =
+  simd_mask>;
+
+  static_assert(std::is_same(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split(
+  native_simd_mask())),
+  std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(simd_mask())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(native_simd_mask())),
+ std::array>::value,
+"");
+}
+
 int main() {
-  test_split();
-  test_split_array();
+  test_split_simd();
+  test_split_mask();
+  test_split_array_simd();
+  test_split_array_mask();
 }
Index: libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/mask.pass.cpp
@@ -0,0 +1,171 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//

[PATCH] D41747: [libcxx] implement simd_mask<> and operators.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128687.
timshen added a comment.

Remove unintended binary file.


https://reviews.llvm.org/D41747

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/default.pass.cpp
  
libcxx/test/std/experimental/simd/simd.mask.cons/fixed_size_conversion.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
@@ -0,0 +1,82 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_to(value_type* mem, Flags) const;
+
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd_mask a;
+  a[0] = false;
+  a[1] = true;
+  a[2] = true;
+  a[3] = false;
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+#endif
+}
+
+int main() { test_store(); }
Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
@@ -0,0 +1,105 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_from(const value_type* mem, Flags);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+
+  not_supported_load((bool*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) bool buffer[] = {false, true, true, false};
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, element_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, vector_aligned_tag());
+assert(!a[0]);
+assert(a[1]);
+assert(a[2]);
+

[PATCH] D41747: [libcxx] implement simd_mask<> and operators.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

simd_mask stores a simd, where U has the same length of T, but 
is an unsigned integer. Then all functionality of simd_mask can be 
implemented in terms of simd.

For reference, Vc seems to store an int as a bitset. This results into 
inefficient code:

- https://godbolt.org/g/e4uDPM storing int is slow.
- https://godbolt.org/g/hT7SYT storing simd has zero cost.


https://reviews.llvm.org/D41747

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.access/a.out
  libcxx/test/std/experimental/simd/simd.mask.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/default.pass.cpp
  
libcxx/test/std/experimental/simd/simd.mask.cons/fixed_size_conversion.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/store.pass.cpp
@@ -0,0 +1,82 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_to(value_type* mem, Flags) const;
+
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd_mask a;
+  a[0] = false;
+  a[1] = true;
+  a[2] = true;
+  a[3] = false;
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+  {
+alignas(32) bool buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(!buffer[0]);
+assert(buffer[1]);
+assert(buffer[2]);
+assert(!buffer[3]);
+  }
+#endif
+}
+
+int main() { test_store(); }
Index: libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mask.mem/load.pass.cpp
@@ -0,0 +1,105 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.mask.copy]
+// template  void copy_from(const value_type* mem, Flags);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, element_aligned_tag());
+  supported_load((bool*)nullptr, 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128679.
timshen added a comment.

Rebase.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,121 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
+!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2018-01-04 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 128680.
timshen added a comment.

Rebase. Also modify the simd reference implementation to separate the stored 
type and value_type (which could be bool later).


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,92 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned<32>);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,118 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  

[PATCH] D41386: [libunwind][PPC64] Port to ppc64le - initial version

2018-01-02 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

In https://reviews.llvm.org/D41386#966189, @mstorsjo wrote:

> In https://reviews.llvm.org/D41386#966187, @timshen wrote:
>
> > The static_assert on line 1189 fails with the following build on x86:
> >
> >   cmake -GNinja -DLIBUNWIND_ENABLE_CROSS_UNWINDING=ON 
> > -DLLVM_PATH=$PATH_TO_LLVM $PATH_TO_LIBUNWIND && ninja libunwind.a
> >   
> >
> > It seems that 136 in `# define _LIBUNWIND_CONTEXT_SIZE 136` is too small. 
> > Reverting the patch for now.
>
>
> Actually, I can fix this directly without having to revert, if you give me a 
> couple minutes.


Ah sorry, didn't see this earlier. It's already reverted. :(


Repository:
  rL LLVM

https://reviews.llvm.org/D41386



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41386: [libunwind][PPC64] Port to ppc64le - initial version

2018-01-02 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

The static_assert on line 1189 fails with the following build on x86:

  cmake -GNinja -DLIBUNWIND_ENABLE_CROSS_UNWINDING=ON -DLLVM_PATH=$PATH_TO_LLVM 
$PATH_TO_LIBUNWIND && ninja libunwind.a

It seems that 136 in `# define _LIBUNWIND_CONTEXT_SIZE 136` is too small. 
Reverting the patch for now.


Repository:
  rL LLVM

https://reviews.llvm.org/D41386



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41415: [libcxx] implement casts.

2017-12-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127639.
timshen added a comment.

s/_LIBCPP_HAS_VECTOR_EXTENSION/_LIBCPP_HAS_NO_VECTOR_EXTENSION/


https://reviews.llvm.org/D41415

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
@@ -0,0 +1,56 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// native_simd to_native(const fixed_size_simd&) noexcept;
+//
+// template 
+// native_simd_mask to_native(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_native() {
+  auto v = to_native(
+  fixed_size_simd([](int i) { return i; }));
+  native_simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_native_extension() {
+  auto arr = split_by<32 / native_simd::size()>(
+  to_native(fixed_size_simd([](int i) { return i; })));
+  static_assert(
+  std::is_same::value, "");
+  int v = 0;
+  for (size_t i = 0; i < arr.size(); i++) {
+for (size_t j = 0; j < arr[0].size(); j++) {
+  assert(arr[i][j] == v);
+  v++;
+}
+  }
+}
+
+int main() {
+  test_to_native();
+  test_to_native_extension();
+}
Index: libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
@@ -0,0 +1,40 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// fixed_size_simd>
+// to_fixed_size(const simd&) noexcept;
+//
+// template 
+// fixed_size_simd_mask>
+// to_fixed_size(const simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_fixed_size() {
+  auto v = to_fixed_size(native_simd([](int i) { return i; }));
+  static_assert(std::is_same,
+ decltype(v)>::value,
+"");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == (int)i);
+  }
+}
+
+int main() { test_to_fixed_size(); }
Index: libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
@@ -0,0 +1,55 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template  simd
+// to_compatible(const fixed_size_simd&) noexcept;
+//
+// template  simd_mask
+// to_compatible(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_compatible() {
+  auto v = to_compatible(
+  fixed_size_simd([](int i) { return i; }));
+  simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_compatible_extension() {
+  auto arr = split_by<32 / simd::size()>(
+  to_compatible(fixed_size_simd([](int 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2017-12-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127638.
timshen added a comment.

s/_LIBCPP_HAS_VECTOR_EXTENSION/_LIBCPP_HAS_NO_VECTOR_EXTENSION/


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,90 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,116 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_supported_load((int*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) 

[PATCH] D41422: [libcxx] implement operators and reduction.

2017-12-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

This patch completes the implementation of simd<> and related operations.


https://reviews.llvm.org/D41422

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.elementwise/clamp.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/max.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/min.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/minmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.elementwise/operators.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/reduce.pass.cpp
@@ -0,0 +1,54 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // reductions [simd.reductions]
+// template >
+// T reduce(const simd&, BinaryOperation = BinaryOperation());
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x,
+// typename V::value_type neutral_element, BinaryOperation binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, plus<> binary_op = plus<>());
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, multiplies<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_and<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_or<> binary_op);
+//
+// template 
+// typename V::value_type reduce(const const_where_expression& x, bit_xor<> binary_op);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+inline int factorial(int n) { return n == 1 ? 1 : n * factorial(n - 1); }
+
+void test_reduce() {
+  int n = (int)native_simd::size();
+  assert(reduce(native_simd([](int i) { return i; })) == n * (n - 1) / 2);
+  assert(reduce(native_simd([](int i) { return i; }), std::plus()) ==
+ n * (n - 1) / 2);
+  assert(reduce(native_simd([](int i) { return i + 1; }),
+std::multiplies()) == factorial(n));
+}
+
+int main() { test_reduce(); }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmin.pass.cpp
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template  T hmin(const simd&);
+// template  T hmin(const const_where_expression&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_hmin() {
+  {
+int a[] = {2, 5, -4, 6};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {6, 2, 5, -4};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {-4, 6, 2, 5};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+  {
+int a[] = {5, -4, 6, 2};
+assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+  }
+}
+
+int main() { test_hmin(); }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
@@ -0,0 +1,42 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template  T hmax(const simd&);
+// template  T hmax(const const_where_expression&);
+
+#include 
+#include 

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127622.
timshen added a comment.

include "test_macros.h" in the tests


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,121 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+#include "test_macros.h"
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) &&\
+!defined(_LIBCPP_HAS_NO_INLINE_VARIABLES)
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");

[PATCH] D41415: [libcxx] implement casts.

2017-12-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

This patch also changed all simd size-related types to size_t. Before the
change, as P0214 proposed, they are half-int, half-size_t in different
places. The inconsistency of size types cause to_compatible to fail to
deduce the template arguments.


https://reviews.llvm.org/D41415

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_native.pass.cpp
@@ -0,0 +1,56 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// native_simd to_native(const fixed_size_simd&) noexcept;
+//
+// template 
+// native_simd_mask to_native(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_native() {
+  auto v = to_native(
+  fixed_size_simd([](int i) { return i; }));
+  native_simd w([](int i) { return i; });
+
+  static_assert(std::is_same::value, "");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == w[i]);
+  }
+}
+
+void test_to_native_extension() {
+  auto arr = split_by<32 / native_simd::size()>(
+  to_native(fixed_size_simd([](int i) { return i; })));
+  static_assert(
+  std::is_same::value, "");
+  int v = 0;
+  for (size_t i = 0; i < arr.size(); i++) {
+for (size_t j = 0; j < arr[0].size(); j++) {
+  assert(arr[i][j] == v);
+  v++;
+}
+  }
+}
+
+int main() {
+  test_to_native();
+  test_to_native_extension();
+}
Index: libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_fixed_size.pass.cpp
@@ -0,0 +1,40 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template 
+// fixed_size_simd>
+// to_fixed_size(const simd&) noexcept;
+//
+// template 
+// fixed_size_simd_mask>
+// to_fixed_size(const simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_fixed_size() {
+  auto v = to_fixed_size(native_simd([](int i) { return i; }));
+  static_assert(std::is_same,
+ decltype(v)>::value,
+"");
+
+  for (size_t i = 0; i < v.size(); i++) {
+assert(v[i] == (int)i);
+  }
+}
+
+int main() { test_to_fixed_size(); }
Index: libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.casts/to_compatible.pass.cpp
@@ -0,0 +1,55 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.casts]
+//
+// template  simd
+// to_compatible(const fixed_size_simd&) noexcept;
+//
+// template  simd_mask
+// to_compatible(const fixed_size_simd_mask&) noexcept;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_to_compatible() {
+  auto v = to_compatible(
+  fixed_size_simd([](int i) { return i; }));
+  simd w([](int i) { return i; });
+
+  static_assert(std::is_same

[PATCH] D41412: [libcxx] implement concat() and split()

2017-12-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

This patch implements the extended version (see P0820) of P0214
concat() and split().


https://reviews.llvm.org/D41412

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
  libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/split.pass.cpp
@@ -0,0 +1,125 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// tuple...> split(const simd&);
+//
+// template 
+// tuple...> split(const simd_mask&);
+//
+// template 
+// array split(
+// const simd&);
+//
+// template 
+// array split(
+// const simd_mask&);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd& x);
+//
+// template 
+// array / n, A>>, n> split_by(
+// const simd_mask& x);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_split() {
+  auto t = split<1, 2, 3>(fixed_size_simd([](int i) { return i; }));
+  static_assert(std::tuple_size::value == 3, "");
+
+  assert(std::get<0>(t).size() == 1);
+  assert(std::get<0>(t)[0] == 0);
+
+  assert(std::get<1>(t).size() == 2);
+  assert(std::get<1>(t)[0] == 1);
+  assert(std::get<1>(t)[1] == 2);
+
+  assert(std::get<2>(t).size() == 3);
+  assert(std::get<2>(t)[0] == 3);
+  assert(std::get<2>(t)[1] == 4);
+  assert(std::get<2>(t)[2] == 5);
+}
+
+void test_split_array() {
+  {
+auto arr = split_by<2>(fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+  {
+auto arr = split>(
+fixed_size_simd([](int i) { return i; }));
+static_assert(arr.size() == 2, "");
+
+assert(arr[0].size() == 3);
+assert(arr[0][0] == 0);
+assert(arr[0][1] == 1);
+assert(arr[0][2] == 2);
+
+assert(arr[1].size() == 3);
+assert(arr[1][0] == 3);
+assert(arr[1][1] == 4);
+assert(arr[1][2] == 5);
+  }
+}
+
+void compile_split_propagate_abi() {
+  using compatible_simd_half =
+  simd>;
+  using native_simd_half =
+  simd>;
+
+  static_assert(
+  std::is_same<
+  decltype(
+  split(simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same(native_simd())),
+   std::tuple>::value,
+  "");
+
+  static_assert(std::is_same(simd())),
+ std::array>::value,
+"");
+
+  static_assert(std::is_same(native_simd())),
+ std::array>::value,
+"");
+}
+
+int main() {
+  test_split();
+  test_split_array();
+}
Index: libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.horizontal/concat.pass.cpp
@@ -0,0 +1,80 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// template 
+// simd + ...)>>
+// concat(const simd&...);
+//
+// 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2017-12-18 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127458.
timshen added a comment.

Fix return type of reference::opreator--.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,90 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,116 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_supported_load((int*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) int32_t buffer[] = {4, 

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2017-12-18 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127455.
timshen added a comment.

Fix reference's access control.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,90 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,116 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_supported_load((int*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) int32_t buffer[] = {4, 3, 2, 1};

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2017-12-18 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127453.
timshen added a comment.

Update description.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,90 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,116 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) {}
+
+template 
+void supported_load(...) = delete;
+
+void compile_load() {
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+  supported_load((unsigned int*)nullptr, element_aligned_tag());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_supported_load((int*)nullptr, int());
+}
+
+void test_load() {
+  alignas(32) int32_t buffer[] = {4, 3, 2, 1};
+  {
+

[PATCH] D41376: [libcxx] Implement ABI for Clang/GCC vector extension, constructors, copy_from and copy_to.

2017-12-18 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added reviewers: mclow.lists, EricWF.
Herald added a subscriber: sanjoy.

This patch added a new macro _LIBCPP_HAS_VECTOR_EXTENSION for detecting
whether a vector extension (__attribute__((vector_size(num_bytes is
available.

This patch also backports std::integer_sequence to C++11.

On the top of that, this patch implements the following API:

- all constructors
- operator[]
- copy_from
- copy_to

It also defines simd_abi::native to use vector extension, if available.
In GCC and Clang, certain values with vector extension are passed by registers,
instead of memory.

Based on https://reviews.llvm.org/D41148.


https://reviews.llvm.org/D41376

Files:
  libcxx/include/__config
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/include/utility
  libcxx/test/std/experimental/simd/simd.abi/vector_extension.pass.cpp
  libcxx/test/std/experimental/simd/simd.access/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/default.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
  libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/store.pass.cpp
@@ -0,0 +1,90 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // stores [simd.store]
+// template  void copy_to(U* mem, Flags f) const;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_store() {
+  fixed_size_simd a([](int i) { return 4 - i; });
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned_tag());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned_tag<32>());
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+
+#if TEST_STD_VER > 14
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, element_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, vector_aligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+  {
+alignas(32) int32_t buffer[4] = {0};
+a.copy_to(buffer, overaligned);
+assert(buffer[0] == 4);
+assert(buffer[1] == 3);
+assert(buffer[2] == 2);
+assert(buffer[3] == 1);
+  }
+#endif
+}
+
+void test_converting_store() {
+  float buffer[4] = {0.};
+  fixed_size_simd a([](int i) { return 1 << i; });
+  a.copy_to(buffer, element_aligned_tag());
+  assert(buffer[0] == 1.);
+  assert(buffer[1] == 2.);
+  assert(buffer[2] == 4.);
+  assert(buffer[3] == 8.);
+}
+
+int main() {
+  test_store();
+  test_converting_store();
+}
Index: libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.mem/load.pass.cpp
@@ -0,0 +1,116 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// loads [simd.load]
+// template  void copy_from(const U* mem, Flags f);
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+template 
+auto not_supported_load(Args&&... args) -> decltype(
+std::declval().copy_from(std::forward(args)...),
+void()) = delete;
+
+template 
+void not_supported_load(...) {}
+
+template 
+auto supported_load(Args&&... args) -> decltype(
+

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-18 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 127399.
timshen added a comment.

Formatted the files.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,119 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-13 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: libcxx/include/experimental/simd:594
+
+#warning " is under construction and not for practical use 
for now."
+

EricWF wrote:
> I would just remove this. The `experimental` part of the name should say 
> enough.
> 
> Also we normally wait until an implementation is mostly complete before 
> landing it. 
> Also we normally wait until an implementation is mostly complete before 
> landing it.

What's the definition of "landing"? I prefer to implement this library in 
multiple patches, does that mean I keep working on the next ones and finally 
commit all of them all at once? If that's the case, SGTM.



Comment at: libcxx/test/std/experimental/simd/traits.pass.cpp:15
+// [simd.traits]
+// template  struct is_abi_tag;
+// template  inline constexpr bool is_abi_tag_v = 
is_abi_tag::value;

EricWF wrote:
> Please create a directory called `simd/traits/` and then put each trait in a 
> separate test file under that directory.
> The `foo_v` tests should be in the same file as the `foo` tests.
> 
> 
Thanks! Done for all tests. Used directory names like "simd.cons", 
"simd.traits", "simd.casts".


https://reviews.llvm.org/D41148



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-13 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 126872.
timshen marked 7 inline comments as done.
timshen added a comment.

Address second round of comments.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/__config
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.casts/static_simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/broadcast.pass.cpp
  libcxx/test/std/experimental/simd/simd.cons/geneartor.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/abi_for_size.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_flag_type.pass.cpp
  libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp

Index: libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/simd.traits/is_simd_mask.pass.cpp
@@ -0,0 +1,119 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+static_assert(is_simd_mask::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+static_assert(is_simd_mask>::value, "");
+
+static_assert(!is_simd_mask::value, "");
+
+#if TEST_STD_VER > 14
+
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");
+static_assert(is_simd_mask_v, "");

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-13 Thread Tim Shen via Phabricator via cfe-commits
timshen marked 4 inline comments as done.
timshen added inline comments.



Comment at: libcxx/include/experimental/simd:1069
+std::is_same<_Abi, simd_abi::fixed_size>::value &&
+__is_non_narrowing_convertible<_Up, _Tp>()>::type>
+  simd(const simd<_Up, simd_abi::fixed_size>&) {}

lichray wrote:
> Does it causes a problem if the logic of `is_convertible` is folded into 
> `__is_non_narrowing_convertible`?
Avoided to answer this question by sfinae on is_arithmetic.


https://reviews.llvm.org/D41148



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-13 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 126813.
timshen added a comment.

Address comments:

- Generator ctor is implementable
- Format issues of tests
- SFINAE on __is_non_narrowing_convertible for arithmetics only.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/ctor.pass.cpp
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/traits.pass.cpp

Index: libcxx/test/std/experimental/simd/traits.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/traits.pass.cpp
@@ -0,0 +1,179 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_abi_tag;
+// template  inline constexpr bool is_abi_tag_v = is_abi_tag::value;
+// template  struct is_simd;
+// template  inline constexpr bool is_simd_v = is_simd::value;
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+// template  struct is_simd_flag_type;
+// template  inline constexpr bool is_simd_flag_type_v = is_simd_flag_type::value;
+// template  struct abi_for_size { using type = see below ; };
+// template  using abi_for_size_t = typename abi_for_size::type;
+// template > struct simd_size;
+// template >
+// inline constexpr size_t simd_size_v = simd_size::value;
+// template  struct memory_alignment;
+// template 
+// inline constexpr size_t memory_alignment_v = memory_alignment::value;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+
+static_assert(is_abi_tag::value, "");
+static_assert(!std::is_same>::value,
+  "");
+
+static_assert(is_abi_tag>::value, "");
+static_assert(is_abi_tag>::value, "");
+static_assert(is_abi_tag>::value, "");
+static_assert(is_abi_tag>::value, "");
+static_assert(is_abi_tag>::value, "");
+static_assert(is_abi_tag>::value, "");
+
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+static_assert(is_simd>::value, "");
+
+static_assert(is_simd>::value, "");

[PATCH] D41148: [libcxx] implement declarations based on P0214R7.

2017-12-12 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
timshen added a reviewer: mclow.lists.
Herald added a subscriber: sanjoy.
Herald added a reviewer: EricWF.

The patch includes all declarations, and also implements the following features:

- ABI.
- narrowing-conversion related SFIANE, including simd<> ctors and 
(static_)simd_cast.


https://reviews.llvm.org/D41148

Files:
  libcxx/include/experimental/simd
  libcxx/test/std/experimental/simd/ctor.pass.cpp
  libcxx/test/std/experimental/simd/nothing_to_do.pass.cpp
  libcxx/test/std/experimental/simd/simd_cast.pass.cpp
  libcxx/test/std/experimental/simd/traits.pass.cpp

Index: libcxx/test/std/experimental/simd/traits.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/experimental/simd/traits.pass.cpp
@@ -0,0 +1,179 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// [simd.traits]
+// template  struct is_abi_tag;
+// template  inline constexpr bool is_abi_tag_v = is_abi_tag::value;
+// template  struct is_simd;
+// template  inline constexpr bool is_simd_v = is_simd::value;
+// template  struct is_simd_mask;
+// template  inline constexpr bool is_simd_mask_v = is_simd_mask::value;
+// template  struct is_simd_flag_type;
+// template  inline constexpr bool is_simd_flag_type_v = is_simd_flag_type::value;
+// template  struct abi_for_size { using type = see below ; };
+// template  using abi_for_size_t = typename abi_for_size::type;
+// template > struct simd_size;
+// template >
+// inline constexpr size_t simd_size_v = simd_size::value;
+// template  struct memory_alignment;
+// template 
+// inline constexpr size_t memory_alignment_v = memory_alignment::value;
+
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+static_assert(is_abi_tag::value, "");
+
+static_assert(is_abi_tag::value, "");
+static_assert(!std::is_same >::value,
+  "");
+
+static_assert(is_abi_tag >::value, "");
+static_assert(is_abi_tag >::value, "");
+static_assert(is_abi_tag >::value, "");
+static_assert(is_abi_tag >::value, "");
+static_assert(is_abi_tag >::value, "");
+static_assert(is_abi_tag >::value, "");
+
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+static_assert(is_simd::value, "");
+
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");
+static_assert(is_simd >::value, "");

[PATCH] D39308: [libcxx] Keep track of heap allocated regex states

2017-10-27 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 120711.
timshen added a comment.

Remove the uses of variadic template and auto.

I'm not sure of how to implement this without a ABI change (the addition of 
__storage_).


https://reviews.llvm.org/D39308

Files:
  libcxx/include/regex

Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -765,6 +765,8 @@
 #include 
 #include 
 
+#include <__debug>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -1404,16 +1406,8 @@
 _LIBCPP_INLINE_VISIBILITY
 explicit __owns_one_state(__node<_CharT>* __s)
 : base(__s) {}
-
-virtual ~__owns_one_state();
 };
 
-template 
-__owns_one_state<_CharT>::~__owns_one_state()
-{
-delete this->first();
-}
-
 // __empty_state
 
 template 
@@ -1507,20 +1501,12 @@
 explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
 : base(__s1), __second_(__s2) {}
 
-virtual ~__owns_two_states();
-
 _LIBCPP_INLINE_VISIBILITY
 base*  second() const {return __second_;}
 _LIBCPP_INLINE_VISIBILITY
 base*& second()   {return __second_;}
 };
 
-template 
-__owns_two_states<_CharT>::~__owns_two_states()
-{
-delete __second_;
-}
-
 // __loop
 
 template 
@@ -2493,17 +2479,51 @@
 typedef typename _Traits::locale_type   locale_type;
 
 private:
+typedef _VSTD::__state<_CharT> __state;
+typedef _VSTD::__node<_CharT> __node;
+
+// Shared, append-only storage for regexes.
+class __storage
+{
+  // invariant: __v_ is never nullptr.
+  shared_ptr>> __v_;
+
+public:
+  __storage() : __v_(make_shared>>()) {}
+  __storage(const __storage&) = default;
+  __storage(__storage&& __rhs) : __v_(std::move(__rhs.__v_))
+  { __rhs.__clear(); }
+
+  __storage& operator=(const __storage&) = default;
+  __storage& operator=(__storage&& __rhs)
+  {
+__v_ = std::move(__rhs.__v_);
+__rhs.__clear();
+return *this;
+  }
+
+  __node* __push(__node* __n)
+  {
+_LIBCPP_ASSERT(__v_.use_count() == 1,
+   "__push should be called only "
+   "when the storage is not shared");
+__v_->emplace_back(unique_ptr<__node>(__n));
+return __n;
+  }
+
+  void __clear()
+  { __v_ = make_shared>>(); }
+};
+
 _Traits   __traits_;
 flag_type __flags_;
 unsigned __marked_count_;
 unsigned __loop_count_;
 int __open_count_;
-shared_ptr<__empty_state<_CharT> > __start_;
+__storage __storage_;
+__empty_state<_CharT>* __start_;
 __owns_one_state<_CharT>* __end_;
 
-typedef _VSTD::__state<_CharT> __state;
-typedef _VSTD::__node<_CharT> __node;
-
 public:
 // constants:
 static const regex_constants::syntax_option_type icase = regex_constants::icase;
@@ -2521,40 +2541,40 @@
 _LIBCPP_INLINE_VISIBILITY
 basic_regex()
 : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {}
 _LIBCPP_INLINE_VISIBILITY
 explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p, __p + __traits_.length(__p));}
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p, __p + __len);}
 // basic_regex(const basic_regex&) = default;
 // basic_regex(basic_regex&&) = default;
 template 
 _LIBCPP_INLINE_VISIBILITY
 explicit basic_regex(const basic_string& __p,
  flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p.begin(), __p.end());}
 template 
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(_ForwardIterator __first, _ForwardIterator __last,
 flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__first, __last);}
 #ifndef _LIBCPP_CXX03_LANG
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(initializer_list __il,
 flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 

[PATCH] D39308: [libcxx] Keep track of heap allocated regex states

2017-10-26 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

In https://reviews.llvm.org/D39308#907424, @mclow.lists wrote:

> A couple of notes.


Sorry for the oversights, when a C++11(-only :) contributor doesn't care about 
ABI stability, nor exceptions, he contributes naive code. :P I'll fix them.

> - This change means that  now requires C++11 (the new `__push` 
> function w/ the varargs).  I don't know how important that is; but I'm pretty 
> sure libc++ currently provides `` in C++03 mode.
> - This is an ABI change; existing code that was compiled with the "old" 
> `` implementation will not interoperate with this.

Can you give an example on what would go wrong, while it's not expected to go 
wrong?

> - I think that there may be some exception-safety issues in `__push`; if the 
> `push_back` throws, I think we leak.


https://reviews.llvm.org/D39308



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39308: [libcxx] Keep track of heap allocated regex states

2017-10-25 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 120334.
timshen added a comment.

Add an assertion to __push.


https://reviews.llvm.org/D39308

Files:
  libcxx/include/regex

Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -765,6 +765,8 @@
 #include 
 #include 
 
+#include <__debug>
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
 #endif
@@ -1404,16 +1406,8 @@
 _LIBCPP_INLINE_VISIBILITY
 explicit __owns_one_state(__node<_CharT>* __s)
 : base(__s) {}
-
-virtual ~__owns_one_state();
 };
 
-template 
-__owns_one_state<_CharT>::~__owns_one_state()
-{
-delete this->first();
-}
-
 // __empty_state
 
 template 
@@ -1507,20 +1501,12 @@
 explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
 : base(__s1), __second_(__s2) {}
 
-virtual ~__owns_two_states();
-
 _LIBCPP_INLINE_VISIBILITY
 base*  second() const {return __second_;}
 _LIBCPP_INLINE_VISIBILITY
 base*& second()   {return __second_;}
 };
 
-template 
-__owns_two_states<_CharT>::~__owns_two_states()
-{
-delete __second_;
-}
-
 // __loop
 
 template 
@@ -2493,17 +2479,50 @@
 typedef typename _Traits::locale_type   locale_type;
 
 private:
+typedef _VSTD::__state<_CharT> __state;
+typedef _VSTD::__node<_CharT> __node;
+
+// Shared, append-only storage for regexes.
+class __storage
+{
+  // invariant: __v_ is never nullptr.
+  shared_ptr>> __v_;
+
+public:
+  __storage() : __v_(make_shared>>()) {}
+  __storage(const __storage&) = default;
+  __storage(__storage&& __rhs) : __v_(std::move(__rhs.__v_))
+  { __rhs.__clear(); }
+
+  __storage& operator=(const __storage&) = default;
+  __storage& operator=(__storage&& __rhs)
+  {
+__v_ = std::move(__rhs.__v_);
+__rhs.__clear();
+return *this;
+  }
+
+  void __push(__node* __n)
+  {
+_LIBCPP_ASSERT(__v_.use_count() == 1,
+   "__push should be called only "
+   "when the storage is not shared");
+__v_->emplace_back(__n);
+  }
+
+  void __clear()
+  { __v_ = make_shared>>(); }
+};
+
 _Traits   __traits_;
 flag_type __flags_;
 unsigned __marked_count_;
 unsigned __loop_count_;
 int __open_count_;
-shared_ptr<__empty_state<_CharT> > __start_;
+__storage __storage_;
+__empty_state<_CharT>* __start_;
 __owns_one_state<_CharT>* __end_;
 
-typedef _VSTD::__state<_CharT> __state;
-typedef _VSTD::__node<_CharT> __node;
-
 public:
 // constants:
 static const regex_constants::syntax_option_type icase = regex_constants::icase;
@@ -2521,40 +2540,40 @@
 _LIBCPP_INLINE_VISIBILITY
 basic_regex()
 : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {}
 _LIBCPP_INLINE_VISIBILITY
 explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p, __p + __traits_.length(__p));}
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p, __p + __len);}
 // basic_regex(const basic_regex&) = default;
 // basic_regex(basic_regex&&) = default;
 template 
 _LIBCPP_INLINE_VISIBILITY
 explicit basic_regex(const basic_string& __p,
  flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p.begin(), __p.end());}
 template 
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(_ForwardIterator __first, _ForwardIterator __last,
 flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__first, __last);}
 #ifndef _LIBCPP_CXX03_LANG
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(initializer_list __il,
 flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__il.begin(), __il.end());}
 #endif  // _LIBCPP_CXX03_LANG
 
@@ -2656,7 +2675,8 @@
 locale_type imbue(locale_type __loc)
 {
 

[PATCH] D39308: [libcxx] Keep track of heap allocated regex states

2017-10-25 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
Herald added a subscriber: sanjoy.
Herald added a reviewer: EricWF.

Build abstraction on regex's allocation

This fixes a fuzzer crasher from a huge input (provided by Marshall), which 
seems to be a stackoverflow during destruction. However, I can't reproduce 
Marshall's crasher even before the change.

No new tests are added, but all old tests pass. I didn't really run valgrind on 
tests to check for memory leak, as the new allocation is basically correct by 
construction (only one call site uses `new`, no explicit `delete` calls).


https://reviews.llvm.org/D39308

Files:
  libcxx/include/regex

Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -1404,16 +1404,8 @@
 _LIBCPP_INLINE_VISIBILITY
 explicit __owns_one_state(__node<_CharT>* __s)
 : base(__s) {}
-
-virtual ~__owns_one_state();
 };
 
-template 
-__owns_one_state<_CharT>::~__owns_one_state()
-{
-delete this->first();
-}
-
 // __empty_state
 
 template 
@@ -1507,20 +1499,12 @@
 explicit __owns_two_states(__node<_CharT>* __s1, base* __s2)
 : base(__s1), __second_(__s2) {}
 
-virtual ~__owns_two_states();
-
 _LIBCPP_INLINE_VISIBILITY
 base*  second() const {return __second_;}
 _LIBCPP_INLINE_VISIBILITY
 base*& second()   {return __second_;}
 };
 
-template 
-__owns_two_states<_CharT>::~__owns_two_states()
-{
-delete __second_;
-}
-
 // __loop
 
 template 
@@ -2493,17 +2477,45 @@
 typedef typename _Traits::locale_type   locale_type;
 
 private:
+typedef _VSTD::__state<_CharT> __state;
+typedef _VSTD::__node<_CharT> __node;
+
+// Shared, append-only storage for regexes.
+class __storage
+{
+  // invariant: __v_ is never nullptr.
+  shared_ptr>> __v_;
+
+public:
+  __storage() : __v_(make_shared>>()) {}
+  __storage(const __storage&) = default;
+  __storage(__storage&& __rhs) : __v_(std::move(__rhs.__v_))
+  { __rhs.__clear(); }
+
+  __storage& operator=(const __storage&) = default;
+  __storage& operator=(__storage&& __rhs)
+  {
+__v_ = std::move(__rhs.__v_);
+__rhs.__clear();
+return *this;
+  }
+
+  void __push(__node* __n)
+  { __v_->emplace_back(__n); }
+
+  void __clear()
+  { __v_ = make_shared>>(); }
+};
+
 _Traits   __traits_;
 flag_type __flags_;
 unsigned __marked_count_;
 unsigned __loop_count_;
 int __open_count_;
-shared_ptr<__empty_state<_CharT> > __start_;
+__storage __storage_;
+__empty_state<_CharT>* __start_;
 __owns_one_state<_CharT>* __end_;
 
-typedef _VSTD::__state<_CharT> __state;
-typedef _VSTD::__node<_CharT> __node;
-
 public:
 // constants:
 static const regex_constants::syntax_option_type icase = regex_constants::icase;
@@ -2521,40 +2533,40 @@
 _LIBCPP_INLINE_VISIBILITY
 basic_regex()
 : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {}
 _LIBCPP_INLINE_VISIBILITY
 explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p, __p + __traits_.length(__p));}
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p, __p + __len);}
 // basic_regex(const basic_regex&) = default;
 // basic_regex(basic_regex&&) = default;
 template 
 _LIBCPP_INLINE_VISIBILITY
 explicit basic_regex(const basic_string& __p,
  flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__p.begin(), __p.end());}
 template 
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(_ForwardIterator __first, _ForwardIterator __last,
 flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 {__parse(__first, __last);}
 #ifndef _LIBCPP_CXX03_LANG
 _LIBCPP_INLINE_VISIBILITY
 basic_regex(initializer_list __il,
 flag_type __f = regex_constants::ECMAScript)
 : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
-  __end_(0)
+  __start_(0), __end_(0)
 

[PATCH] D39162: [test] Fix clang-test for FreeBSD and NetBSD

2017-10-23 Thread Tim Shen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL316411: [test] Fix clang-test for FreeBSD and NetBSD 
(authored by timshen).

Changed prior to commit:
  https://reviews.llvm.org/D39162?vs=119803=119995#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D39162

Files:
  cfe/trunk/test/Unit/lit.cfg.py


Index: cfe/trunk/test/Unit/lit.cfg.py
===
--- cfe/trunk/test/Unit/lit.cfg.py
+++ cfe/trunk/test/Unit/lit.cfg.py
@@ -35,17 +35,23 @@
 if symbolizer in os.environ:
 config.environment[symbolizer] = os.environ[symbolizer]
 
-shlibpath_var = ''
-if platform.system() == 'Linux':
-shlibpath_var = 'LD_LIBRARY_PATH'
-elif platform.system() == 'Darwin':
-shlibpath_var = 'DYLD_LIBRARY_PATH'
-elif platform.system() == 'Windows':
-shlibpath_var = 'PATH'
-
-# in stand-alone builds, shlibdir is clang's build tree
-# while llvm_libs_dir is installed LLVM (and possibly older clang)
-shlibpath = os.path.pathsep.join((config.shlibdir, config.llvm_libs_dir,
- config.environment.get(shlibpath_var,'')))
-
-config.environment[shlibpath_var] = shlibpath
+def find_shlibpath_var():
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
+yield 'LD_LIBRARY_PATH'
+elif platform.system() == 'Darwin':
+yield 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+yield 'PATH'
+
+for shlibpath_var in find_shlibpath_var():
+# in stand-alone builds, shlibdir is clang's build tree
+# while llvm_libs_dir is installed LLVM (and possibly older clang)
+shlibpath = os.path.pathsep.join(
+(config.shlibdir,
+ config.llvm_libs_dir,
+ config.environment.get(shlibpath_var, '')))
+config.environment[shlibpath_var] = shlibpath
+break
+else:
+lit_config.warning("unable to inject shared library path on '{}'"
+   .format(platform.system()))


Index: cfe/trunk/test/Unit/lit.cfg.py
===
--- cfe/trunk/test/Unit/lit.cfg.py
+++ cfe/trunk/test/Unit/lit.cfg.py
@@ -35,17 +35,23 @@
 if symbolizer in os.environ:
 config.environment[symbolizer] = os.environ[symbolizer]
 
-shlibpath_var = ''
-if platform.system() == 'Linux':
-shlibpath_var = 'LD_LIBRARY_PATH'
-elif platform.system() == 'Darwin':
-shlibpath_var = 'DYLD_LIBRARY_PATH'
-elif platform.system() == 'Windows':
-shlibpath_var = 'PATH'
-
-# in stand-alone builds, shlibdir is clang's build tree
-# while llvm_libs_dir is installed LLVM (and possibly older clang)
-shlibpath = os.path.pathsep.join((config.shlibdir, config.llvm_libs_dir,
- config.environment.get(shlibpath_var,'')))
-
-config.environment[shlibpath_var] = shlibpath
+def find_shlibpath_var():
+if platform.system() in ['Linux', 'FreeBSD', 'NetBSD']:
+yield 'LD_LIBRARY_PATH'
+elif platform.system() == 'Darwin':
+yield 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+yield 'PATH'
+
+for shlibpath_var in find_shlibpath_var():
+# in stand-alone builds, shlibdir is clang's build tree
+# while llvm_libs_dir is installed LLVM (and possibly older clang)
+shlibpath = os.path.pathsep.join(
+(config.shlibdir,
+ config.llvm_libs_dir,
+ config.environment.get(shlibpath_var, '')))
+config.environment[shlibpath_var] = shlibpath
+break
+else:
+lit_config.warning("unable to inject shared library path on '{}'"
+   .format(platform.system()))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39066: [libcxx] Fix signed overflow when constructing integers from brace expressions.

2017-10-18 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
Herald added a subscriber: sanjoy.
Herald added a reviewer: EricWF.

This should unblock PR24411.


https://reviews.llvm.org/D39066

Files:
  libcxx/include/regex
  libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp


Index: libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
@@ -0,0 +1,40 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+// UNSUPPORTED: libcpp-no-exceptions
+// UNSUPPORTED: c++03
+
+// the "n" in `a{n}` should be within the numeric limits.
+
+#include 
+#include 
+
+int main() {
+  for (std::regex_constants::syntax_option_type op :
+   {std::regex::basic, std::regex::grep}) {
+try {
+  (void)std::regex("a\\{10\\}", op);
+  assert(false);
+} catch (const std::regex_error ) {
+  assert(e.code() == std::regex_constants::error_badbrace);
+}
+  }
+  for (std::regex_constants::syntax_option_type op :
+   {std::regex::ECMAScript, std::regex::extended, std::regex::egrep,
+std::regex::awk}) {
+try {
+  (void)std::regex("a{10}", op);
+  assert(false);
+} catch (const std::regex_error ) {
+  assert(e.code() == std::regex_constants::error_badbrace);
+}
+  }
+  return 0;
+}
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -4064,6 +4064,8 @@
  __first != __last && ( __val = __traits_.value(*__first, 10)) 
!= -1;
  ++__first)
 {
+if (__c >= std::numeric_limits::max() / 10)
+  __throw_regex_error();
 __c *= 10;
 __c += __val;
 }


Index: libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/re/re.grammar/excessive_brace_count.pass.cpp
@@ -0,0 +1,40 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+// UNSUPPORTED: libcpp-no-exceptions
+// UNSUPPORTED: c++03
+
+// the "n" in `a{n}` should be within the numeric limits.
+
+#include 
+#include 
+
+int main() {
+  for (std::regex_constants::syntax_option_type op :
+   {std::regex::basic, std::regex::grep}) {
+try {
+  (void)std::regex("a\\{10\\}", op);
+  assert(false);
+} catch (const std::regex_error ) {
+  assert(e.code() == std::regex_constants::error_badbrace);
+}
+  }
+  for (std::regex_constants::syntax_option_type op :
+   {std::regex::ECMAScript, std::regex::extended, std::regex::egrep,
+std::regex::awk}) {
+try {
+  (void)std::regex("a{10}", op);
+  assert(false);
+} catch (const std::regex_error ) {
+  assert(e.code() == std::regex_constants::error_badbrace);
+}
+  }
+  return 0;
+}
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -4064,6 +4064,8 @@
  __first != __last && ( __val = __traits_.value(*__first, 10)) != -1;
  ++__first)
 {
+if (__c >= std::numeric_limits::max() / 10)
+  __throw_regex_error();
 __c *= 10;
 __c += __val;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37955: [libcxx] Fix invert negative bracket match.

2017-09-19 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 115851.
timshen added a comment.

Fixed.

Those tests were XFAILing on linux-gnu. I also created 
https://reviews.llvm.org/D38041 to XFAIL only on the failing ones.


https://reviews.llvm.org/D37955

Files:
  libcxx/include/regex
  libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp


Index: libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
@@ -0,0 +1,29 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+
+// template 
+// bool
+// regex_search(BidirectionalIterator first, BidirectionalIterator last,
+//  match_results& m,
+//  const basic_regex& e,
+//  regex_constants::match_flag_type flags = 
regex_constants::match_default);
+
+#include 
+#include 
+#include "test_macros.h"
+
+// PR34310
+int main()
+{
+  assert(std::regex_search("HelloWorld", std::regex("[^\\W]")));
+  assert(std::regex_search("_", std::regex("[^\\W]")));
+  return 0;
+}
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -2409,17 +2409,28 @@
 goto __exit;
 }
 }
-if (!__neg_chars_.empty())
+// set of "__found" chars =
+//   union(complement(union(__neg_chars_, __neg_mask_)),
+// other cases...)
+//
+// __neg_chars_ and __neg_mask_'d better be handled together, as there
+// are no short circuit opportunities.
+//
+// In addition, when __neg_mask_/__neg_chars_ is empty, they should be
+// treated as all ones/all chars.
 {
-for (size_t __i = 0; __i < __neg_chars_.size(); ++__i)
-{
-if (__ch == __neg_chars_[__i])
-goto __is_neg_char;
-}
+  const bool __in_neg_mask = (__neg_mask_ == 0) ||
+  __traits_.isctype(__ch, __neg_mask_);
+  const bool __in_neg_chars =
+  __neg_chars_.empty() ||
+  std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) !=
+  __neg_chars_.end();
+  if (!(__in_neg_mask || __in_neg_chars))
+  {
 __found = true;
 goto __exit;
+  }
 }
-__is_neg_char:
 if (!__ranges_.empty())
 {
 string_type __s2 = __collate_ ?
@@ -2451,11 +2462,6 @@
 __found = true;
 goto __exit;
 }
-if (__neg_mask_ && !__traits_.isctype(__ch, __neg_mask_))
-{
-__found = true;
-goto __exit;
-}
 }
 else
 __found = __negate_;  // force reject


Index: libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
@@ -0,0 +1,29 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// 
+
+// template 
+// bool
+// regex_search(BidirectionalIterator first, BidirectionalIterator last,
+//  match_results& m,
+//  const basic_regex& e,
+//  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+#include 
+#include 
+#include "test_macros.h"
+
+// PR34310
+int main()
+{
+  assert(std::regex_search("HelloWorld", std::regex("[^\\W]")));
+  assert(std::regex_search("_", std::regex("[^\\W]")));
+  return 0;
+}
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -2409,17 +2409,28 @@
 goto __exit;
 }
 }
-if (!__neg_chars_.empty())
+// set of "__found" chars =
+//   union(complement(union(__neg_chars_, __neg_mask_)),
+// other cases...)
+//
+// __neg_chars_ and __neg_mask_'d better be handled together, as there
+// are no short circuit opportunities.
+//
+// In addition, 

[PATCH] D38041: [libc++] Separate locale tests that are XFAIL on linux-gnu from others

2017-09-19 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
Herald added a subscriber: sanjoy.
Herald added a reviewer: EricWF.

The tests don't pass on linux-gnu. Move them out, so that the others
don't have to be XFAIL.


https://reviews.llvm.org/D38041

Files:
  libcxx/test/std/re/re.alg/re.alg.match/basic.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.match/basic_locale.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.match/ecma.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.match/ecma_locale.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.match/extended.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.match/extended_locale.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.search/awk.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.search/awk_locale.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.search/ecma.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.search/ecma_locale.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.search/extended.pass.cpp
  libcxx/test/std/re/re.alg/re.alg.search/extended_locale.pass.cpp

Index: libcxx/test/std/re/re.alg/re.alg.search/extended_locale.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/re/re.alg/re.alg.search/extended_locale.pass.cpp
@@ -0,0 +1,98 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// REQUIRES: locale.cs_CZ.ISO8859-2
+
+// 
+
+// template 
+// bool
+// regex_search(BidirectionalIterator first, BidirectionalIterator last,
+//  match_results& m,
+//  const basic_regex& e,
+//  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+// TODO: investigation needed
+// XFAIL: linux-gnu
+
+#include 
+#include 
+#include "test_macros.h"
+#include "test_iterators.h"
+
+#include "platform_support.h" // locale name macros
+
+int main()
+{
+std::locale::global(std::locale(LOCALE_cs_CZ_ISO8859_2));
+{
+std::cmatch m;
+const char s[] = "m";
+assert(std::regex_search(s, m, std::regex("[a[=M=]z]",
+ std::regex_constants::extended)));
+assert(m.size() == 1);
+assert(!m.prefix().matched);
+assert(m.prefix().first == s);
+assert(m.prefix().second == m[0].first);
+assert(!m.suffix().matched);
+assert(m.suffix().first == m[0].second);
+assert(m.suffix().second == m[0].second);
+assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s));
+assert(m.position(0) == 0);
+assert(m.str(0) == s);
+}
+{
+std::cmatch m;
+const char s[] = "Ch";
+assert(std::regex_search(s, m, std::regex("[a[.ch.]z]",
+   std::regex_constants::extended | std::regex_constants::icase)));
+assert(m.size() == 1);
+assert(!m.prefix().matched);
+assert(m.prefix().first == s);
+assert(m.prefix().second == m[0].first);
+assert(!m.suffix().matched);
+assert(m.suffix().first == m[0].second);
+assert(m.suffix().second == m[0].second);
+assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s));
+assert(m.position(0) == 0);
+assert(m.str(0) == s);
+}
+{
+std::wcmatch m;
+const wchar_t s[] = L"m";
+assert(std::regex_search(s, m, std::wregex(L"[a[=M=]z]",
+ std::regex_constants::extended)));
+assert(m.size() == 1);
+assert(!m.prefix().matched);
+assert(m.prefix().first == s);
+assert(m.prefix().second == m[0].first);
+assert(!m.suffix().matched);
+assert(m.suffix().first == m[0].second);
+assert(m.suffix().second == m[0].second);
+assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s));
+assert(m.position(0) == 0);
+assert(m.str(0) == s);
+}
+{
+std::wcmatch m;
+const wchar_t s[] = L"Ch";
+assert(std::regex_search(s, m, std::wregex(L"[a[.ch.]z]",
+   std::regex_constants::extended | std::regex_constants::icase)));
+assert(m.size() == 1);
+assert(!m.prefix().matched);
+assert(m.prefix().first == s);
+assert(m.prefix().second == m[0].first);
+assert(!m.suffix().matched);
+assert(m.suffix().first == m[0].second);
+assert(m.suffix().second == m[0].second);
+assert(m.length(0) >= 0 && static_cast(m.length(0)) == std::char_traits::length(s));
+assert(m.position(0) == 0);
+assert(m.str(0) == s);
+}
+}
Index: 

[PATCH] D37958: [libc++] Correctly propagate user-defined lookup_classname().

2017-09-18 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: 
libcxx/test/std/re/re.traits/lookup_classname_user_defined.pass.cpp:46
+// matches all characters (they are classified as alnum)
+std::wstring re1 = L"([[:alnum:]]+)";
+std::regex_search(in, m, std::wregex(re1));

Quuxplusone wrote:
> Could you add a test here for
> 
> std::wstring re3 = L"([[:ALNUM:]]+)";
> std::regex_search(in, m, std::wregex(re3, std::regex_constants::icase));
> 
> std::wstring re4 = L"(\\W+)";
> std::regex_search(in, m, std::wregex(re4, std::regex_constants::icase));
> 
> documenting the expected outputs?  It's unclear to me from cppreference
> http://en.cppreference.com/w/cpp/regex/regex_traits/lookup_classname
> whether lookup_classname("W") is supposed to produce a result or not (but you 
> seem to assume it does).
> 
> My understanding is that the "icase" parameter to lookup_classname is talking 
> about the icaseness of the regex matcher; classnames should always be matched 
> with exact case, i.e. `[[:alnum:]]` is always a valid classname and 
> `[[:ALNUM:]]` is always invalid, regardless of regex_constants::icase. But 
> I'm not sure.
[re.req] says that, for lookup_classname(), "The value returned shall be 
independent of the case of the characters in the sequence."

I take it as regardless of lookup_classname()'s icase argument, [[:ALNUM:]] is 
always valid.

There are existing tests that confirms it in 
std/re/re.traits/lookup_classname.pass.cpp. Search for "AlNum".

I fixed my patch, since I was misunderstanding it as well (I thought icase is 
for the input char sequence). Now they are just forwarded into 
lookup_classname().


https://reviews.llvm.org/D37958



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37958: [libc++] Correctly propagate user-defined lookup_classname().

2017-09-18 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 115597.
timshen added a comment.

Propagate __icase_ correctly into lookup_classname.


https://reviews.llvm.org/D37958

Files:
  libcxx/include/regex
  libcxx/test/std/re/re.traits/lookup_classname_user_defined.pass.cpp
  libcxx/utils/libcxx/test/target_info.py

Index: libcxx/utils/libcxx/test/target_info.py
===
--- libcxx/utils/libcxx/test/target_info.py
+++ libcxx/utils/libcxx/test/target_info.py
@@ -55,6 +55,7 @@
 ('fr_FR.UTF-8', 'French_France.1252'),
 ('ru_RU.UTF-8', 'Russian_Russia.1251'),
 ('zh_CN.UTF-8', 'Chinese_China.936'),
+('ja_JP.UTF-8', 'Japanese_Japan.932'),
 ('fr_CA.ISO8859-1', 'French_Canada.1252'),
 ('cs_CZ.ISO8859-2', 'Czech_Czech Republic.1250')
 ]
Index: libcxx/test/std/re/re.traits/lookup_classname_user_defined.pass.cpp
===
--- /dev/null
+++ libcxx/test/std/re/re.traits/lookup_classname_user_defined.pass.cpp
@@ -0,0 +1,54 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// REQUIRES: locale.ja_JP.UTF-8
+
+// 
+
+// template  struct regex_traits;
+
+// template 
+//   char_class_type
+//   lookup_classname(ForwardIterator first, ForwardIterator last,
+//bool icase = false) const;
+
+#include 
+#include 
+#include "test_macros.h"
+#include "platform_support.h" // locale name macros
+
+struct wctype_traits : std::regex_traits
+{
+using char_class_type = std::wctype_t;
+template
+char_class_type lookup_classname(ForwardIt first, ForwardIt last, bool icase = false ) const {
+(void)icase;
+return std::wctype(std::string(first, last).c_str());
+}
+bool isctype(wchar_t c, char_class_type f) const {
+return std::iswctype(c, f);
+}
+};
+
+int main()
+{
+std::locale::global(std::locale("ja_JP.utf8"));
+std::wsmatch m;
+std::wstring in = L"風の谷のナウシカ";
+
+// matches all characters (they are classified as alnum)
+std::wstring re1 = L"([[:alnum:]]+)";
+std::regex_search(in, m, std::wregex(re1));
+assert(m[1] == L"風の谷のナウシカ");
+
+// matches only the kanji
+std::wstring re2 = L"([[:jkata:]]+)";
+std::regex_search(in, m, std::basic_regex(re2));
+assert(m[1] == L"ナウシカ");
+}
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -2213,8 +2213,8 @@
 vector > __ranges_;
 vector > __digraphs_;
 vector __equivalences_;
-typename regex_traits<_CharT>::char_class_type __mask_;
-typename regex_traits<_CharT>::char_class_type __neg_mask_;
+typename _Traits::char_class_type __mask_;
+typename _Traits::char_class_type __neg_mask_;
 bool __negate_;
 bool __icase_;
 bool __collate_;
@@ -2307,12 +2307,26 @@
 _LIBCPP_INLINE_VISIBILITY
 void __add_equivalence(const string_type& __s)
 {__equivalences_.push_back(__s);}
+
+template 
 _LIBCPP_INLINE_VISIBILITY
-void __add_class(typename regex_traits<_CharT>::char_class_type __mask)
-{__mask_ |= __mask;}
+void __add_class(_Iter __begin, _Iter __end)
+{
+  auto __class_type = __traits_.lookup_classname(__begin, __end, __icase_);
+  if (__class_type == 0)
+  __throw_regex_error();
+  __mask_ |= __class_type;
+}
+
+template 
 _LIBCPP_INLINE_VISIBILITY
-void __add_neg_class(typename regex_traits<_CharT>::char_class_type __mask)
-{__neg_mask_ |= __mask;}
+void __add_neg_class(_Iter __begin, _Iter __end)
+{
+  auto __class_type = __traits_.lookup_classname(__begin, __end, __icase_);
+  if (__class_type == 0)
+  __throw_regex_error();
+  __neg_mask_ |= __class_type;
+}
 };
 
 template 
@@ -3841,23 +3855,23 @@
 __str = _CharT(8);
 return ++__first;
 case 'd':
-__ml->__add_class(ctype_base::digit);
+__ml->__add_class(__first, std::next(__first));
 return ++__first;
 case 'D':
-__ml->__add_neg_class(ctype_base::digit);
+__ml->__add_neg_class(__first, std::next(__first));
 return ++__first;
 case 's':
-__ml->__add_class(ctype_base::space);
+__ml->__add_class(__first, std::next(__first));
 return ++__first;
 case 'S':
-__ml->__add_neg_class(ctype_base::space);
+__ml->__add_neg_class(__first, std::next(__first));
 return ++__first;
 case 'w':
-__ml->__add_class(ctype_base::alnum);
+   

  1   2   >