Skip to content

[libc++] <experimental/simd> Add ++/-- operators for simd reference #88091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 14, 2024

Conversation

joy2myself
Copy link
Member

No description provided.

@joy2myself joy2myself requested a review from a team as a code owner April 9, 2024 05:41
@joy2myself joy2myself marked this pull request as draft April 9, 2024 05:42
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Apr 9, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 9, 2024

@llvm/pr-subscribers-libcxx

Author: ZhangYin (joy2myself)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/88091.diff

2 Files Affected:

  • (modified) libcxx/include/experimental/__simd/reference.h (+26)
  • (added) libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp (+43)
diff --git a/libcxx/include/experimental/__simd/reference.h b/libcxx/include/experimental/__simd/reference.h
index 7efbba96ec71b1..8fc1d97770f335 100644
--- a/libcxx/include/experimental/__simd/reference.h
+++ b/libcxx/include/experimental/__simd/reference.h
@@ -55,6 +55,32 @@ class __simd_reference {
     __set(static_cast<value_type>(std::forward<_Up>(__v)));
     return {__s_, __idx_};
   }
+
+  template <class _Up = value_type, class = decltype(std::declval<_Up>() + _Up{1})>
+  __simd_reference _LIBCPP_HIDE_FROM_ABI operator++() && noexcept {
+    __set(__get() + 1);
+    return {__s_, __idx_};
+  }
+
+  template <class _Up = value_type, class = decltype(std::declval<_Up>() + _Up{1})>
+  value_type _LIBCPP_HIDE_FROM_ABI operator++(int) && noexcept {
+    auto __r = __get();
+    __set(__get() + 1);
+    return __r;
+  }
+
+  template <class _Up = value_type, class = decltype(std::declval<_Up>() - _Up{1})>
+  __simd_reference _LIBCPP_HIDE_FROM_ABI operator--() && noexcept {
+    __set(__get() - 1);
+    return {__s_, __idx_};
+  }
+
+  template <class _Up = value_type, class = decltype(std::declval<_Up>() - _Up{1})>
+  value_type _LIBCPP_HIDE_FROM_ABI operator--(int) && noexcept {
+    auto __r = __get();
+    __set(__get() - 1);
+    return __r;
+  }
 };
 
 } // namespace parallelism_v2
diff --git a/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp b/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp
new file mode 100644
index 00000000000000..7452dc986cd4af
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.reference/reference_unary.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <experimental/simd>
+//
+// [simd.reference]
+// reference operator++() && noexcept;
+// value_type operator++(int) && noexcept;
+// reference operator--() && noexcept;
+// value_type operator--(int) && noexcept;
+
+#include "../test_utils.h"
+#include <experimental/simd>
+
+namespace ex = std::experimental::parallelism_v2;
+
+template <class T, std::size_t>
+struct CheckSimdReferenceUnaryOperators {
+  template <class SimdAbi>
+  void operator()() const {
+    ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));
+    static_assert(noexcept(++origin_simd[0]));
+    assert(((T)(++origin_simd[0]) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(4)));
+    static_assert(noexcept(origin_simd[0]++));
+    assert(((T)(origin_simd[0]++) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(5)));
+    static_assert(noexcept(--origin_simd[0]));
+    assert(((T)(--origin_simd[0]) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(4)));
+    static_assert(noexcept(origin_simd[0]--));
+    assert(((T)(origin_simd[0]--) == static_cast<T>(4)) && ((T)origin_simd[0] == static_cast<T>(3)));
+  }
+};
+
+int main(int, char**) {
+  test_all_simd_abi<CheckSimdReferenceUnaryOperators>();
+  return 0;
+}

@joy2myself joy2myself force-pushed the reference_unary branch 2 times, most recently from 07bfbb2 to 3e2b325 Compare August 12, 2024 09:51
@joy2myself
Copy link
Member Author

@philnik777 It seems that the floating-point types do support the ++ and -- operators (https://godbolt.org/z/GMcj5nb96). Now, I’ve added traits that check if operators exist and all the results for test types are the same. Is it necessary to keep these code?

@philnik777
Copy link
Contributor

@philnik777 It seems that the floating-point types do support the ++ and -- operators (https://godbolt.org/z/GMcj5nb96). Now, I’ve added traits that check if operators exist and all the results for test types are the same. Is it necessary to keep these code?

That's... surprising. In that case what's the point of the constraint? There should be some way to test them, otherwise they're just garbage.

@joy2myself
Copy link
Member Author

@philnik777 It seems that the floating-point types do support the ++ and -- operators (https://godbolt.org/z/GMcj5nb96). Now, I’ve added traits that check if operators exist and all the results for test types are the same. Is it necessary to keep these code?

That's... surprising. In that case what's the point of the constraint? There should be some way to test them, otherwise they're just garbage.

According to the specification, the set of vectorizable types for a data-parallel type comprises all cv-unqualified arithmetic types other than bool. This way, all valid types will support the ++, -- operators. Should I remove the code related to SFINAE checks and the code that tests them?

@joy2myself joy2myself force-pushed the reference_unary branch 2 times, most recently from cd23f68 to aec79c0 Compare August 12, 2024 12:04
@joy2myself
Copy link
Member Author

@philnik777 I just removed the constraint. See previous comment for the reason. Any other comments?

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm fine with it. Maybe add a comment saying that there doesn't seem to be a way to trigger the constraint.

@joy2myself joy2myself merged commit 812ae91 into llvm:main Aug 14, 2024
56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants