[libcxx-commits] [PATCH] D144394: [libc++] Forward to std::{, w}memcmp in std::find

Nikolas Klauser via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Mar 24 10:40:17 PDT 2023


philnik marked 2 inline comments as done.
philnik added inline comments.


================
Comment at: libcxx/include/__algorithm/find.h:54
+          __enable_if_t<__is_identity<_Proj>::value && __is_trivially_equality_comparable<_Tp, _Up>::value &&
+                            sizeof(_Tp) == sizeof(wchar_t) && alignof(_Tp) >= alignof(wchar_t),
+                        int> = 0>
----------------
Mordante wrote:
> philnik wrote:
> > Mordante wrote:
> > > Why not test `is_same_v<_Tp, wchar_t>`?
> > Because that would disable the optimization for other types that have the same size as `wchar_t`. For these types this optimization is probably UB, but that shouldn't be a problem in practice, since it's on an ABI boundary and no compiler currently optimizes `wmemchr` specifically (and IMO no compiler should ever optimize based on this, since there is no potential gain I can see).
> The function you call has the following signature
> 
> ```
> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const wchar_t*
> __constexpr_wmemchr(const wchar_t* __str, wchar_t __char, size_t __count)
> ```
> So how can this work when `_Tp` is not a `wchar_t`? That requires a `reinterpret_cast` which is not allowed during constant evaluation. What am I missing?
> 
Your signature is wrong, `__constexpr_wmemchr` is templated.



================
Comment at: libcxx/include/__string/constexpr_c_functions.h:73-83
+#if _LIBCPP_STD_VER >= 17 && __has_builtin(__builtin_char_memchr)
+    if constexpr (is_same<_Tp, char>::value)
+      return __builtin_char_memchr(__str, __char, __count);
 #endif
+
+    for (; __count; --__count) {
+      if (*__str == __char)
----------------
Mordante wrote:
> philnik wrote:
> > Mordante wrote:
> > > Note that the current way it's written generates unneeded code
> > This looks quite surprising to me, and I'm not sure it's worth the little bit of time the compiler spends on this.
> This is something we have used before. Now it will generate dead code.
clang doesn't even emit the condition from the fronted AFAICT, let alone the backend: https://godbolt.org/z/87bvzbhbT. This is at best a minimal compile time speedup.


================
Comment at: libcxx/test/std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp:78
+  types::for_each(types::integer_types(), TestTypes<long long>());
+  types::for_each(types::integer_types(), TestTypes<Comparable>());
+
----------------
Mordante wrote:
> I really would like to see tests for all types that will use this optimization. Especially to make sure the code is valid during constant evaluation.
We currently only have integral types and pointers marked trivially equality comparable,  and I don't think it's worth testing for pointers specifically, since they are for all intents and purposes integers with a funny syntax in this case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D144394



More information about the libcxx-commits mailing list