[Bug c++/94082] __builtin_memcpy in constexpr context should compile

2021-08-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082

--- Comment #7 from Andrew Pinski  ---
clang produces:
:8:5: note: cannot constant evaluate 'memcpy' from object of type
'unsigned char' to object of type 'std::uint32_t' (aka 'unsigned int')
__builtin_memcpy(&num, data, sizeof(std::uint32_t));
^

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

2020-03-09 Thread D.Bahadir at GMX dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082

--- Comment #6 from Deniz Bahadir  ---
(In reply to Jonathan Wakely from comment #5)
> 
> It definitely doesn't mean __builtin_memcpy has to be used. It means "we
> don't want to change std::memcpy, implementations must use some other method
> to make it work". 
> 
> That could mean using some new intrinsic like __builtin_constant_memcpy, or
> anything else that makes the algorithms work in constant expressions. The
> solution in libstdc++ is based on std::is_constant_evaluted() and ensures
> that memcpy and __builtin_memcpy are never needed in constant expressions
> because we implement those copies by hand when needed during constant
> evaluation.

OK, I see.
Would you then suggest GCC should provide such an intrinsic or would you expect
developers to do copies by hand, too, in `constexpr` context.

> > > It might be useful if it could be used, but the fact it can't currently
> > > isn't a bug.
> > 
> > OK, then consider this issue a feature-request and a question.
> > 
> > As the link to Compiler Explorer shows the compiler is already able to
> > calculate the result of the entire function call at compile-time when called
> > from a non-`constexpr` context.
> 
> For some cases. I don't think it's true for all inputs.

Well, that is unfortunate.

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

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

--- Comment #5 from Jonathan Wakely  ---
(In reply to Deniz Bahadir from comment #4)
> (In reply to Jonathan Wakely from comment #3)
> > (In reply to Deniz Bahadir from comment #1)
> > > Reading P0202 (wg21.link/p0202) (which made it into C++20) it sounds as if
> > > `__builtin_memcpy` should be usable from a `constexpr` context.
> > 
> > Why? std::memcpy isn't usable in constant expressions.
> 
> 
> Revision 0 of P0202 (https://wg21.link/p0202r0) originally had the following
> text in section III.B:
> 
> "B. std::memmove and std::memcpy must have constexpr additions
> 
> std::memmove and std::memcpy accept void* and const void* parameters.
> This makes them impossible to implement in pure C++ as constexpr, because
> constant expressions can not evaluate a conversion from type cv void * to
> a pointer-to-object type according to [expr.const].
> 
> However those functions are not only popular, but also are widely used
> across Standard Library to gain better performance. Not making them
> constexpr will force standard Library developer to have compiler
> intrinsics for them anyway. This is a hard step that must be done."
> 
> That was rejected at the committee meeting in Jacksonville in early 2018 and
> the section was replaced by the following:
> 
> "During the Jacksonville meeting it was decided not to modify the
> 
> headers, leading to a decision to use compiler specific intrinsics
> instead
> of functions from  header."
> 
> To me that sounds as if compiler-intrinsics like `__builtin_memcpy` should
> instead be usable in `constexpr` contexts.

It definitely doesn't mean __builtin_memcpy has to be used. It means "we don't
want to change std::memcpy, implementations must use some other method to make
it work". 

That could mean using some new intrinsic like __builtin_constant_memcpy, or
anything else that makes the algorithms work in constant expressions. The
solution in libstdc++ is based on std::is_constant_evaluted() and ensures that
memcpy and __builtin_memcpy are never needed in constant expressions because we
implement those copies by hand when needed during constant evaluation.


> > It might be useful if it could be used, but the fact it can't currently
> > isn't a bug.
> 
> OK, then consider this issue a feature-request and a question.
> 
> As the link to Compiler Explorer shows the compiler is already able to
> calculate the result of the entire function call at compile-time when called
> from a non-`constexpr` context.

For some cases. I don't think it's true for all inputs.

> Shouldn't it then be able to still do so in a `constexpr` context, too?
> (As I mentioned, e.g. for `__builtin_bswap32` that is possible.)

bswap32 is much simpler than mempcy and can always be expanded by the compiler,
for all inputs.

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

2020-03-09 Thread D.Bahadir at GMX dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082

--- Comment #4 from Deniz Bahadir  ---
(In reply to Jonathan Wakely from comment #3)
> (In reply to Deniz Bahadir from comment #1)
> > Reading P0202 (wg21.link/p0202) (which made it into C++20) it sounds as if
> > `__builtin_memcpy` should be usable from a `constexpr` context.
> 
> Why? std::memcpy isn't usable in constant expressions.


Revision 0 of P0202 (https://wg21.link/p0202r0) originally had the following
text in section III.B:

"B. std::memmove and std::memcpy must have constexpr additions

std::memmove and std::memcpy accept void* and const void* parameters.
This makes them impossible to implement in pure C++ as constexpr, because
constant expressions can not evaluate a conversion from type cv void * to
a pointer-to-object type according to [expr.const].

However those functions are not only popular, but also are widely used
across Standard Library to gain better performance. Not making them
constexpr will force standard Library developer to have compiler
intrinsics for them anyway. This is a hard step that must be done."

That was rejected at the committee meeting in Jacksonville in early 2018 and
the section was replaced by the following:

"During the Jacksonville meeting it was decided not to modify the 
headers, leading to a decision to use compiler specific intrinsics instead
of functions from  header."

To me that sounds as if compiler-intrinsics like `__builtin_memcpy` should
instead be usable in `constexpr` contexts.


> It might be useful if it could be used, but the fact it can't currently
> isn't a bug.

OK, then consider this issue a feature-request and a question.

As the link to Compiler Explorer shows the compiler is already able to
calculate the result of the entire function call at compile-time when called
from a non-`constexpr` context.
Shouldn't it then be able to still do so in a `constexpr` context, too?
(As I mentioned, e.g. for `__builtin_bswap32` that is possible.)

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

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

--- Comment #3 from Jonathan Wakely  ---
(In reply to Deniz Bahadir from comment #1)
> Reading P0202 (wg21.link/p0202) (which made it into C++20) it sounds as if
> `__builtin_memcpy` should be usable from a `constexpr` context.

Why? std::memcpy isn't usable in constant expressions.

It might be useful if it could be used, but the fact it can't currently isn't a
bug.

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

2020-03-08 Thread D.Bahadir at GMX dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082

--- Comment #2 from Deniz Bahadir  ---
Here is a link to Stack Overflow where I originally asked a question about this
behavior: https://stackoverflow.com/q/60572199/3115457

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

2020-03-08 Thread D.Bahadir at GMX dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082

--- Comment #1 from Deniz Bahadir  ---
Not: As due to the sourceware/gcc move it seems my original bug-report comment
got lost, I am here re-posting it.


Reading P0202 (wg21.link/p0202) (which made it into C++20) it sounds as if
`__builtin_memcpy` should be usable from a `constexpr` context. However, it is
not, as the following code demonstrates:

```
#include 
#include 

constexpr std::uint32_t extract(const std::uint8_t* data) noexcept
{
std::uint32_t num;
__builtin_memcpy(&num, data, sizeof(std::uint32_t));
return num;
}

int main()
{
constexpr std::array a1 {{ 0xff, 0xff, 0xff, 0xff }};
constexpr auto val = extract(a1.data());  // <--- Error!
return val;
}
```

Compilation fails with:

```
: In function 'int main()':
:14:33:   in 'constexpr' expansion of 'extract(a1.std::array::data())'
:7:21: error: '__builtin_memcpy(((void*)(& num)), ((const void*)(&
a1.std::array::_M_elems)), 4)' is not a constant expression

7 | __builtin_memcpy(&num, data, sizeof(std::uint32_t));
  | ^~~
```

I would have expected this to compile and `__builtin_memcpy` being optimized
away.

Interestingly, removing the `constexpr` in front of the call to the function
and thereby not calling it from a `constexpr` context compiles just fine and
the optimizer is even able to optimize the call away and replace it by the
returned value (`-1`).

The `constexpr` keyword in front of the function definition seems then to just
be an indicator for inlining, similar to the `inline` keyword. But for this
simple example, the compiler is even able to optimize it without `inline` or
`constexpr` in front of the function definition.


I think a `constexpr` context should not prevent compilation and optimization,
as the optimizer seems to be able to do that.

BTW: Using e.g. `__builtin_bswap32` from a `constexpr` context is compiling and
optimizing just fine.

See Compiler Explorer for a demonstration of the described behavior:
https://godbolt.org/z/HaBt__

[Bug c++/94082] __builtin_memcpy in constexpr context should compile

2020-03-07 Thread fche at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082

Frank Ch. Eigler  changed:

   What|Removed |Added

 CC||fche at redhat dot com

test