[Bug c++/94082] __builtin_memcpy in constexpr context should compile
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Mar 9 11:28:03 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94082
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(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
> <cstring>
> headers, leading to a decision to use compiler specific intrinsics
> instead
> of functions from <cstring> 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.
More information about the Gcc-bugs
mailing list