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

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

Rebase.


https://reviews.llvm.org/D41756

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

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

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

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

Rebased.


https://reviews.llvm.org/D41756

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

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

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

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

Add tests to boolean version of the horizontal operations.


https://reviews.llvm.org/D41756

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

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

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

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

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


https://reviews.llvm.org/D41756

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

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