This is the mail archive of the gcc-patches@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] |
On 29/03/19 12:02 -0400, Ed Smith-Rowland wrote:
On 3/29/19 9:23 AM, Jakub Jelinek wrote:On Fri, Mar 29, 2019 at 09:10:26AM -0400, Ed Smith-Rowland via gcc-patches wrote:Greetings, This patch implements C++20 constexpr for <algorithm>, <uility>, <array>. It's a large patch but only affects C++20 and the volume is mostly test cases. This differs from the previous patch in actually testing constexpr :-\ and in the addition of wrappers for __builtin_memmove and __builtin_memcmp that supply constexpr branches if C++20 and is_constant_evaluated().+ void* + __memmove(_Tp* __dst, const _Tp* __src, ptrdiff_t __num) + { +#if __cplusplus > 201703L + if (is_constant_evaluated()) + { + for(; __num > 0; --__num) + { + *__dst = *__src; + ++__src; + ++__dst; + } + return __dst; + } + else if (__num) +#endif + return __builtin_memmove(__dst, __src, sizeof(_Tp) * abs(__num)); + return __dst; .. const ptrdiff_t _Num = __last - __first; if (_Num) - __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); + __memmove(__result, __first, _Num); .. const ptrdiff_t _Num = __last - __first; if (_Num) - __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + __memmove(__result - _Num, __first, _Num); Why the abs in there, that is something that wasn't previously there and if the compiler doesn't figure out that __last >= __first, it would mean larger emitted code for the non-constexpr case. As memmove argument is size_t, wouldn't it be better to make __num just size_t and remove this abs? Also, wouldn't it be better to have on the other side the __num == 0 handling inside of __memmove, you already have it there for C++2a, but not for older. You could then drop the if (_Num) guards around __memmove.memmove needs to be able to work with __last < __first also.
Why?
I was getting negative __num and when passed to __builtin_memmove which takes size_t got blowups.I'm not sure why it worked before. __builtin_memmove will work with __last < __first and sensible positive __num.When I tried to do what __builtin_memmove or ::memmove must do with unsigned num I would need to branch on __last < __first
How can last < first be true for any algorithm?
and copy backwards. But pointer comparisons were getting caught as non-constexpr.I'll look at the __num==0 (noop) testing.Also, shouldn't the is_constant_evaluated() calls be guarded with _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED ? Without that it won't be defined...I am trying for a C++20-only patch (hoping to get it in for 9) so I used the library function and tested __cplusplus > 201703L.We could do _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED and then we could use these for lower version. Maybe stage 1?
The reason to check _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED is that std::is_constant_evaluated() is not available when compiling with Clang, because it doesn't provide the built-in yet. It's fine to make the algos not constexpr when the builtin isn't available, it's not fine to just use something that won't compile.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |