[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2021-10-06 Thread m.cencora at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

m.cencora at gmail dot com changed:

   What|Removed |Added

 CC||m.cencora at gmail dot com

--- Comment #48 from m.cencora at gmail dot com ---
Any progress on this?

I have stumbled upon same inefficiencies when writing serialization code that
copies raw bytes to unsigned char* raw memory buffer from contiguous containers
(string/vector/array) with elements of any 1 byte trivially copyable type
(signed char, char, enum, UDT).

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2021-04-27 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

Jonathan Wakely  changed:

   What|Removed |Added

   Target Milestone|11.2|---

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2021-04-27 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|11.0|11.2

--- Comment #47 from Jakub Jelinek  ---
GCC 11.1 has been released, retargeting bugs to GCC 11.2.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-09-02 Thread cvs-commit at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #46 from CVS Commits  ---
The master branch has been updated by Jonathan Wakely :

https://gcc.gnu.org/g:2f983fa69005b603ea1758a013b4134d5b0f24a8

commit r11-2981-g2f983fa69005b603ea1758a013b4134d5b0f24a8
Author: Jonathan Wakely 
Date:   Wed Sep 2 15:17:24 2020 +0100

libstdc++: Fix three-way comparison for std::array [PR 96851]

The spaceship operator for std::array uses memcmp when the
__is_byte trait is true, but memcmp isn't usable in
constexpr contexts. Also, memcmp should only be used for unsigned byte
types, because it gives the wrong answer for signed chars with negative
values.

We can simply check std::is_constant_evaluated() so that we don't use
memcmp during constant evaluation.

To fix the problem of using memcmp for inappropriate types, this patch
adds new __is_memcmp_ordered and __is_memcmp_ordered_with traits. These
say whether using memcmp will give the right answer for ordering
operations such as lexicographical_compare and three-way comparisons.
The new traits can be used in several places, and can also be used to
implement my suggestion in PR 93059 comment 37 to use memcmp for
unsigned integers larger than one byte on big endian targets.

libstdc++-v3/ChangeLog:

PR libstdc++/96851
* include/bits/cpp_type_traits.h (__is_memcmp_ordered):
New trait that says if memcmp can be used for ordering.
(__is_memcmp_ordered_with): Likewise, for two types.
* include/bits/deque.tcc (__lex_cmp_dit): Use new traits
instead of __is_byte and __numeric_traits.
(__lexicographical_compare_aux1): Likewise.
* include/bits/ranges_algo.h (__lexicographical_compare_fn):
Likewise.
* include/bits/stl_algobase.h (__lexicographical_compare_aux1)
(__is_byte_iter): Likewise.
* include/std/array (operator<=>): Likewise. Only use memcmp
when std::is_constant_evaluated() is false.
* testsuite/23_containers/array/comparison_operators/96851.cc:
New test.
* testsuite/23_containers/array/tuple_interface/get_neg.cc:
Adjust dg-error line numbers.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-03 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #45 from fdlbxtqi  ---
(In reply to Jonathan Wakely from comment #43)
> (In reply to fdlbxtqi from comment #39)
> > const auto __c = __builtin_memcmp(&*__first1, &*__first2, __len) <=> 0;
> 
> Are you mistakenly reading this as dereferencing &*begin and &*end of an
> iterator range? Because that's not what it does. It dereferences the begin
> iterator of two separate non-empty ranges.
> 
> There is no past-the-end iterator in this statement.

But I still think &* is not a good idea tbh. Better just call
to_address(__first) to avoid potential issues of a contiguous iterator.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-03 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #44 from Jonathan Wakely  ---
(In reply to fdlbxtqi from comment #41)
> And the volatile bugs haven't fixed either.

Maybe you shouldn't use a single bug report for multiple, unrelated problems.

I've reported Bug 94013 for that because it's completely unrelated to this bug.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-03 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #43 from Jonathan Wakely  ---
(In reply to fdlbxtqi from comment #39)
> const auto __c = __builtin_memcmp(&*__first1, &*__first2, __len) <=> 0;

Are you mistakenly reading this as dereferencing &*begin and &*end of an
iterator range? Because that's not what it does. It dereferences the begin
iterator of two separate non-empty ranges.

There is no past-the-end iterator in this statement.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-03 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #42 from Jonathan Wakely  ---
(In reply to fdlbxtqi from comment #39)
> Hi Jonathan. Another bug I found before and you haven't fixed:

Have you reported it?

> https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/
> stl_algobase.h#L1706
> 
> const auto __c = __builtin_memcmp(&*__first1, &*__first2, __len) <=> 0;
> 
> 
> You cannot call &*__first, &*__first2 for contiguous_iterator since a lot of
> implementations of contiguous iterators will check bounds at debugging mode
> (for example MSVC's STL vector implementation). Yours will break code.

How? The iterators are only dereferenced when __len is non-zero.

And how would MSVC's vector be used with libstdc++ algorithms?

Do you have a testcase demonstrating an actual problem?

> __second is not allowed to dereference, that is UB.

What is __second?

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-02 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #41 from fdlbxtqi  ---
(In reply to Jonathan Wakely from comment #38)
> We could also use memcmp for std::equal when it's using std::equal_to<> or
> std::equal_to<_ValueType1> or std::equal_to<_ValueType2>, and for
> std::lexicographical_compare when it's using std::less<> or
> std::less<_ValueType1> or std::less<_ValueType2> (as long as the existing
> conditions are also met).
> 
> Currently we only use memcmp when those algos are used without a comparison
> function.

And the volatile bugs haven't fixed either. The code works fine in GCC 9.0. Now
it failed to work. Even I swap the standard to C++17, it still does not work.
Does deprecate volatile work in this case in C++20?? However, even that is the
case, C++17 should still work.

#include
auto f(std::array arr)
{
decltype(arr) arr2;
std::copy(arr.begin(),arr.end(),arr2.begin());
}

https://godbolt.org/z/Tn87r5

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-02 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #39 from fdlbxtqi  ---
(In reply to Jonathan Wakely from comment #38)
> We could also use memcmp for std::equal when it's using std::equal_to<> or
> std::equal_to<_ValueType1> or std::equal_to<_ValueType2>, and for
> std::lexicographical_compare when it's using std::less<> or
> std::less<_ValueType1> or std::less<_ValueType2> (as long as the existing
> conditions are also met).
> 
> Currently we only use memcmp when those algos are used without a comparison
> function.

Hi Jonathan. Another bug I found before and you haven't fixed:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_algobase.h#L1706

const auto __c = __builtin_memcmp(&*__first1, &*__first2, __len) <=> 0;


You cannot call &*__first, &*__first2 for contiguous_iterator since a lot of
implementations of contiguous iterators will check bounds at debugging mode
(for example MSVC's STL vector implementation). Yours will break code. __second
is not allowed to dereference, that is UB.

Instead, you should call to_address(__first),to_address(__second)

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-02 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #40 from fdlbxtqi  ---
to_address(__first),to_address(__second)

to_address(__first1),to_address(__first2)

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-02 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #38 from Jonathan Wakely  ---
We could also use memcmp for std::equal when it's using std::equal_to<> or
std::equal_to<_ValueType1> or std::equal_to<_ValueType2>, and for
std::lexicographical_compare when it's using std::less<> or
std::less<_ValueType1> or std::less<_ValueType2> (as long as the existing
conditions are also met).

Currently we only use memcmp when those algos are used without a comparison
function.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-03-02 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #37 from Jonathan Wakely  ---
Similarly, the condition for using memcmp in std::equal is too strict:

  typedef typename iterator_traits<_II1>::value_type _ValueType1;
  typedef typename iterator_traits<_II2>::value_type _ValueType2;
  const bool __simple = ((__is_integer<_ValueType1>::__value
  || __is_pointer<_ValueType1>::__value)
 && __is_pointer<_II1>::__value
 && __is_pointer<_II2>::__value
 && __are_same<_ValueType1, _ValueType2>::__value);

If the types are integers of the same size and same signedness then we can use
memcmp, they don't have to be exactly the same type.

And for lexicographical_compare we have:

  typedef typename iterator_traits<_II1>::value_type _ValueType1;
  typedef typename iterator_traits<_II2>::value_type _ValueType2;
  const bool __simple =
(__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value
 && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed
 && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed
 && __is_pointer<_II1>::__value
 && __is_pointer<_II2>::__value);

On big endian targets we could also use memcmp for unsigned integer types
larger than one byte.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-02-26 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

Jonathan Wakely  changed:

   What|Removed |Added

 Target|gcc 10.0|
   Target Milestone|--- |11.0

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-02-26 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

Jonathan Wakely  changed:

   What|Removed |Added

   Keywords||missed-optimization
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2020-02-26
 Ever confirmed|0   |1

--- Comment #36 from Jonathan Wakely  ---
Patches should be sent to the mailing list, and a copyright assignment (or
public domain disclaimer) would be needed for a patch of this size. Otherwise,
leave it to me to do once we start the GCC 11 dev phase.

Adding checks for types satisfying contiguous_iterator looks worthwhile, but
should be a separate patch.

I think the condition for using memmove should be something like:

  __are_same<_ValueTypeI, _ValueTypeO>::__value
  || (__is_integer<_ValueTypeI>::__value
  && __is_integer<_ValueTypeo>::__value
  && sizeof(_ValueTypeI) == sizeof(_ValueTypeO))

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2020-02-26 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #35 from Jonathan Wakely  ---
(In reply to Bernd Edlinger from comment #26)
> (In reply to fdlbxtqi from comment #2)
> > Also find a bug of __memmove
> > 
> >   /*
> >* A constexpr wrapper for __builtin_memmove.
> >* @param __num The number of elements of type _Tp (not bytes).
> >*/
> >   template
> > _GLIBCXX14_CONSTEXPR
> > inline void*
> > __memmove(_Tp* __dst, const _Tp* __src, size_t __num)
> > {
> > #ifdef __cpp_lib_is_constant_evaluated
> >   if (std::is_constant_evaluated())
> > {
> >   for(; __num > 0; --__num)
> > {
> >   if constexpr (_IsMove)
> > *__dst = std::move(*__src);
> >   else
> > *__dst = *__src;
> >   ++__src;
> >   ++__dst;
> > }
> >   return __dst;
> > }
> >   else
> > #endif
> > return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
> >   return __dst;
> > }
> > 
> > The last 2nd line return __dst is wrong. It should not exist.
> 
> Sorry, I don't know what this function is all about.
> But to me the code in the ifdef looks totally bogus.
> First it returns __dst+__num, while memmove is sopposed
> to return __dst, and is is somehow clear that
> __dst and __src do not overlap?

Yes, it was only used by std::copy and std::move and they require that __dst is
not in the range [__src, __src+__num). It's allowed for __dst+__num to be in
that range, but the function works correctly in that case anyway.

The return value wasn't used.

But I've removed the entire function, so it doesn't matter now.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #34 from Bernd Edlinger  ---
(In reply to fdlbxtqi from comment #33)
> Created attachment 47574 [details]
> copy_backward bug fixed for the last patch
> 
> going to further run testsuite

Your test does not contain any test cases.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

fdlbxtqi  changed:

   What|Removed |Added

  Attachment #47559|0   |1
is obsolete||
  Attachment #47560|0   |1
is obsolete||
  Attachment #47570|0   |1
is obsolete||
  Attachment #47571|0   |1
is obsolete||

--- Comment #33 from fdlbxtqi  ---
Created attachment 47574
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47574&action=edit
copy_backward bug fixed for the last patch

going to further run testsuite

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #32 from fdlbxtqi  ---
(In reply to Bernd Edlinger from comment #31)
> Yes, you usually need to make a full bootstrap / make check twice
> which the same svn revision one with and one without your patch.
> You also should make sure that the test case actually is able to fail
> before your patch.
> You run "$(srcdir)/contrib/test_summary -t" each time and
> compare the output.

I am going to bootstrap a new GCC version on my friend's new machine installed
with CentOS

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #31 from Bernd Edlinger  ---
Yes, you usually need to make a full bootstrap / make check twice
which the same svn revision one with and one without your patch.
You also should make sure that the test case actually is able to fail
before your patch.
You run "$(srcdir)/contrib/test_summary -t" each time and
compare the output.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #30 from fdlbxtqi  ---
Created attachment 47571
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47571&action=edit
Here is my stl_algobase.h after patch. You can try it directly.

Here is my stl_algobase.h after patch. You can try it directly.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #29 from fdlbxtqi  ---
(In reply to Marc Glisse from comment #17)
> (In reply to fdlbxtqi from comment #15)
> > What I am worried about is that whether revamping these functions would be 
> > a new wave of ABI breaking.
> 
> I don't foresee any ABI issue here. Do make sure your code doesn't break
> with -std=c++03, and run the testsuite before submitting it.

I think the test suite has passed. However, I am not sure since I have never
used dejagnu before.

It looks like these test suites will fail in some cases even without my patch.
(filesystem, network ts for example)

I need you to check them.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-30 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #28 from fdlbxtqi  ---
Created attachment 47570
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47570&action=edit
Testsuite

Testsuite :

cqwrteur@DESKTOP-7H7UHQ9:~/libstdcpp_testsuite$ runtest --tool libstdc++
Using ../gcc/libstdc++-v3/testsuite/lib/libstdc++.exp as tool init file.
Test run by cqwrteur on Mon Dec 30 05:14:00 2019

Schedule of variations:
unix

Running target unix
Running ../gcc/libstdc++-v3/testsuite/libstdc++-xmethods/xmethods.exp ..   
 .

=== libstdc++ Summary ===

# of expected passes12982
# of unexpected failures6
# of expected failures  92
# of unsupported tests  614


After patch:



cqwrteur@DESKTOP-7H7UHQ9:~/libstdcpp_testsuite$ runtest --tool libstdc++
--srcdir=../gcc/libstdc++-v3/testsuite
Using ../gcc/libstdc++-v3/testsuite/lib/libstdc++.exp as tool init file.
Test run by cqwrteur on Mon Dec 30 09:58:12 2019
Native configuration is x86_64-pc-linux-gnu

=== libstdc++ tests ===

Schedule of variations:
unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for
target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../gcc/libstdc++-v3/testsuite/config/default.exp as
tool-and-target-specific interface file.
Running ../gcc/libstdc++-v3/testsuite/libstdc++-abi/abi.exp ...
Running ../gcc/libstdc++-v3/testsuite/libstdc++-dg/conformance.exp ...
FAIL: 18_support/set_terminate.cc execution test
FAIL: 18_support/set_unexpected.cc execution test
FAIL: 20_util/bind/ref_neg.cc (test for excess errors)
FAIL: 27_io/filesystem/path/concat/92853.cc execution test
FAIL: 27_io/filesystem/path/concat/path.cc execution test
FAIL: experimental/net/internet/resolver/ops/lookup.cc execution test
Running
../gcc/libstdc++-v3/testsuite/libstdc++-prettyprinters/prettyprinters.exp ...
Running ../gcc/libstdc++-v3/testsuite/libstdc++-xmethods/xmethods.exp ...

=== libstdc++ Summary ===

# of expected passes12982
# of unexpected failures6
# of expected failures  92
# of unsupported tests  614
cqwrteur@DESKTOP-7H7UHQ9:~/libstdcpp_testsuite$

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #27 from fdlbxtqi  ---
(In reply to Bernd Edlinger from comment #26)
> (In reply to fdlbxtqi from comment #2)
> > Also find a bug of __memmove
> > 
> >   /*
> >* A constexpr wrapper for __builtin_memmove.
> >* @param __num The number of elements of type _Tp (not bytes).
> >*/
> >   template
> > _GLIBCXX14_CONSTEXPR
> > inline void*
> > __memmove(_Tp* __dst, const _Tp* __src, size_t __num)
> > {
> > #ifdef __cpp_lib_is_constant_evaluated
> >   if (std::is_constant_evaluated())
> > {
> >   for(; __num > 0; --__num)
> > {
> >   if constexpr (_IsMove)
> > *__dst = std::move(*__src);
> >   else
> > *__dst = *__src;
> >   ++__src;
> >   ++__dst;
> > }
> >   return __dst;
> > }
> >   else
> > #endif
> > return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
> >   return __dst;
> > }
> > 
> > The last 2nd line return __dst is wrong. It should not exist.
> 
> Sorry, I don't know what this function is all about.
> But to me the code in the ifdef looks totally bogus.
> First it returns __dst+__num, while memmove is sopposed
> to return __dst, and is is somehow clear that
> __dst and __src do not overlap?
> 
> because if they do the loop would overwite the __dst buffer before
> __src is fully copied?

Nope. It is C++20's new feature if(std::is_constant_evaluated()) which allows
you to write functions can be used both in compile and runtime.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

Bernd Edlinger  changed:

   What|Removed |Added

 CC||bernd.edlinger at hotmail dot 
de

--- Comment #26 from Bernd Edlinger  ---
(In reply to fdlbxtqi from comment #2)
> Also find a bug of __memmove
> 
>   /*
>* A constexpr wrapper for __builtin_memmove.
>* @param __num The number of elements of type _Tp (not bytes).
>*/
>   template
> _GLIBCXX14_CONSTEXPR
> inline void*
> __memmove(_Tp* __dst, const _Tp* __src, size_t __num)
> {
> #ifdef __cpp_lib_is_constant_evaluated
>   if (std::is_constant_evaluated())
>   {
> for(; __num > 0; --__num)
>   {
> if constexpr (_IsMove)
>   *__dst = std::move(*__src);
> else
>   *__dst = *__src;
> ++__src;
> ++__dst;
>   }
> return __dst;
>   }
>   else
> #endif
>   return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>   return __dst;
> }
> 
> The last 2nd line return __dst is wrong. It should not exist.

Sorry, I don't know what this function is all about.
But to me the code in the ifdef looks totally bogus.
First it returns __dst+__num, while memmove is sopposed
to return __dst, and is is somehow clear that
__dst and __src do not overlap?

because if they do the loop would overwite the __dst buffer before
__src is fully copied?

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #25 from fdlbxtqi  ---
Created attachment 47560
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47560&action=edit
forgot to_address

2nd patch

I am going to run testsuites

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #24 from fdlbxtqi  ---
Comment on attachment 47559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47559
An untested patch

>From 1dfd714e1f29e229d69a0c7f6f84bf05dd4ee85d Mon Sep 17 00:00:00 2001
>From: expnkx 
>Date: Sun, 29 Dec 2019 09:49:19 -0500
>Subject: [PATCH] Untested patch fix volatile bug of std::copyXXX and
> std::uninitialized_copyXXX Support custom contiguous_iterator Fix undefined
> behavior of &*end constexpr std::fill Greatly improve performance of
> std::copyXXX and std::uninitialized_copyXX for different types and apply
> pipeline optimization to reduce branch misprediction
>
>---
> libstdc++-v3/include/bits/stl_algobase.h | 170 ---
> 1 file changed, 148 insertions(+), 22 deletions(-)
>
>diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
>b/libstdc++-v3/include/bits/stl_algobase.h
>index 40d056ae8d5..01672a8f232 100644
>--- a/libstdc++-v3/include/bits/stl_algobase.h
>+++ b/libstdc++-v3/include/bits/stl_algobase.h
>@@ -1,6 +1,6 @@
> // Core algorithmic facilities -*- C++ -*-
> 
>-// Copyright (C) 2001-2019 Free Software Foundation, Inc.
>+// Copyright (C) 2001-2020 Free Software Foundation, Inc.
> //
> // This file is part of the GNU ISO C++ Library.  This library is free
> // software; you can redistribute it and/or modify it under the
>@@ -84,10 +84,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>* A constexpr wrapper for __builtin_memmove.
>* @param __num The number of elements of type _Tp (not bytes).
>*/
>+#ifndef __cpp_lib_concepts
>   template
>+  _GLIBCXX14_CONSTEXPR
>+inline void volatile*
>+__memmove(_Tp volatile* __dst, _Tp volatile const* __src, size_t __num)
>+{
>+for(; __num > 0; --__num)
>+  {
>+#if __cplusplus >= 201103L
>+if constexpr (_IsMove)
>+  *__dst = std::move(*__src);
>+else
>+#endif
>+  *__dst = *__src;
>+++__src;
>+++__dst;
>+  }
>+return __dst;
>+}
>+#endif
>+  template
>+/*
>+#ifdef __cpp_lib_concepts
>+requires (is_trivially_copyable_v<_Tp>&&!is_volatile_v<_Tp>
>+  &&is_trivially_copyable_v<_Tp_src>&&!is_volatile_v<_Tp_src>
>+  
>&&(same_as<_Tp,_Tp_src>||(sizeof(_Tp)==sizeof(_Tp_src)&&integral<_Tp>&&integral<_Tp_src>)))
>+#endif
>+*/
> _GLIBCXX14_CONSTEXPR
> inline void*
>-__memmove(_Tp* __dst, const _Tp* __src, size_t __num)
>+__memmove(_Tp* __dst, _Tp_src const* __src, size_t __num)
> {
> #ifdef __cpp_lib_is_constant_evaluated
>   if (std::is_constant_evaluated())
>@@ -106,9 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   else
> #endif
>   return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>-  return __dst;
> }
>-
>   /*
>* A constexpr wrapper for __builtin_memcmp.
>* @param __num The number of elements of type _Tp (not bytes).
>@@ -431,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   }
> };
> #endif
>-
>+#ifndef __cpp_lib_concepts
>   template
> struct __copy_move<_IsMove, true, random_access_iterator_tag>
> {
>@@ -448,12 +473,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> static_assert( __assignable::type::value, "type is not assignable" );
> #endif
> const ptrdiff_t _Num = __last - __first;
>-if (_Num)
>-  std::__memmove<_IsMove>(__result, __first, _Num);
>+if (!_Num)
>+return __result + _Num;
>+//since before C++20, we do not have [[likely]] attribute. We need to do it 
>manually
>+std::__memmove<_IsMove>(__result, __first, _Num);
> return __result + _Num;
>   }
> };
>-
>+#endif
>   // Helpers for streambuf iterators (either istream or ostream).
>   // NB: avoid including , relatively large.
>   template
>@@ -491,11 +518,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   typedef typename iterator_traits<_II>::value_type _ValueTypeI;
>   typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
>   typedef typename iterator_traits<_II>::iterator_category _Category;
>+#ifdef __cpp_lib_concepts
>+  if constexpr(
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeI>)&&
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeO>)&&
>+  contiguous_iterator<_II>&&
>+  contiguous_iterator<_OI>&&
>+  (same_as<_ValueTypeI,_ValueTypeO>
>+  ||(integral<_ValueTypeI>&&integral<_ValueTypeO>&&
>+  sizeof(_ValueTypeI)==sizeof(_ValueTypeO
>+  {
>+using __assignable = conditional<_IsMove,
>+ is_move_assignable<_OI>,
>+is_copy_assignable<_OI>>;
>+static_assert( __assignable::type::value, "result type is not 
>assignable" );
>+ptrdiff_t const _Num = __last - __first;
>+if (_Num)
>+#ifdef __has_cpp_attribute(likely)
>+//This if statement is by default bad since it affects CPU pipeline.
>+//needs likely attribute or the branch misprediction pen

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #20 from fdlbxtqi  ---
Comment on attachment 47559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47559
An untested patch

>From 1dfd714e1f29e229d69a0c7f6f84bf05dd4ee85d Mon Sep 17 00:00:00 2001
>From: expnkx 
>Date: Sun, 29 Dec 2019 09:49:19 -0500
>Subject: [PATCH] Untested patch fix volatile bug of std::copyXXX and
> std::uninitialized_copyXXX Support custom contiguous_iterator Fix undefined
> behavior of &*end constexpr std::fill Greatly improve performance of
> std::copyXXX and std::uninitialized_copyXX for different types and apply
> pipeline optimization to reduce branch misprediction
>
>---
> libstdc++-v3/include/bits/stl_algobase.h | 170 ---
> 1 file changed, 148 insertions(+), 22 deletions(-)
>
>diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
>b/libstdc++-v3/include/bits/stl_algobase.h
>index 40d056ae8d5..01672a8f232 100644
>--- a/libstdc++-v3/include/bits/stl_algobase.h
>+++ b/libstdc++-v3/include/bits/stl_algobase.h
>@@ -1,6 +1,6 @@
> // Core algorithmic facilities -*- C++ -*-
> 
>-// Copyright (C) 2001-2019 Free Software Foundation, Inc.
>+// Copyright (C) 2001-2020 Free Software Foundation, Inc.
> //
> // This file is part of the GNU ISO C++ Library.  This library is free
> // software; you can redistribute it and/or modify it under the
>@@ -84,10 +84,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>* A constexpr wrapper for __builtin_memmove.
>* @param __num The number of elements of type _Tp (not bytes).
>*/
>+#ifndef __cpp_lib_concepts
>   template
>+  _GLIBCXX14_CONSTEXPR
>+inline void volatile*
>+__memmove(_Tp volatile* __dst, _Tp volatile const* __src, size_t __num)
>+{
>+for(; __num > 0; --__num)
>+  {
>+#if __cplusplus >= 201103L
>+if constexpr (_IsMove)
>+  *__dst = std::move(*__src);
>+else
>+#endif
>+  *__dst = *__src;
>+++__src;
>+++__dst;
>+  }
>+return __dst;
>+}
>+#endif
>+  template
>+/*
>+#ifdef __cpp_lib_concepts
>+requires (is_trivially_copyable_v<_Tp>&&!is_volatile_v<_Tp>
>+  &&is_trivially_copyable_v<_Tp_src>&&!is_volatile_v<_Tp_src>
>+  
>&&(same_as<_Tp,_Tp_src>||(sizeof(_Tp)==sizeof(_Tp_src)&&integral<_Tp>&&integral<_Tp_src>)))
>+#endif
>+*/
> _GLIBCXX14_CONSTEXPR
> inline void*
>-__memmove(_Tp* __dst, const _Tp* __src, size_t __num)
>+__memmove(_Tp* __dst, _Tp_src const* __src, size_t __num)
> {
> #ifdef __cpp_lib_is_constant_evaluated
>   if (std::is_constant_evaluated())
>@@ -106,9 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   else
> #endif
>   return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>-  return __dst;
> }
>-
>   /*
>* A constexpr wrapper for __builtin_memcmp.
>* @param __num The number of elements of type _Tp (not bytes).
>@@ -431,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   }
> };
> #endif
>-
>+#ifndef __cpp_lib_concepts
>   template
> struct __copy_move<_IsMove, true, random_access_iterator_tag>
> {
>@@ -448,12 +473,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> static_assert( __assignable::type::value, "type is not assignable" );
> #endif
> const ptrdiff_t _Num = __last - __first;
>-if (_Num)
>-  std::__memmove<_IsMove>(__result, __first, _Num);
>+if (!_Num)
>+return __result + _Num;
>+//since before C++20, we do not have [[likely]] attribute. We need to do it 
>manually
>+std::__memmove<_IsMove>(__result, __first, _Num);
> return __result + _Num;
>   }
> };
>-
>+#endif
>   // Helpers for streambuf iterators (either istream or ostream).
>   // NB: avoid including , relatively large.
>   template
>@@ -491,11 +518,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   typedef typename iterator_traits<_II>::value_type _ValueTypeI;
>   typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
>   typedef typename iterator_traits<_II>::iterator_category _Category;
>+#ifdef __cpp_lib_concepts
>+  if constexpr(
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeI>)&&
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeO>)&&
>+  contiguous_iterator<_II>&&
>+  contiguous_iterator<_OI>&&
>+  (same_as<_ValueTypeI,_ValueTypeO>
>+  ||(integral<_ValueTypeI>&&integral<_ValueTypeO>&&
>+  sizeof(_ValueTypeI)==sizeof(_ValueTypeO
>+  {
>+using __assignable = conditional<_IsMove,
>+ is_move_assignable<_OI>,
>+is_copy_assignable<_OI>>;
>+static_assert( __assignable::type::value, "result type is not 
>assignable" );
>+ptrdiff_t const _Num = __last - __first;
>+if (_Num)
>+#ifdef __has_cpp_attribute(likely)
>+//This if statement is by default bad since it affects CPU pipeline.
>+//needs likely attribute or the branch misprediction pen

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #23 from fdlbxtqi  ---
Comment on attachment 47559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47559
An untested patch

>From 1dfd714e1f29e229d69a0c7f6f84bf05dd4ee85d Mon Sep 17 00:00:00 2001
>From: expnkx 
>Date: Sun, 29 Dec 2019 09:49:19 -0500
>Subject: [PATCH] Untested patch fix volatile bug of std::copyXXX and
> std::uninitialized_copyXXX Support custom contiguous_iterator Fix undefined
> behavior of &*end constexpr std::fill Greatly improve performance of
> std::copyXXX and std::uninitialized_copyXX for different types and apply
> pipeline optimization to reduce branch misprediction
>
>---
> libstdc++-v3/include/bits/stl_algobase.h | 170 ---
> 1 file changed, 148 insertions(+), 22 deletions(-)
>
>diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
>b/libstdc++-v3/include/bits/stl_algobase.h
>index 40d056ae8d5..01672a8f232 100644
>--- a/libstdc++-v3/include/bits/stl_algobase.h
>+++ b/libstdc++-v3/include/bits/stl_algobase.h
>@@ -1,6 +1,6 @@
> // Core algorithmic facilities -*- C++ -*-
> 
>-// Copyright (C) 2001-2019 Free Software Foundation, Inc.
>+// Copyright (C) 2001-2020 Free Software Foundation, Inc.
> //
> // This file is part of the GNU ISO C++ Library.  This library is free
> // software; you can redistribute it and/or modify it under the
>@@ -84,10 +84,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>* A constexpr wrapper for __builtin_memmove.
>* @param __num The number of elements of type _Tp (not bytes).
>*/
>+#ifndef __cpp_lib_concepts
>   template
>+  _GLIBCXX14_CONSTEXPR
>+inline void volatile*
>+__memmove(_Tp volatile* __dst, _Tp volatile const* __src, size_t __num)
>+{
>+for(; __num > 0; --__num)
>+  {
>+#if __cplusplus >= 201103L
>+if constexpr (_IsMove)
>+  *__dst = std::move(*__src);
>+else
>+#endif
>+  *__dst = *__src;
>+++__src;
>+++__dst;
>+  }
>+return __dst;
>+}
>+#endif
>+  template
>+/*
>+#ifdef __cpp_lib_concepts
>+requires (is_trivially_copyable_v<_Tp>&&!is_volatile_v<_Tp>
>+  &&is_trivially_copyable_v<_Tp_src>&&!is_volatile_v<_Tp_src>
>+  
>&&(same_as<_Tp,_Tp_src>||(sizeof(_Tp)==sizeof(_Tp_src)&&integral<_Tp>&&integral<_Tp_src>)))
>+#endif
>+*/
> _GLIBCXX14_CONSTEXPR
> inline void*
>-__memmove(_Tp* __dst, const _Tp* __src, size_t __num)
>+__memmove(_Tp* __dst, _Tp_src const* __src, size_t __num)
> {
> #ifdef __cpp_lib_is_constant_evaluated
>   if (std::is_constant_evaluated())
>@@ -106,9 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   else
> #endif
>   return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>-  return __dst;
> }
>-
>   /*
>* A constexpr wrapper for __builtin_memcmp.
>* @param __num The number of elements of type _Tp (not bytes).
>@@ -431,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   }
> };
> #endif
>-
>+#ifndef __cpp_lib_concepts
>   template
> struct __copy_move<_IsMove, true, random_access_iterator_tag>
> {
>@@ -448,12 +473,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> static_assert( __assignable::type::value, "type is not assignable" );
> #endif
> const ptrdiff_t _Num = __last - __first;
>-if (_Num)
>-  std::__memmove<_IsMove>(__result, __first, _Num);
>+if (!_Num)
>+return __result + _Num;
>+//since before C++20, we do not have [[likely]] attribute. We need to do it 
>manually
>+std::__memmove<_IsMove>(__result, __first, _Num);
> return __result + _Num;
>   }
> };
>-
>+#endif
>   // Helpers for streambuf iterators (either istream or ostream).
>   // NB: avoid including , relatively large.
>   template
>@@ -491,11 +518,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   typedef typename iterator_traits<_II>::value_type _ValueTypeI;
>   typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
>   typedef typename iterator_traits<_II>::iterator_category _Category;
>+#ifdef __cpp_lib_concepts
>+  if constexpr(
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeI>)&&
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeO>)&&
>+  contiguous_iterator<_II>&&
>+  contiguous_iterator<_OI>&&
>+  (same_as<_ValueTypeI,_ValueTypeO>
>+  ||(integral<_ValueTypeI>&&integral<_ValueTypeO>&&
>+  sizeof(_ValueTypeI)==sizeof(_ValueTypeO
>+  {
>+using __assignable = conditional<_IsMove,
>+ is_move_assignable<_OI>,
>+is_copy_assignable<_OI>>;
>+static_assert( __assignable::type::value, "result type is not 
>assignable" );
>+ptrdiff_t const _Num = __last - __first;
>+if (_Num)
>+#ifdef __has_cpp_attribute(likely)
>+//This if statement is by default bad since it affects CPU pipeline.
>+//needs likely attribute or the branch misprediction pen

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #22 from fdlbxtqi  ---
Comment on attachment 47559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47559
An untested patch

>From 1dfd714e1f29e229d69a0c7f6f84bf05dd4ee85d Mon Sep 17 00:00:00 2001
>From: expnkx 
>Date: Sun, 29 Dec 2019 09:49:19 -0500
>Subject: [PATCH] Untested patch fix volatile bug of std::copyXXX and
> std::uninitialized_copyXXX Support custom contiguous_iterator Fix undefined
> behavior of &*end constexpr std::fill Greatly improve performance of
> std::copyXXX and std::uninitialized_copyXX for different types and apply
> pipeline optimization to reduce branch misprediction
>
>---
> libstdc++-v3/include/bits/stl_algobase.h | 170 ---
> 1 file changed, 148 insertions(+), 22 deletions(-)
>
>diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
>b/libstdc++-v3/include/bits/stl_algobase.h
>index 40d056ae8d5..01672a8f232 100644
>--- a/libstdc++-v3/include/bits/stl_algobase.h
>+++ b/libstdc++-v3/include/bits/stl_algobase.h
>@@ -1,6 +1,6 @@
> // Core algorithmic facilities -*- C++ -*-
> 
>-// Copyright (C) 2001-2019 Free Software Foundation, Inc.
>+// Copyright (C) 2001-2020 Free Software Foundation, Inc.
> //
> // This file is part of the GNU ISO C++ Library.  This library is free
> // software; you can redistribute it and/or modify it under the
>@@ -84,10 +84,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>* A constexpr wrapper for __builtin_memmove.
>* @param __num The number of elements of type _Tp (not bytes).
>*/
>+#ifndef __cpp_lib_concepts
>   template
>+  _GLIBCXX14_CONSTEXPR
>+inline void volatile*
>+__memmove(_Tp volatile* __dst, _Tp volatile const* __src, size_t __num)
>+{
>+for(; __num > 0; --__num)
>+  {
>+#if __cplusplus >= 201103L
>+if constexpr (_IsMove)
>+  *__dst = std::move(*__src);
>+else
>+#endif
>+  *__dst = *__src;
>+++__src;
>+++__dst;
>+  }
>+return __dst;
>+}
>+#endif
>+  template
>+/*
>+#ifdef __cpp_lib_concepts
>+requires (is_trivially_copyable_v<_Tp>&&!is_volatile_v<_Tp>
>+  &&is_trivially_copyable_v<_Tp_src>&&!is_volatile_v<_Tp_src>
>+  
>&&(same_as<_Tp,_Tp_src>||(sizeof(_Tp)==sizeof(_Tp_src)&&integral<_Tp>&&integral<_Tp_src>)))
>+#endif
>+*/
> _GLIBCXX14_CONSTEXPR
> inline void*
>-__memmove(_Tp* __dst, const _Tp* __src, size_t __num)
>+__memmove(_Tp* __dst, _Tp_src const* __src, size_t __num)
> {
> #ifdef __cpp_lib_is_constant_evaluated
>   if (std::is_constant_evaluated())
>@@ -106,9 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   else
> #endif
>   return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>-  return __dst;
> }
>-
>   /*
>* A constexpr wrapper for __builtin_memcmp.
>* @param __num The number of elements of type _Tp (not bytes).
>@@ -431,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   }
> };
> #endif
>-
>+#ifndef __cpp_lib_concepts
>   template
> struct __copy_move<_IsMove, true, random_access_iterator_tag>
> {
>@@ -448,12 +473,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> static_assert( __assignable::type::value, "type is not assignable" );
> #endif
> const ptrdiff_t _Num = __last - __first;
>-if (_Num)
>-  std::__memmove<_IsMove>(__result, __first, _Num);
>+if (!_Num)
>+return __result + _Num;
>+//since before C++20, we do not have [[likely]] attribute. We need to do it 
>manually
>+std::__memmove<_IsMove>(__result, __first, _Num);
> return __result + _Num;
>   }
> };
>-
>+#endif
>   // Helpers for streambuf iterators (either istream or ostream).
>   // NB: avoid including , relatively large.
>   template
>@@ -491,11 +518,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   typedef typename iterator_traits<_II>::value_type _ValueTypeI;
>   typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
>   typedef typename iterator_traits<_II>::iterator_category _Category;
>+#ifdef __cpp_lib_concepts
>+  if constexpr(
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeI>)&&
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeO>)&&
>+  contiguous_iterator<_II>&&
>+  contiguous_iterator<_OI>&&
>+  (same_as<_ValueTypeI,_ValueTypeO>
>+  ||(integral<_ValueTypeI>&&integral<_ValueTypeO>&&
>+  sizeof(_ValueTypeI)==sizeof(_ValueTypeO
>+  {
>+using __assignable = conditional<_IsMove,
>+ is_move_assignable<_OI>,
>+is_copy_assignable<_OI>>;
>+static_assert( __assignable::type::value, "result type is not 
>assignable" );
>+ptrdiff_t const _Num = __last - __first;
>+if (_Num)
>+#ifdef __has_cpp_attribute(likely)
>+//This if statement is by default bad since it affects CPU pipeline.
>+//needs likely attribute or the branch misprediction pen

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #21 from fdlbxtqi  ---
Comment on attachment 47559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47559
An untested patch

>From 1dfd714e1f29e229d69a0c7f6f84bf05dd4ee85d Mon Sep 17 00:00:00 2001
>From: expnkx 
>Date: Sun, 29 Dec 2019 09:49:19 -0500
>Subject: [PATCH] Untested patch fix volatile bug of std::copyXXX and
> std::uninitialized_copyXXX Support custom contiguous_iterator Fix undefined
> behavior of &*end constexpr std::fill Greatly improve performance of
> std::copyXXX and std::uninitialized_copyXX for different types and apply
> pipeline optimization to reduce branch misprediction
>
>---
> libstdc++-v3/include/bits/stl_algobase.h | 170 ---
> 1 file changed, 148 insertions(+), 22 deletions(-)
>
>diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
>b/libstdc++-v3/include/bits/stl_algobase.h
>index 40d056ae8d5..01672a8f232 100644
>--- a/libstdc++-v3/include/bits/stl_algobase.h
>+++ b/libstdc++-v3/include/bits/stl_algobase.h
>@@ -1,6 +1,6 @@
> // Core algorithmic facilities -*- C++ -*-
> 
>-// Copyright (C) 2001-2019 Free Software Foundation, Inc.
>+// Copyright (C) 2001-2020 Free Software Foundation, Inc.
> //
> // This file is part of the GNU ISO C++ Library.  This library is free
> // software; you can redistribute it and/or modify it under the
>@@ -84,10 +84,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>* A constexpr wrapper for __builtin_memmove.
>* @param __num The number of elements of type _Tp (not bytes).
>*/
>+#ifndef __cpp_lib_concepts
>   template
>+  _GLIBCXX14_CONSTEXPR
>+inline void volatile*
>+__memmove(_Tp volatile* __dst, _Tp volatile const* __src, size_t __num)
>+{
>+for(; __num > 0; --__num)
>+  {
>+#if __cplusplus >= 201103L
>+if constexpr (_IsMove)
>+  *__dst = std::move(*__src);
>+else
>+#endif
>+  *__dst = *__src;
>+++__src;
>+++__dst;
>+  }
>+return __dst;
>+}
>+#endif
>+  template
>+/*
>+#ifdef __cpp_lib_concepts
>+requires (is_trivially_copyable_v<_Tp>&&!is_volatile_v<_Tp>
>+  &&is_trivially_copyable_v<_Tp_src>&&!is_volatile_v<_Tp_src>
>+  
>&&(same_as<_Tp,_Tp_src>||(sizeof(_Tp)==sizeof(_Tp_src)&&integral<_Tp>&&integral<_Tp_src>)))
>+#endif
>+*/
> _GLIBCXX14_CONSTEXPR
> inline void*
>-__memmove(_Tp* __dst, const _Tp* __src, size_t __num)
>+__memmove(_Tp* __dst, _Tp_src const* __src, size_t __num)
> {
> #ifdef __cpp_lib_is_constant_evaluated
>   if (std::is_constant_evaluated())
>@@ -106,9 +133,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   else
> #endif
>   return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>-  return __dst;
> }
>-
>   /*
>* A constexpr wrapper for __builtin_memcmp.
>* @param __num The number of elements of type _Tp (not bytes).
>@@ -431,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   }
> };
> #endif
>-
>+#ifndef __cpp_lib_concepts
>   template
> struct __copy_move<_IsMove, true, random_access_iterator_tag>
> {
>@@ -448,12 +473,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> static_assert( __assignable::type::value, "type is not assignable" );
> #endif
> const ptrdiff_t _Num = __last - __first;
>-if (_Num)
>-  std::__memmove<_IsMove>(__result, __first, _Num);
>+if (!_Num)
>+return __result + _Num;
>+//since before C++20, we do not have [[likely]] attribute. We need to do it 
>manually
>+std::__memmove<_IsMove>(__result, __first, _Num);
> return __result + _Num;
>   }
> };
>-
>+#endif
>   // Helpers for streambuf iterators (either istream or ostream).
>   // NB: avoid including , relatively large.
>   template
>@@ -491,11 +518,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>   typedef typename iterator_traits<_II>::value_type _ValueTypeI;
>   typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
>   typedef typename iterator_traits<_II>::iterator_category _Category;
>+#ifdef __cpp_lib_concepts
>+  if constexpr(
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeI>)&&
>+  ((!is_volatile_v>)&&
>+  is_trivially_copyable_v<_ValueTypeO>)&&
>+  contiguous_iterator<_II>&&
>+  contiguous_iterator<_OI>&&
>+  (same_as<_ValueTypeI,_ValueTypeO>
>+  ||(integral<_ValueTypeI>&&integral<_ValueTypeO>&&
>+  sizeof(_ValueTypeI)==sizeof(_ValueTypeO
>+  {
>+using __assignable = conditional<_IsMove,
>+ is_move_assignable<_OI>,
>+is_copy_assignable<_OI>>;
>+static_assert( __assignable::type::value, "result type is not 
>assignable" );
>+ptrdiff_t const _Num = __last - __first;
>+if (_Num)
>+#ifdef __has_cpp_attribute(likely)
>+//This if statement is by default bad since it affects CPU pipeline.
>+//needs likely attribute or the branch misprediction pen

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #19 from fdlbxtqi  ---
Created attachment 47559
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47559&action=edit
An untested patch

From 1dfd714e1f29e229d69a0c7f6f84bf05dd4ee85d Mon Sep 17 00:00:00 2001
From: expnkx 
Date: Sun, 29 Dec 2019 09:49:19 -0500
Subject: [PATCH] Untested patch fix volatile bug of std::copyXXX and
 std::uninitialized_copyXXX Support custom contiguous_iterator Fix undefined
 behavior of &*end constexpr std::fill Greatly improve performance of
 std::copyXXX and std::uninitialized_copyXX for different types and apply
 pipeline optimization to reduce branch misprediction

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #18 from fdlbxtqi  ---
(In reply to Marc Glisse from comment #17)
> (In reply to fdlbxtqi from comment #15)
> > What I am worried about is that whether revamping these functions would be 
> > a new wave of ABI breaking.
> 
> I don't foresee any ABI issue here. Do make sure your code doesn't break
> with -std=c++03, and run the testsuite before submitting it.

Also, I have found another bug??? in both libstdc++ and libc++

memmove is not allowed for using volatile. Only MSVC passes the test.

libstdc++&libc++ are wrong.

https://godbolt.org/z/FoTCbk

I will fix this as well.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #17 from Marc Glisse  ---
(In reply to fdlbxtqi from comment #15)
> What I am worried about is that whether revamping these functions would be a 
> new wave of ABI breaking.

I don't foresee any ABI issue here. Do make sure your code doesn't break with
-std=c++03, and run the testsuite before submitting it.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #16 from fdlbxtqi  ---
(In reply to Marc Glisse from comment #13)
> (In reply to fdlbxtqi from comment #11)
> > TBH. I would rather see the library does the optimization instead of the
> > compiler. I do not trust the compiler can always optimize this stuff.
> 
> If we have both, that looks even safer ;-)

Concepts are no doubt a huge deal breaker.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #15 from fdlbxtqi  ---
(In reply to fdlbxtqi from comment #14)
> I think It is worth the effort to rewrite these functions since they are so
> fundamental to the performance of entire C++. What I am worry about is that
> whether revamping these functions would be a new ABI breaking.
> 
> If it won’t, I would like to contribute my implementation.
> 
> Sent from Mail for Windows 10
> 
> From: glisse at gcc dot gnu.org
> Sent: Sunday, December 29, 2019 03:22
> To: euloa...@live.com
> Subject: [Bug libstdc++/93059] char and char8_t does not talk with each
> other with memcpy. std::copy std::copy_n, std::fill, std::fill_n,
> std::uninitialized_copy std::uninitialized_copy_n, std::fill,
> std::uninitialized_fill_n fails to convert to memxxx functions
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059
> 
> --- Comment #13 from Marc Glisse  ---
> (In reply to fdlbxtqi from comment #11)
> > TBH. I would rather see the library does the optimization instead of the
> > compiler. I do not trust the compiler can always optimize this stuff.
> 
> If we have both, that looks even safer ;-)
> 
> --
> You are receiving this mail because:
> You are on the CC list for the bug.
> You reported the bug.

I think It is worth the effort to rewrite these functions since they are so
fundamental to the performance of entire C++. Revamping them would create 100%
of performance benefits in a lot of important benchmarks. What I am worried
about is that whether revamping these functions would be a new wave of ABI
breaking.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #14 from fdlbxtqi  ---
I think It is worth the effort to rewrite these functions since they are so
fundamental to the performance of entire C++. What I am worry about is that
whether revamping these functions would be a new ABI breaking.

If it won’t, I would like to contribute my implementation.

Sent from Mail for Windows 10

From: glisse at gcc dot gnu.org
Sent: Sunday, December 29, 2019 03:22
To: euloa...@live.com
Subject: [Bug libstdc++/93059] char and char8_t does not talk with each other
with memcpy. std::copy std::copy_n, std::fill, std::fill_n,
std::uninitialized_copy std::uninitialized_copy_n, std::fill,
std::uninitialized_fill_n fails to convert to memxxx functions

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

--- Comment #13 from Marc Glisse  ---
(In reply to fdlbxtqi from comment #11)
> TBH. I would rather see the library does the optimization instead of the
> compiler. I do not trust the compiler can always optimize this stuff.

If we have both, that looks even safer ;-)

--
You are receiving this mail because:
You are on the CC list for the bug.
You reported the bug.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-29 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #13 from Marc Glisse  ---
(In reply to fdlbxtqi from comment #11)
> TBH. I would rather see the library does the optimization instead of the
> compiler. I do not trust the compiler can always optimize this stuff.

If we have both, that looks even safer ;-)

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-28 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #12 from fdlbxtqi  ---
(In reply to Marc Glisse from comment #8)
> (In reply to fdlbxtqi from comment #6)
> > void copy_char_vector_with_iter(std::vector::iterator
> > out,std::vector const& bits)
> > {
> > std::copy_n(bits.begin(),bits.size(),out);
> > }
> > 
> > https://godbolt.org/z/_yA_Ls
> > See the assembly
> 
> Thanks, I just filed PR 93063 about a subpart that the compiler should be
> able to do without help from the library.

I think the implementation is still problematic since C++ 20 adds the
contiguous_iterator concept. The current implementation looks not to allow
custom 
 contiguous iterators types to be optimized as memmove.

It needs certain kinds of revamping IMO.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-28 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #11 from fdlbxtqi  ---
(In reply to Marc Glisse from comment #8)
> (In reply to fdlbxtqi from comment #6)
> > void copy_char_vector_with_iter(std::vector::iterator
> > out,std::vector const& bits)
> > {
> > std::copy_n(bits.begin(),bits.size(),out);
> > }
> > 
> > https://godbolt.org/z/_yA_Ls
> > See the assembly
> 
> Thanks, I just filed PR 93063 about a subpart that the compiler should be
> able to do without help from the library.

TBH. I would rather see the library does the optimization instead of the
compiler. I do not trust the compiler can always optimize this stuff.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-24 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #10 from fdlbxtqi  ---
(In reply to fdlbxtqi from comment #9)
> (In reply to Marc Glisse from comment #8)
> > (In reply to fdlbxtqi from comment #6)
> > > void copy_char_vector_with_iter(std::vector::iterator
> > > out,std::vector const& bits)
> > > {
> > >   std::copy_n(bits.begin(),bits.size(),out);
> > > }
> > > 
> > > https://godbolt.org/z/_yA_Ls
> > > See the assembly
> > 
> > Thanks, I just filed PR 93063 about a subpart that the compiler should be
> > able to do without help from the library.
> 
> I have tried the same benchmark on clang. It has the same issue. However,
> GCC's optimization of this would inspire Clang I believe.

and libc++

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-24 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #9 from fdlbxtqi  ---
(In reply to Marc Glisse from comment #8)
> (In reply to fdlbxtqi from comment #6)
> > void copy_char_vector_with_iter(std::vector::iterator
> > out,std::vector const& bits)
> > {
> > std::copy_n(bits.begin(),bits.size(),out);
> > }
> > 
> > https://godbolt.org/z/_yA_Ls
> > See the assembly
> 
> Thanks, I just filed PR 93063 about a subpart that the compiler should be
> able to do without help from the library.

I have tried the same benchmark on clang. It has the same issue. However, GCC's
optimization of this would inspire Clang I believe.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-24 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #8 from Marc Glisse  ---
(In reply to fdlbxtqi from comment #6)
> void copy_char_vector_with_iter(std::vector::iterator
> out,std::vector const& bits)
> {
>   std::copy_n(bits.begin(),bits.size(),out);
> }
> 
> https://godbolt.org/z/_yA_Ls
> See the assembly

Thanks, I just filed PR 93063 about a subpart that the compiler should be able
to do without help from the library.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-24 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #7 from Marc Glisse  ---
(In reply to fdlbxtqi from comment #6)
> > > clearly incorrect
> > 
> > Please distinguish between what is wrong (generated code crashes, or returns
> > 3 instead of 2), and what is suboptimal.
> 
> Suppose #ifdef __cpp_lib_is_constant_evaluated is not defined (for C++17)
> 
> It becomes:
> return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
>   return __dst;
> 
> ?

I should have kept the whole quote:

> 1. libstdc++ does not use memmove for different trivially copyable objects. 
> It only uses it for the same type which is clearly incorrect.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-24 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #6 from fdlbxtqi  ---

> What operation are you doing on vector? None of your testcases seem to use
> it.


void copy_char_vector_with_iter(std::vector::iterator
out,std::vector const& bits)
{
std::copy_n(bits.begin(),bits.size(),out);
}

https://godbolt.org/z/_yA_Ls
See the assembly

> > clearly incorrect
> 
> Please distinguish between what is wrong (generated code crashes, or returns
> 3 instead of 2), and what is suboptimal.

Suppose #ifdef __cpp_lib_is_constant_evaluated is not defined (for C++17)

It becomes:
return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
  return __dst;

?

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-24 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #5 from Marc Glisse  ---
We could indeed relax a bit the "same type" condition. We could also make sure
that __restrict appears somewhere in the call chain when using copy or
uninitialized_*, which lets the compiler merge the 2 loads/stores.

(In reply to fdlbxtqi from comment #2)
> The last 2nd line return __dst is wrong. It should not exist.

Write a patch, test it, and send it to the mailing list?

(In reply to fdlbxtqi from comment #3)
> For vector, the performance lost is even worse. It generates 96 lines of
> assembly for different types since it does not call memmove.

What operation are you doing on vector? None of your testcases seem to use it.

> clearly incorrect

Please distinguish between what is wrong (generated code crashes, or returns 3
instead of 2), and what is suboptimal.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-23 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #4 from fdlbxtqi  ---
A demo fix would be like this i think:

template
inline constexpr output_iter my_copy_n(input_iter first,std::size_t
count,output_iter result)
{
using input_value_type = typename
std::iterator_traits::value_type;
using output_value_type = typename
std::iterator_traits::value_type;
if constexpr
(std::contiguous_iterator&&
std::contiguous_iterator&&
std::is_trivially_copyable_v&&
std::is_trivially_copyable_v&&
   
(std::same_as||(std::integral&&
   
std::integral&&sizeof(std::is_trivially_copyable_v)==sizeof(std::is_trivially_copyable_v
{
if (std::is_constant_evaluated())
{
for(;count--;)
{
*result=*first;
++first;
++result;
}
}
else
__builtin_memmove(std::to_address(result),std::to_address(first),
sizeof(typename
std::iterator_traits::value_type)*count);
return result+count;
}
return std::copy_n(first,count,result);
}

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-23 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #3 from fdlbxtqi  ---
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_algobase.h

I have found out the problem.

1. libstdc++ does not use memmove for different trivially copyable objects. It
only uses it for the same type which is clearly incorrect.

The performance lost is HUGE in my benchmarks for losing at least 50% of
performance in some critical path.

https://godbolt.org/z/ouNiHn

For vector, the performance lost is even worse. It generates 96 lines of
assembly for different types since it does not call memmove.

2. memmove should not be used for different types unless the source and dest
have char*, char const* and std::byte* for trivially copyable types. It should
call memcpy because of the strict-aliasing rule. However, I do not know whether
it is possible to detect the strict-aliasing context for libstdc++ in GCC. It
should add some magic here to make it faster.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-23 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #2 from fdlbxtqi  ---
Also find a bug of __memmove

  /*
   * A constexpr wrapper for __builtin_memmove.
   * @param __num The number of elements of type _Tp (not bytes).
   */
  template
_GLIBCXX14_CONSTEXPR
inline void*
__memmove(_Tp* __dst, const _Tp* __src, size_t __num)
{
#ifdef __cpp_lib_is_constant_evaluated
  if (std::is_constant_evaluated())
{
  for(; __num > 0; --__num)
{
  if constexpr (_IsMove)
*__dst = std::move(*__src);
  else
*__dst = *__src;
  ++__src;
  ++__dst;
}
  return __dst;
}
  else
#endif
return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
  return __dst;
}

The last 2nd line return __dst is wrong. It should not exist.

[Bug libstdc++/93059] char and char8_t does not talk with each other with memcpy. std::copy std::copy_n, std::fill, std::fill_n, std::uninitialized_copy std::uninitialized_copy_n, std::fill, std::unin

2019-12-23 Thread euloanty at live dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #1 from fdlbxtqi  ---
I am going to rewrite these functions by C++20 concepts + if constexpr for
C++20 for you, Jwakely. I do not believe these enable-if/ overloading functions
would not be a problem.