This is an archive of the discontinued LLVM Phabricator instance.

Bit-casting object representations (p0476r2)
AbandonedPublic

Authored by zoecarver on Feb 9 2019, 10:09 AM.

Details

Reviewers
mclow.lists
jfb
Summary

Add bit_cast function outlined here.

Diff Detail

Event Timeline

zoecarver created this revision.Feb 9 2019, 10:09 AM
zoecarver added inline comments.Feb 9 2019, 10:11 AM
include/bit
168

It would be great if this could use the llvm BitCastInst but I am not sure how to add support for this in the compiler. Maybe you know @mclow.lists?

zoecarver updated this revision to Diff 186125.Feb 9 2019, 10:23 AM

Update version, status, and ensure that libcxx std version is over 17.

jfb requested changes to this revision.Feb 9 2019, 11:31 AM
jfb added a subscriber: erik.pilkington.

You need support from the compiler for constexpr support. I don't think we want this without constexpr. @erik.pilkington was looking into this.

This revision now requires changes to proceed.Feb 9 2019, 11:31 AM

I talked with @lebedev.ri a bit about this on the IRC channel. @jfb do you know if the bitcast instruction would work for constexpr without type punning? It seems like memcpy (and __builtin_memcpy ) is not the way to go.

Here is another idea, what if we treated fundamental types differently because they can be cast using c-style casting? Like this:

    std::is_fundamental<_To>::value &&
    std::is_fundamental<_Fm>::value,
    _To
>::type
bit_cast(const _Fm &__src) noexcept
{
    return (_To) __src;
}
jfb added a comment.Feb 9 2019, 11:53 AM

Here is another idea, what if we treated fundamental types differently because they can be cast using c-style casting? Like this:

    std::is_fundamental<_To>::value &&
    std::is_fundamental<_Fm>::value,
    _To
>::type
bit_cast(const _Fm &__src) noexcept
{
    return (_To) __src;
}

I don't think you'll need any of this once we have a builtin.

For sure, but would it work instead of a builtin?

Is there some documentation on adding builtins to clang? I am happy to work on writing one I just don't know where to start.

jfb added a comment.Feb 9 2019, 11:59 AM

For sure, but would it work instead of a builtin?

No, because it wouldn't support everything the standard says. Things like float -> int are also wrong with what you suggest.

Is there some documentation on adding builtins to clang? I am happy to work on writing one I just don't know where to start.

You can look at prior builtins that were added, that's usually the easiest route. In this case I'd wait to see what Erik had, maybe he can upload his partial patch.

No, because it wouldn't support everything the standard says. Things like float -> int are also wrong with what you suggest.

Fair enough. Out of curiosity though, what is wrong with float -> int?

You can look at prior builtins that were added, that's usually the easiest route. In this case I'd wait to see what Erik had, maybe he can upload his partial patch.

Sounds good. I will look over some code and wait for him.

jfb added a comment.Feb 9 2019, 12:14 PM

No, because it wouldn't support everything the standard says. Things like float -> int are also wrong with what you suggest.

Fair enough. Out of curiosity though, what is wrong with float -> int?

It's not doing the same thing: https://godbolt.org/z/FREjFX

I see. It's doing something like fptosi instead of a bitcast. Thanks for the link, very helpful.

@erik.pilkington friendly ping, have you made any progress on compiler support?

A more general question: bit_cast is only available in C++20 which supports the memcpy function as a constexpr, does that resolve the issue or would there be other benefits form compiler support (no type punning, etc.)?

@erik.pilkington friendly ping, have you made any progress on compiler support?

I'm planning on implementing this, but haven't quite gotten around to it yet. The idea is a builtin spelt __builtin_bit_cast(T, expr), that would just IRGen to a simple memcpy. In the frontend's constant evaluator (lib/AST/ExprConstant.cpp), we need to map from an APValue of one type to an APValue of another, which can get a little hairy (especially since we want to evaluate it however the target would). If you're interested in taking a look at this I can give you a more detailed brain dump and dig up some WIP patches.

A more general question: bit_cast is only available in C++20 which supports the memcpy function as a constexpr, does that resolve the issue or would there be other benefits form compiler support (no type punning, etc.)?

constexpr memcpy doesn't do type-punning, so compiler support is still needed in general.

@erik.pilkington thanks for the explanation. I will take a look at those files and see if I can understand better what needs to be done. If it seems doable (for me) I will ask about the WIP, thanks for the offer :)

zoecarver abandoned this revision.Feb 24 2020, 10:16 AM