[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] 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] 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, element_aligned_tag());
+  supported_load((unsigned int*)

[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 &e) {
+  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 &e) {
+  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 &e) {
+  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 &e) {
+  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] 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&id=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] 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] 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>, "");
-sta

[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: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-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>, "");
-static_

[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
This revision was automatically updated to reflect the committed changes.
Closed by commit rL338309: [libcxx] implement  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&id=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] 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] 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] 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] 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: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: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-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] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-24 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
Herald added subscribers: eraman, inglorion, Prazek, mehdi_amini.

Also see https://reviews.llvm.org/D33429 for other ThinLTO + New PM related 
changes.


https://reviews.llvm.org/D33525

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/CodeGen/thin_link_bitcode.c
  llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
  llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp

Index: llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
===
--- llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -7,13 +7,11 @@
 //
 //===--===//
 //
-// This pass prepares a module containing type metadata for ThinLTO by splitting
-// it into regular and thin LTO parts if possible, and writing both parts to
-// a multi-module bitcode file. Modules that do not contain type metadata are
-// written unmodified as a single module.
+// Pass implementation.
 //
 //===--===//
 
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -421,6 +419,21 @@
 AU.addRequired();
   }
 };
+
+class AARGetter {
+  FunctionAnalysisManager &AM;
+  Optional AAR;
+
+public:
+  AARGetter(FunctionAnalysisManager &AM) : AM(AM) {}
+
+  AAResults &operator()(Function &F) {
+if (!AAR)
+  AAR.emplace(AAManager().run(F, AM));
+return *AAR;
+  }
+};
+
 } // anonymous namespace
 
 char WriteThinLTOBitcode::ID = 0;
@@ -436,3 +449,13 @@
 raw_ostream *ThinLinkOS) {
   return new WriteThinLTOBitcode(Str, ThinLinkOS);
 }
+
+PreservedAnalyses
+llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
+  writeThinLTOBitcode(
+  OS, ThinLinkOS,
+  AARGetter(
+  AM.getResult(M).getManager()),
+  M, &AM.getResult(M));
+  return PreservedAnalyses::all();
+}
Index: llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
===
--- /dev/null
+++ llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -0,0 +1,39 @@
+//===- ThinLTOBitcodeWriter.h - Bitcode writing pass for ThinLTO --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This pass prepares a module containing type metadata for ThinLTO by splitting
+// it into regular and thin LTO parts if possible, and writing both parts to
+// a multi-module bitcode file. Modules that do not contain type metadata are
+// written unmodified as a single module.
+//
+//===--===//
+
+#ifndef LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+#define LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+
+#include 
+#include 
+
+namespace llvm {
+
+class ThinLTOBitcodeWriterPass
+: public PassInfoMixin {
+  raw_ostream &OS;
+  raw_ostream *ThinLinkOS;
+
+public:
+  ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS)
+  : OS(OS), ThinLinkOS(ThinLinkOS) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif
Index: clang/test/CodeGen/thin_link_bitcode.c
===
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,9 +1,12 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t -flto=thin -fexperimental-new-pass-manager -fthin-link-bitcode=%t.newpm -triple x86_64-unknown-linux-gnu -emit-llvm-bc %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s --check-prefix=NEW_PM
 int main (void) {
   return 0;
 }
 
 // CHECK: COMPILE_UNIT
 // NO_DEBUG-NOT: COMPILE_UNIT
+// NEW_PM-NOT: COMPILE_UNIT
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -898,16 +899,33 @@
   // create that pass manager here and use 

[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-24 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp:423
+
+class AARGetter {
+  FunctionAnalysisManager &AM;

mehdi_amini wrote:
> Can't you do it with a lambda?
I can, except that AAR needs to be allocated outside of the lambda, on the 
stack:

Optional AAR;
auto F = [&AAR](Function &) -> AAResults& { ... };

(AAR can't be captured by value, since AAResults is not copyable) this way AAR 
out-lives the lambda, and I feel less readable.


https://reviews.llvm.org/D33525



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


[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-25 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

In https://reviews.llvm.org/D33525#764251, @chandlerc wrote:

> (focusing on the LLVM side of this review for now)
>
> Can you add an LLVM-based test? Can you add this to 
> `lib/Passes/PassRegistry.def`?


I see that not all passes are registered (BitcodeWriterPass). Is it an 
oversight?

Does a pass have to be default constructible, in order to be registered easily?


https://reviews.llvm.org/D33525



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


[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-26 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 100462.
timshen added a comment.

Change the test case.


https://reviews.llvm.org/D33525

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/CodeGen/thin_link_bitcode.c
  llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
  llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp

Index: llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
===
--- llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -7,13 +7,11 @@
 //
 //===--===//
 //
-// This pass prepares a module containing type metadata for ThinLTO by splitting
-// it into regular and thin LTO parts if possible, and writing both parts to
-// a multi-module bitcode file. Modules that do not contain type metadata are
-// written unmodified as a single module.
+// Pass implementation.
 //
 //===--===//
 
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -436,3 +434,15 @@
 raw_ostream *ThinLinkOS) {
   return new WriteThinLTOBitcode(Str, ThinLinkOS);
 }
+
+PreservedAnalyses
+llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
+  FunctionAnalysisManager &FAM =
+  AM.getResult(M).getManager();
+  writeThinLTOBitcode(OS, ThinLinkOS,
+  [&FAM](Function &F) -> AAResults & {
+return FAM.getResult(F);
+  },
+  M, &AM.getResult(M));
+  return PreservedAnalyses::all();
+}
Index: llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
===
--- /dev/null
+++ llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -0,0 +1,39 @@
+//===- ThinLTOBitcodeWriter.h - Bitcode writing pass for ThinLTO --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This pass prepares a module containing type metadata for ThinLTO by splitting
+// it into regular and thin LTO parts if possible, and writing both parts to
+// a multi-module bitcode file. Modules that do not contain type metadata are
+// written unmodified as a single module.
+//
+//===--===//
+
+#ifndef LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+#define LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+
+#include 
+#include 
+
+namespace llvm {
+
+class ThinLTOBitcodeWriterPass
+: public PassInfoMixin {
+  raw_ostream &OS;
+  raw_ostream *ThinLinkOS;
+
+public:
+  ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS)
+  : OS(OS), ThinLinkOS(ThinLinkOS) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif
Index: clang/test/CodeGen/thin_link_bitcode.c
===
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager -fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s --check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -898,16 +899,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addPass(BitcodeWriterPass(*OS, Code

[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-26 Thread Tim Shen via Phabricator via cfe-commits
timshen marked an inline comment as done.
timshen added a comment.

In https://reviews.llvm.org/D33525#764251, @chandlerc wrote:

> (focusing on the LLVM side of this review for now)
>
> Can you add an LLVM-based test? Can you add this to 
> `lib/Passes/PassRegistry.def`?


Talked offline. Given the fact that BitcodeWriter (and possibly assembly 
writer?) is not registered either, it seems to be a larger issue that's out of 
the scope of this patch.


https://reviews.llvm.org/D33525



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


[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-26 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 100488.
timshen added a comment.

Add opt support and llvm test.


https://reviews.llvm.org/D33525

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/CodeGen/thin_link_bitcode.c
  llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
  llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
  llvm/test/Transforms/ThinLTOBitcodeWriter/new-pm.ll
  llvm/tools/opt/NewPMDriver.cpp
  llvm/tools/opt/NewPMDriver.h
  llvm/tools/opt/opt.cpp

Index: llvm/tools/opt/opt.cpp
===
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -529,12 +529,19 @@
 // The user has asked to use the new pass manager and provided a pipeline
 // string. Hand off the rest of the functionality to the new code for that
 // layer.
-return runPassPipeline(argv[0], *M, TM.get(), Out.get(),
-   PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
-   PreserveBitcodeUseListOrder, EmitSummaryIndex,
-   EmitModuleHash)
-   ? 0
-   : 1;
+Optional ThinLTOBC;
+if (OutputThinLTOBC)
+  ThinLTOBC.emplace(ThinLinkOut.get());
+if (!runPassPipeline(argv[0], *M, TM.get(), Out.get(), PassPipeline, OK, VK,
+ PreserveAssemblyUseListOrder,
+ PreserveBitcodeUseListOrder, EmitSummaryIndex,
+ EmitModuleHash, ThinLTOBC))
+  return 1;
+
+if (ThinLinkOut)
+  ThinLinkOut->keep();
+
+return 0;
   }
 
   // Create a PassManager to hold and optimize the collection of passes we are
Index: llvm/tools/opt/NewPMDriver.h
===
--- llvm/tools/opt/NewPMDriver.h
+++ llvm/tools/opt/NewPMDriver.h
@@ -21,6 +21,8 @@
 #ifndef LLVM_TOOLS_OPT_NEWPMDRIVER_H
 #define LLVM_TOOLS_OPT_NEWPMDRIVER_H
 
+#include 
+
 namespace llvm {
 class StringRef;
 class LLVMContext;
@@ -47,13 +49,16 @@
 /// inclusion of the new pass manager headers and the old headers into the same
 /// file. It's interface is consequentially somewhat ad-hoc, but will go away
 /// when the transition finishes.
-bool runPassPipeline(StringRef Arg0, Module &M,
- TargetMachine *TM, tool_output_file *Out,
- StringRef PassPipeline, opt_tool::OutputKind OK,
- opt_tool::VerifierKind VK,
+///
+/// ThinLTOBC indicates whether to use ThinLTO's bitcode writer, and if so,
+/// the optional link file path.
+bool runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+ tool_output_file *Out, StringRef PassPipeline,
+ opt_tool::OutputKind OK, opt_tool::VerifierKind VK,
  bool ShouldPreserveAssemblyUseListOrder,
  bool ShouldPreserveBitcodeUseListOrder,
- bool EmitSummaryIndex, bool EmitModuleHash);
+ bool EmitSummaryIndex, bool EmitModuleHash,
+ Optional ThinLTOBC);
 }
 
 #endif
Index: llvm/tools/opt/NewPMDriver.cpp
===
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -29,6 +29,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Scalar/LoopPassManager.h"
 
 using namespace llvm;
@@ -47,13 +48,13 @@
 "pipeline for handling managed aliasing queries"),
cl::Hidden);
 
-bool llvm::runPassPipeline(StringRef Arg0, Module &M,
-   TargetMachine *TM, tool_output_file *Out,
-   StringRef PassPipeline, OutputKind OK,
-   VerifierKind VK,
+bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+   tool_output_file *Out, StringRef PassPipeline,
+   OutputKind OK, VerifierKind VK,
bool ShouldPreserveAssemblyUseListOrder,
bool ShouldPreserveBitcodeUseListOrder,
-   bool EmitSummaryIndex, bool EmitModuleHash) {
+   bool EmitSummaryIndex, bool EmitModuleHash,
+   Optional ThinLTOBC) {
   PassBuilder PB(TM);
 
   // Specially handle the alias analysis manager so that we can register
@@ -101,8 +102,12 @@
 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
 break;
   case OK_OutputBitcode:
-MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
-  EmitSummaryIndex, EmitModuleHash));
+if (ThinLTOBC)
+  MPM.addPass(ThinLTOBitcodeWriterPass(
+  Out->os(), *ThinLTOBC ? &(*ThinLTOBC)->os() : nullptr));
+else
+  MPM.addPass(BitcodeWri

[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-29 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: llvm/test/Transforms/ThinLTOBitcodeWriter/new-pm.ll:1
+; RUN: opt -passes='lto' -debug-pass-manager -thinlto-bc 
-thin-link-bitcode-file=%t2 -o %t %s 2>&1 | FileCheck %s --check-prefix=DEBUG_PM
+; RUN: llvm-bcanalyzer -dump %t2 | FileCheck %s --check-prefix=BITCODE

chandlerc wrote:
> Why run any passes here? 
I saw that the runPassPipeline call is in  `if 
(PassPipeline.getNumOccurrences() > 0) {`. I take that as "must specify 
-passes" in order to run the new pass manager (which is created in 
runPassPipeline). And specifiy an empty -passes cause an error message "unable 
to parse pass pipeline description".



Comment at: llvm/tools/opt/NewPMDriver.h:61
+ bool EmitSummaryIndex, bool EmitModuleHash,
+ Optional ThinLTOBC);
 }

chandlerc wrote:
> Why an optional pointer? Maybe just allow the pointer to be null if there 
> isn't a thin link output file?
There are 3 states:
1) Use ThinLTOBitcodeWrite pass, controlled by OutputThinLTOBC, and the output 
file is not null.
2) OutputThinLTOBC is true, but output file is null (don't write to the file).
3) OutputThinLTOBC is false.

An optional nullable pointer, confusing as it might be (but I'm not sure how 
much), provides 3 states.

If we instead pass in a bool and a pointer, that's 4 states, one of which is 
invalid.


https://reviews.llvm.org/D33525



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


[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

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

Updated based on the comments, and left out Clang changes for a separate patch.


https://reviews.llvm.org/D33525

Files:
  llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
  llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
  llvm/test/Transforms/ThinLTOBitcodeWriter/new-pm.ll
  llvm/tools/opt/NewPMDriver.cpp
  llvm/tools/opt/NewPMDriver.h
  llvm/tools/opt/opt.cpp

Index: llvm/tools/opt/opt.cpp
===
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -529,10 +529,13 @@
 // The user has asked to use the new pass manager and provided a pipeline
 // string. Hand off the rest of the functionality to the new code for that
 // layer.
-return runPassPipeline(argv[0], *M, TM.get(), Out.get(),
-   PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
+Optional ThinLTOBC;
+if (OutputThinLTOBC)
+  ThinLTOBC = ThinLinkOut.get();
+return runPassPipeline(argv[0], *M, TM.get(), Out.get(), PassPipeline, OK,
+   VK, PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex,
-   EmitModuleHash)
+   EmitModuleHash, ThinLTOBC)
? 0
: 1;
   }
Index: llvm/tools/opt/NewPMDriver.h
===
--- llvm/tools/opt/NewPMDriver.h
+++ llvm/tools/opt/NewPMDriver.h
@@ -21,6 +21,8 @@
 #ifndef LLVM_TOOLS_OPT_NEWPMDRIVER_H
 #define LLVM_TOOLS_OPT_NEWPMDRIVER_H
 
+#include 
+
 namespace llvm {
 class StringRef;
 class LLVMContext;
@@ -47,13 +49,16 @@
 /// inclusion of the new pass manager headers and the old headers into the same
 /// file. It's interface is consequentially somewhat ad-hoc, but will go away
 /// when the transition finishes.
-bool runPassPipeline(StringRef Arg0, Module &M,
- TargetMachine *TM, tool_output_file *Out,
- StringRef PassPipeline, opt_tool::OutputKind OK,
- opt_tool::VerifierKind VK,
+///
+/// ThinLTOBC indicates whether to use ThinLTO's bitcode writer, and if so,
+/// the *nullable* pointer points to the opened link file.
+bool runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+ tool_output_file *Out, StringRef PassPipeline,
+ opt_tool::OutputKind OK, opt_tool::VerifierKind VK,
  bool ShouldPreserveAssemblyUseListOrder,
  bool ShouldPreserveBitcodeUseListOrder,
- bool EmitSummaryIndex, bool EmitModuleHash);
+ bool EmitSummaryIndex, bool EmitModuleHash,
+ Optional ThinLTOBC);
 }
 
 #endif
Index: llvm/tools/opt/NewPMDriver.cpp
===
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -29,6 +29,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Scalar/LoopPassManager.h"
 
 using namespace llvm;
@@ -47,13 +48,13 @@
 "pipeline for handling managed aliasing queries"),
cl::Hidden);
 
-bool llvm::runPassPipeline(StringRef Arg0, Module &M,
-   TargetMachine *TM, tool_output_file *Out,
-   StringRef PassPipeline, OutputKind OK,
-   VerifierKind VK,
+bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+   tool_output_file *Out, StringRef PassPipeline,
+   OutputKind OK, VerifierKind VK,
bool ShouldPreserveAssemblyUseListOrder,
bool ShouldPreserveBitcodeUseListOrder,
-   bool EmitSummaryIndex, bool EmitModuleHash) {
+   bool EmitSummaryIndex, bool EmitModuleHash,
+   Optional ThinLTOBC) {
   PassBuilder PB(TM);
 
   // Specially handle the alias analysis manager so that we can register
@@ -101,8 +102,13 @@
 PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
 break;
   case OK_OutputBitcode:
-MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
-  EmitSummaryIndex, EmitModuleHash));
+if (ThinLTOBC)
+  MPM.addPass(ThinLTOBitcodeWriterPass(
+  Out->os(), *ThinLTOBC ? &(*ThinLTOBC)->os() : nullptr));
+else
+  MPM.addPass(BitcodeWriterPass(Out->os(),
+ShouldPreserveBitcodeUseListOrder,
+EmitSummaryIndex, EmitModuleHash));
 break;
   }
 
@@ -113,7 +119,10 @

[PATCH] D33525: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-30 Thread Tim Shen via Phabricator via cfe-commits
timshen added inline comments.



Comment at: llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp:443
+  writeThinLTOBitcode(OS, ThinLinkOS,
+  [&FAM](Function &F) -> AAResults & {
+return FAM.getResult(F);

chandlerc wrote:
> Are we unable to deduce the return type here?
No, because return type deduction uses "auto deduction" instead of "decltype 
deduction" - it deduces to a value type.



Comment at: llvm/tools/opt/NewPMDriver.h:61
+ bool EmitSummaryIndex, bool EmitModuleHash,
+ Optional ThinLTOBC);
 }

chandlerc wrote:
> timshen wrote:
> > chandlerc wrote:
> > > Why an optional pointer? Maybe just allow the pointer to be null if there 
> > > isn't a thin link output file?
> > There are 3 states:
> > 1) Use ThinLTOBitcodeWrite pass, controlled by OutputThinLTOBC, and the 
> > output file is not null.
> > 2) OutputThinLTOBC is true, but output file is null (don't write to the 
> > file).
> > 3) OutputThinLTOBC is false.
> > 
> > An optional nullable pointer, confusing as it might be (but I'm not sure 
> > how much), provides 3 states.
> > 
> > If we instead pass in a bool and a pointer, that's 4 states, one of which 
> > is invalid.
> Ok, but is #2 in your list actually useful? Maybe it is, but if it is then at 
> the very least the comment should make it super clear what is going on here. 
> Otherwise, I suspect many readers will assume than when the optional is 
> engaged the pointer isn't null as that's just too "obvious". 
#2 is consistent with opt's legacy pass manager behavior (search 
"createWriteThinLTOBitcodePass" in opt.cpp).

I added an emphasized "*nullable*" in the comment. :)


https://reviews.llvm.org/D33525



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


[PATCH] D33692: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-05-30 Thread Tim Shen via Phabricator via cfe-commits
timshen created this revision.
Herald added subscribers: inglorion, Prazek, mehdi_amini.

Also see https://reviews.llvm.org/D33429 for other ThinLTO + New PM related 
changes.


https://reviews.llvm.org/D33692

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/CodeGen/thin_link_bitcode.c


Index: clang/test/CodeGen/thin_link_bitcode.c
===
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple 
x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager 
-fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu 
-emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s 
--check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -898,16 +899,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-  CodeGenOpts.EmitSummaryIndex,
-  CodeGenOpts.EmitSummaryIndex));
+if (CodeGenOpts.EmitSummaryIndex) {
+  if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
+std::error_code EC;
+ThinLinkOS.reset(raw_fd_ostream(CodeGenOpts.ThinLinkBitcodeFile, EC,
+llvm::sys::fs::F_None));
+if (EC) {
+  Diags.Report(diag::err_fe_unable_to_open_output)
+  << CodeGenOpts.ThinLinkBitcodeFile << EC.message();
+  return;
+}
+  }
+  MPM.addPass(
+  ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr));
+} else {
+  MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+CodeGenOpts.EmitSummaryIndex,
+CodeGenOpts.EmitSummaryIndex));
+}
 break;
 
   case Backend_EmitLL:


Index: clang/test/CodeGen/thin_link_bitcode.c
===
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager -fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s --check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -898,16 +899,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-  CodeGenOpts.EmitSummaryIndex,
-  CodeGenOpts.EmitSummaryIndex));
+if (CodeGenOpts.EmitSummaryIndex) {
+  if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {

[PATCH] D33692: [ThinLTO] Migrate ThinLTOBitcodeWriter to the new PM.

2017-06-01 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 101106.
timshen added a comment.

Rebase the patch onto https://reviews.llvm.org/D33799.


https://reviews.llvm.org/D33692

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/CodeGen/thin_link_bitcode.c


Index: clang/test/CodeGen/thin_link_bitcode.c
===
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple 
x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager 
-fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu 
-emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s 
--check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -897,16 +898,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-  CodeGenOpts.EmitSummaryIndex,
-  CodeGenOpts.EmitSummaryIndex));
+if (CodeGenOpts.EmitSummaryIndex) {
+  if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
+std::error_code EC;
+ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC,
+   llvm::sys::fs::F_None);
+if (EC) {
+  Diags.Report(diag::err_fe_unable_to_open_output)
+  << CodeGenOpts.ThinLinkBitcodeFile << EC.message();
+  return;
+}
+  }
+  MPM.addPass(
+  ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr));
+} else {
+  MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+CodeGenOpts.EmitSummaryIndex,
+CodeGenOpts.EmitSummaryIndex));
+}
 break;
 
   case Backend_EmitLL:
@@ -1029,6 +1046,7 @@
   Conf.CGOptLevel = getCGOptLevel(CGOpts);
   initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
   Conf.SampleProfile = std::move(SampleProfile);
+  Conf.UseNewPM = CGOpts.ExperimentalNewPassManager;
   switch (Action) {
   case Backend_EmitNothing:
 Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) {


Index: clang/test/CodeGen/thin_link_bitcode.c
===
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager -fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s --check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }
Index: clang/lib/CodeGen/BackendUtil.cpp
===
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -897,16 +898,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addP

[PATCH] D33692: [ThinLTO] Wire up ThinLTO and new PM

2017-06-01 Thread Tim Shen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL304496: [ThinLTO] Wire up ThinLTO and new PM (authored by 
timshen).

Changed prior to commit:
  https://reviews.llvm.org/D33692?vs=101106&id=101135#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D33692

Files:
  cfe/trunk/lib/CodeGen/BackendUtil.cpp
  cfe/trunk/test/CodeGen/thin_link_bitcode.c


Index: cfe/trunk/lib/CodeGen/BackendUtil.cpp
===
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -897,16 +898,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-  CodeGenOpts.EmitSummaryIndex,
-  CodeGenOpts.EmitSummaryIndex));
+if (CodeGenOpts.EmitSummaryIndex) {
+  if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
+std::error_code EC;
+ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC,
+   llvm::sys::fs::F_None);
+if (EC) {
+  Diags.Report(diag::err_fe_unable_to_open_output)
+  << CodeGenOpts.ThinLinkBitcodeFile << EC.message();
+  return;
+}
+  }
+  MPM.addPass(
+  ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr));
+} else {
+  MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+CodeGenOpts.EmitSummaryIndex,
+CodeGenOpts.EmitSummaryIndex));
+}
 break;
 
   case Backend_EmitLL:
@@ -1029,6 +1046,7 @@
   Conf.CGOptLevel = getCGOptLevel(CGOpts);
   initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
   Conf.SampleProfile = std::move(SampleProfile);
+  Conf.UseNewPM = CGOpts.ExperimentalNewPassManager;
   switch (Action) {
   case Backend_EmitNothing:
 Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) {
Index: cfe/trunk/test/CodeGen/thin_link_bitcode.c
===
--- cfe/trunk/test/CodeGen/thin_link_bitcode.c
+++ cfe/trunk/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple 
x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager 
-fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu 
-emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s 
--check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }


Index: cfe/trunk/lib/CodeGen/BackendUtil.cpp
===
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -897,16 +898,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
 break;
 
   case Backend_EmitBC:
-MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-  CodeGenOpts.EmitSummaryIndex,
-  CodeGenOpts.EmitSummaryIndex));
+if (CodeGenOpts.EmitSummaryIndex) {
+  if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
+std::error_code EC;
+ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC,
+   llvm::sys::fs::F_None);
+if (EC) {
+  Diags.Report(diag::err_fe_unable_to_open_output)
+  << CodeGenOpts.ThinLinkBitcodeFile << EC.message();
+  return;
+}
+  }
+  MPM.addPass(
+  ThinLTOBitcodeWriterPa

[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>, "");
+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>, "");
+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_

[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-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>, "");
+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>, "");
+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

[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(
+std::declval>().copy_from(std::forward(args)...),
+ 

[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};
+  {
+fixed_size_simd a;
+a.copy_from(buffer, element

[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};
+  {
+fixed_size_simd a;
+a.copy_from(buf

[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, 3, 2, 1};
+  {
+fixed_size_simd a;
+a.cop

[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 / 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 
+
+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::size() / 2, simd_abi::compatible>>;
+  using native_simd_half =
+  simd::size() / 2,
+ simd_abi::native>>;
+
+  static_assert(
+  std::is_same<
+  decltype(
+  split::size() / 2, simd::size() / 2>(simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same::size() / 2,
+ native_simd::size() / 2>(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>& __v);
+//
+// template 
+// simd_mask + ...)>>
+// concat(const simd_mask&...);
+//
+// template 
+// simd_mask, Abi>>
+// concat(const std::array, N>&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_concat() {
+  auto v = concat(fixed_size_simd([](int i) { return i; }),
+  fixed_size_simd([](int i) { return i + 1; }),
+  fixed_size_simd([](int i) { return i + 3; }));
+  static_assert(v.size() == 6, "");
+  assert(v[0] == 0);
+  assert(v[1] == 1);
+  assert(v[2

[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::size()>([](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::size()>,
+ 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::size()>([](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; })));
+  static_a

[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>, "");
+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>, "");
+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_a

[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 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_hmax() {
+  {
+int a[] = {2

[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) int32_t buffer[] = {4, 3, 2, 1};
+  {
+fixed_s

[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::size()>([](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::size()>,
+ 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::size()>([](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; })));
+  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_

[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] 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] 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>, "");
+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>, "");
+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-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());
+  supported_load((float*)nullptr, element_aligned_tag());
+
+  not_suppo

[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, element_aligned_tag());
+
+  not_supported_load((bool*)nullptr, int());
+}
+
+void test_load() {
+ 

[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]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_

[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::size() / 2, simd_abi::compatible>>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::compatible>>;
+  using native_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::native>>;
+
+  static_assert(std::is_same::size() / 2,
+simd_mask::size() / 2>(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split::size() / 2,
+ native_simd_mask::size() / 2>(
+  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.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03
+
+// 
+//
+// // reductions [simd.mask.reductions]
+// template  bool all_of(const simd_mask&) noexcept;
+// template  bool any_of(const simd_mask&) noexcept;
+// template  bool none_of(const simd_mask&) noexcept;
+// template  bool some_of(const simd_mask&) noexcept;
+// template  int popcount(const simd_mask&) noexcept;
+// template  int find_first_set(const simd_ma

[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::size() / 2, simd_abi::compatible>>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::compatible>>;
+  using native_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::native>>;
+
+  static_assert(std::is_same::size() / 2,
+simd_mask::size() / 2>(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split::size() / 2,
+ native_simd_mask::size() / 2>(
+  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]
+// template  bool all_of(const simd_mask&) noexcept;
+// template  bool any_of(const simd_mask&) noexcept;
+// template  bool none_of(const simd_mask&) noexcept;
+// template  bool some_of(const simd_mask&) noexcept;
+// template  int popcount(const simd_mask&) noexcept;
+// template  int find_first_set(const simd_mask&);
+// template  int find_last_set(const simd_mask&);
+//
+// bool all_of(see below ) noexcept;
+// bool any_of(se

[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; });
+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; });
+   

[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 &x,
 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(a, element_aligned_tag())) == 6);
@@ -39,4 +39,27 @@
   }
 }
 
-int main() { test_hmax(); }
+void test_hmax

[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] 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] 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() {
+  alignas(32) int32_t buffer[] = {4, 3, 2, 1};
+  {
+fi

[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 / 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 
+
+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::size() / 2, simd_abi::compatible>>;
+  using native_simd_half =
+  simd::size() / 2,
+ simd_abi::native>>;
+
+  static_assert(
+  std::is_same<
+  decltype(
+  split::size() / 2, simd::size() / 2>(simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same::size() / 2,
+ native_simd::size() / 2>(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>& __v);
+//
+// template 
+// simd_mask + ...)>>
+// concat(const simd_mask&...);
+//
+// template 
+// simd_mask, Abi>>
+// concat(const std::array, N>&);
+
+#include 
+#include 
+#include 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_concat() {
+  auto v = concat(fixed_size_simd([](int i) { return i; }),
+  fixed_size_simd([](int i) { return i + 1; }),
+  fixed_size_simd([](int i) { return i + 3; }));
+  static_assert(v.size() == 6, "");
+  assert(v[0] == 0);
+  assert(v[1] == 1);
+  assert(v[2] == 2);
+  assert(v[3] == 3);
+  assert(v[4] == 4);
+  assert(v[5] == 5);
+}
+
+void test_concat_array() {
+  std::ar

[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>, "");
+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>, "");
+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] 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::size()>([](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::size()>,
+ 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::size()>([](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; })));
+  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_compatible();
+  test_to_compatible_extension();
+}

[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]);
+  }
+  {
+fixed_size_simd_mask a;
+a.copy_from(buffer, overalign

[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, 5, -4, 6};
+assert(hmax(fixed_size_simd(a, element_aligned_tag())) == 6);
+  }
+  {
+int a[] = {

[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::size() / 2, simd_abi::compatible>>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::compatible>>;
+  using native_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::native>>;
+
+  static_assert(std::is_same::size() / 2,
+simd_mask::size() / 2>(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split::size() / 2,
+ native_simd_mask::size() / 2>(
+  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]
+// template  bool all_of(const simd_mask&) noexcept;
+// template  bool any_of(const simd_mask&) noexcept;
+// template  bool none_of(const simd_mask&) noexcept;
+// template  bool some_of(const simd_mask&) noexcept;
+// template  int popcount(const simd_mask&) noexcept;
+// template  int find_first_set(const simd_mask&);
+// template  int find_last_set(const simd_mask&);
+//
+// bool all_of(see below ) noexcept;
+// bool any_of(see below ) noexcept;
+// bool none_of(see below ) n

[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, unsigned int>::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
+++ libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
@@ -54,8 +54,7 @@
 static_assert(is_abi_tag>::value, "");
 static_assert(is_abi_tag>::value, "");
 
-#if T

[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>, "");
+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>, "");
+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] 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::size()>([](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::size()>,
+ 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::size()>([](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; })));
+  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_compatible();
+ 

[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());
+}
+
+void test_load() {
+  alignas(32) int32_t b

[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 / 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 
+
+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::size() / 2, simd_abi::compatible>>;
+  using native_simd_half =
+  simd::size() / 2,
+ simd_abi::native>>;
+
+  static_assert(
+  std::is_same<
+  decltype(
+  split::size() / 2, simd::size() / 2>(simd())),
+  std::tuple>::value,
+  "");
+
+  static_assert(
+  std::is_same::size() / 2,
+ native_simd::size() / 2>(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>>
+// 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 
+
+using namespace std::experimental::parallelism_v2;
+
+void test_concat() {
+  auto v = concat(fixed_size_simd([](int i) { return i; }),
+  fixed_size_simd([](int i) { return i + 1; }),
+  fixed_size_simd([](int i) { return i + 3; }));
+  static_assert(v.size() == 6, "");
+  assert(v[0] == 0);
+  assert(v[1] == 1);
+  assert(v[2] == 2);
+  assert(v[3] == 3);
+  assert(v[4] == 4);
+  assert(v[5] == 5);
+}
+
+v

[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]);
+assert(a[2]);
+assert(!a[3]);
+  }
+  {
+fixed_size_simd_mask a

[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 test_hmax() {
+  {
+int a[] = {2, 5, -4, 6};
+assert(hmax(fixed_size_simd(a, element_aligned_tag()

[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::size() / 2, simd_abi::compatible>>;
@@ -119,7 +167,41 @@
 "");
 }
 
+void compile_split_simd_mask_propagate_abi() {
+  using compatible_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::compatible>>;
+  using native_simd_mask_half =
+  simd_mask::size() / 2,
+  simd_abi::native>>;
+
+  static_assert(std::is_same::size() / 2,
+simd_mask::size() / 2>(
+ simd_mask())),
+ std::tuple>::value,
+"");
+
+  static_assert(
+  std::is_same<
+  decltype(split::size() / 2,
+ native_simd_mask::size() / 2>(
+  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

[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[] = {false, true, true, false};
+fixed_size_simd_mask a(buffer, element_aligned_tag());
+assert(hmax(where(fi

[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, unsigned int>::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
+++ libcxx/test/std/experimental/simd/simd.traits/is_abi_tag.pass.cpp
@@ -54,8 +54,7 @@
 static_assert(is_abi_tag>::value, "");
 static_assert(is_abi_tag>::value, "");
 
-#if TE

[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().__raw()),
+ ExpectedRawType>::value,
+"");
+  (void)SimdType(ExpectedRawType());
+  (void)static_cast(SimdType());
+}
+
+int main() {
+#if defined(__AVX__)
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256i>();
+  compile_raw, __m256>();
+  compile_raw, __m256d>();
+#elif defined(__SSE2__)
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128i>();
+  compile_raw, __m128>();
+  compile_raw, __m128d>();
+#elif defined(__ALTIVEC__) || defined(__VSX__)
+  compile_raw, __vector char>();
+  compile_raw, __vector char16_t>();
+  compile_raw, __vector char32_t>();
+  compile_raw, __vector wchar_t>();
+  compile_raw, __vector signed char>();
+  compile_raw, __vector signed short>();
+  compile_raw, __vector signed int>();
+  compile_raw, __vector signed long>();
+  compile_raw, __vector signed long long>();
+  compile_raw, __vector unsigned char>();
+  compile_raw, __vector unsigned short>();
+  compile_raw, __vector unsigned int>();
+  compile_raw, __vector unsigned long>();
+  compile_raw, __vector unsigned long long>();
+  compile_raw, __vector float>();
+  compile_raw, __vector double>();
+#elif defined(__ARM_NEON)
+  compile_raw, int8x16_t>();
+  compile_raw, int16x8_t>();
+  compile_raw, int32x4_t>();
+  compile_raw, int64x2_t>();
+  compile_raw, uint8x16_t>();
+  compile_raw, uint16x8_t>();
+  compile_raw, uint32x4_t>();
+  compile_raw, uint64x2_t>();
+  compile_raw, float32x4_t>();
+  compile_raw, float64x2_t>();
+
+  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)  \
-  _SPECIALIZE_VEC_EXT(_TYPE, 1);   \
-  _SPECIALIZE_VEC_EXT(_TYPE, 2);   \
-  _SPECIALIZE_VEC_EXT(_TYPE, 3);   \
-  _SPECIALIZE_VEC_EXT(_TYPE, 4);   \
-  _SPECIALIZE_VEC_EXT(_TYPE, 5);   \
-  _SPECIALIZE_VEC_EXT(_TYPE, 6);   \
-  _SPECIALIZE_VEC_EXT(_TYPE, 7);

[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] == 1);
+assert(a[2] == 2);
+assert(a[3] == 1);
+  }
+  {
+fixed_size_simd a([](int i) { return i; });
+where(a > -2, a) &= 1;
+assert(a[0] == 0);
+assert(a[1] == 

[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] 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++) {
-  __buffer[__i] = (*this)[__i];
-}
+__copy_to_impl<__memory_alignment_impl::value>(
+this, __buffer);
   }
 
   // scalar access [simd.mask.subscr]
@@ -2401,60 +2437,66 @@
   }
 };
 
-template 
+template 
 void __mask_copy_to(const simd<_Tp, _Abi>& __v, const simd_mask<_Tp, _Abi>& __m,
-_Up* __buffer, _Flags) {
-  // TODO: opti

[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), _ValueType(std::forward<_Up>(__u)), this->__m_);
+*this = this->__v_ / std::forward<_Up>(__u);
   }
 
  

[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);
   }
   {
 int a[] = {5, -4, 6, 2};
-assert(hmin(fixed_size_simd(a, element_aligned_tag())) == -4);
+assert(hmin(SimdType(a, element_aligned_t

[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)));
+assert

[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 operator-() const &&;
+//   T operator+() const &&;
+//   T operator~() const &&;
+//
 //   template  void copy_to(U* mem, Flags f) const &&;
 // };
 
Index: libcxx/test/std/experimental/simd/simd.traits/simd_abi_deduce.pass.cpp

[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] 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,
-const native_simd>>::value,
-"");
+static_assert(std::is_same,
+  native_simd>>::value,
+  "");
   }
   {
 const native_simd_mask a{};
 static_assert(
-std::is_same<
-decltype(where(a, a)),
-const_where_expression,
-   const native_simd_mask>>::value,
+std::is_same,
+native_simd_mask>>::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::size() / 2, simd_abi::compatible>>;
+  simd::size() / 2,
+   simd_abi::compatible>>;
   using native_simd_half =
-  simd::size() / 2,
- simd_abi::native>>;
+  simd::size() / 2,
+   simd_abi::native>>;
 
   static_assert(
   std::is_same<
@@ -169,11 +169,11 @@
 
 void compile_split_simd_mask_propagate_abi() {
   using compatible_simd_mask_half =
-  simd_mask::size() / 2,
-  simd_abi::compatible>>;
+  simd_mask::size() / 2,
+simd_abi::compatible>>;
   using native_simd_mask_half =
-  simd_mask::size() / 2,
-  simd_abi::native>>;
+  simd_mask::size() / 2,
+simd_abi::native>>;
 
   static_assert(std::is_same::size() / 2,
 simd_mask::size() / 2>(
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
@@ -87,10 +87,12 @@
 int main() {
   test_hmin_simd_power_of_2>();
   test_hmin_simd_power_of_2<
-  simd>>>();
+  simd>>>();
   test_hmin_simd>();
-  test_hmin_simd>>>();
+  test_hmin_simd<
+  simd>>>();
   test_hmin_simd>();
-  test_hmin_simd>>>();
+  test_hmin_simd<
+  simd>>>();
   test_hmin_mask();
 }
Index: libcxx/test/std/experimental/simd/simd.horizontal/hmax.pass.cpp
==

[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] D37955: [libcxx] Fix invert negative bracket match.

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

Ideally we want !(neg_mask || neg_char), aka (!neg_mask && !neg_char). Before 
the change, the code is (!neg_mask || !neg_char).

This fixes PR34310.


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,30 @@
+//===--===//
+//
+// 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 
+#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,23 @@
 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.
 {
-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_ &&
+  __traits_.isctype(__ch, __neg_mask_);
+  const bool __in_neg_chars =
+  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 +2457,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,30 @@
+//===--===//
+//
+// 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 
+#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,23 @@
 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.
 {
-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_ &&
+  __trai

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

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

Remove "#include " in the test. It was for debugging.


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,23 @@
 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.
 {
-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_ &&
+  __traits_.isctype(__ch, __neg_mask_);
+  const bool __in_neg_chars =
+  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 +2457,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,23 @@
 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.
 {
-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_ &&
+  __traits_.isctype(__ch, __neg_mask_);
+  const bool __in_neg_chars =
+  std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) !=

[PATCH] D37956: [libc++] Check back reference subscript overflow in a single place.

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

Currently it's checked in three places, including one place that's at
regex runtime.

There is no need to do runtime check, as all uses and definitions of
subexpress is known at regex compile-time.

This fixes PR34297.


https://reviews.llvm.org/D37956

Files:
  libcxx/include/regex
  libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp


Index: libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
===
--- libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
+++ libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
@@ -19,11 +19,14 @@
 #include 
 #include "test_macros.h"
 
-static bool error_badbackref_thrown(const char *pat)
+static bool error_badbackref_thrown(
+const char *pat,
+std::regex_constants::syntax_option_type flags =
+std::regex_constants::ECMAScript)
 {
 bool result = false;
 try {
-std::regex re(pat);
+std::regex re(pat, flags);
 } catch (const std::regex_error &ex) {
 result = (ex.code() == std::regex_constants::error_backref);
 }
@@ -34,6 +37,7 @@
 {
 assert(error_badbackref_thrown("\\1abc"));  // no references
 assert(error_badbackref_thrown("ab(c)\\2def")); // only one reference
+assert(error_badbackref_thrown("(cat)\\1", std::regex_constants::basic));
 
 //  this should NOT throw, because we only should look at the '1'
 //  See https://bugs.llvm.org/show_bug.cgi?id=31387
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -1745,8 +1745,6 @@
 void
 __back_ref<_CharT>::__exec(__state& __s) const
 {
-if (__mexp_ > __s.__sub_matches_.size())
-__throw_regex_error();
 sub_match& __sm = __s.__sub_matches_[__mexp_-1];
 if (__sm.matched)
 {
@@ -4320,8 +4318,6 @@
 for (++__first;
 __first != __last && '0' <= *__first && *__first <= '9'; 
++__first)
 __v = 10 * __v + *__first - '0';
-if (__v > mark_count())
-__throw_regex_error();
 __push_back_ref(__v);
 }
 }
@@ -4712,6 +4708,9 @@
 void
 basic_regex<_CharT, _Traits>::__push_back_ref(int __i)
 {
+if (__i > static_cast(mark_count()))
+__throw_regex_error();
+
 if (flags() & icase)
 __end_->first() = new __back_ref_icase<_CharT, _Traits>
   (__traits_, __i, 
__end_->first());


Index: libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
===
--- libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
+++ libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
@@ -19,11 +19,14 @@
 #include 
 #include "test_macros.h"
 
-static bool error_badbackref_thrown(const char *pat)
+static bool error_badbackref_thrown(
+const char *pat,
+std::regex_constants::syntax_option_type flags =
+std::regex_constants::ECMAScript)
 {
 bool result = false;
 try {
-std::regex re(pat);
+std::regex re(pat, flags);
 } catch (const std::regex_error &ex) {
 result = (ex.code() == std::regex_constants::error_backref);
 }
@@ -34,6 +37,7 @@
 {
 assert(error_badbackref_thrown("\\1abc"));  // no references
 assert(error_badbackref_thrown("ab(c)\\2def")); // only one reference
+assert(error_badbackref_thrown("(cat)\\1", std::regex_constants::basic));
 
 //  this should NOT throw, because we only should look at the '1'
 //  See https://bugs.llvm.org/show_bug.cgi?id=31387
Index: libcxx/include/regex
===
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -1745,8 +1745,6 @@
 void
 __back_ref<_CharT>::__exec(__state& __s) const
 {
-if (__mexp_ > __s.__sub_matches_.size())
-__throw_regex_error();
 sub_match& __sm = __s.__sub_matches_[__mexp_-1];
 if (__sm.matched)
 {
@@ -4320,8 +4318,6 @@
 for (++__first;
 __first != __last && '0' <= *__first && *__first <= '9'; ++__first)
 __v = 10 * __v + *__first - '0';
-if (__v > mark_count())
-__throw_regex_error();
 __push_back_ref(__v);
 }
 }
@@ -4712,6 +4708,9 @@
 void
 basic_regex<_CharT, _Traits>::__push_back_ref(int __i)
 {
+if (__i > static_cast(mark_count()))
+__throw_regex_error();
+
 if (flags() & icase)
 __end_->first() = new __back_ref_icase<_CharT, _Traits>
   (__traits_, __i, __end_->first());
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-co

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

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

Always lookup the class name, even when the traits type is regex_traits<>.
The lookup happens at regex compile time, so it shouldn't affect the 
performance.

I also added ja_JP.UTF-8 as a common locale.


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, true);
+  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));

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

2017-09-17 Thread Tim Shen via Phabricator via cfe-commits
timshen added a comment.

I'm not sure if we need to change the CI server to suport ja_JP.UTF-8.


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-17 Thread Tim Shen via Phabricator via cfe-commits
timshen updated this revision to Diff 115559.
timshen added a comment.

Update description.


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, true);
+  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);
+__ml->__add_class(__first, std::next(__first));
 __ml->__add_char('_');
 return ++__first;
 c

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

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

Stylize template decl to "template 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, true);
+  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);
+__ml->__add_class(__first, std::next(__first));
 __ml->__add_char('_');
 return ++

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

2017-09-17 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);
+__ml->__add_class(__first, std::next(__first));
 __ml->__add_char('

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

2017-09-17 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] 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: libcxx/test/std/re/re.alg/re.alg.search/extended.pass.cpp
===

[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, when __neg_mask_/__neg_chars_ is empty, they should be
+// treated as all ones/all chars.
 

[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] 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] 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, "");
+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>, "");
+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>, "");
+sta

  1   2   >