This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/80265] __builtin_{memcmp,memchr,strlen} are not usable in constexpr functions


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80265

--- Comment #31 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Pedro Alves from comment #28)
> So back to the constexpr __builtin_memcmp, or __constexpr_memcmp ideas.
> 
> Though I still don't see how __constexpr_memcmp would make a difference wrt
> to number of __equal::equal implementations, but now I'm thinking that
> that's not what you meant.

It's not what I meant :-)

What I mean is that when you call std::equal today, it either dispatches to a
for-loop, or __builtin_memcmp. That's two.

If we replaced __builtin_memcmp with __constexpr_memcmp which either uses a
for-loop or memcmp, then we have three. The foor-loop in __equal<false>::equal,
or a for-loop in __constexpr_memcmp, or a call to __builtin_memcmp.

There are still only two versions of __equal<bool>::equal but we do have more
code, and two for-loops that are effectively identical (one in
__equal<false>::equal and one in __constexpr_memcmp). If the one in
__constexpr_memcmp is guaranteed to always be optimized out that's great, but I
don't know if it's guaranteed. Intuitively, adding more code doesn't seem like
it's going to _help_ guarantee we optimize everything out :-)

> From my view, __constexpr_memcmp implemented in
> a helper constexpr function or directly in the frontend (as
> __builtin_memcmp), is just an implementation detail of the function. 
> Ultimately, __constexpr_memcmp or constexpr __builtin_memcmp ends up
> interpreted in a similar way internally, I expect.

I would hope so, but I'd like to be certain, not hopeful.


It would be nice if we could just add _GLIBCXX17_CONSTEXPR in a few places and
then do:

--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -807,11 +807,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __equal<true>
     {
       template<typename _Tp>
-       static bool
+       static _GLIBCXX14_CONSTEXPR bool
        equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2)
        {
          if (const size_t __len = (__last1 - __first1))
+         {
+           if (__builtin_constant_p( something something ))
+             return __equal<false>::equal(__first1, __last1, __first2);
            return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) * __len);
+         }
          return true;
        }
     };

(For some value of "something something", as you did for char_traits).

This is somewhere that https://wg21.link/p0595r0 would help again (and if the
arguments aren't constants, we just get an error in __equal<false>::equal).

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]