Bug 113718 - std::bit_cast making the compiler generate unnecessary code.
Summary: std::bit_cast making the compiler generate unnecessary code.
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 13.2.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2024-02-02 11:42 UTC by Cassio Neri
Modified: 2024-02-05 01:21 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-02-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Cassio Neri 2024-02-02 11:42:18 UTC
Consider:

#include <bit>

void f();

auto const p1 = &f;
auto const p2 = std::bit_cast<void(*)()>(&f);

bool a() {
  return p1 == p2;
}

The code emitted for `a` should be the same as-if `return true;` but the usage of a "no-op" `std::bit_cast` muddies the waters and the compiler generates:

a():
  cmp QWORD PTR p2[rip], OFFSET FLAT:_Z1fv
  sete al
  ret

FWIW: The following changes make the compiler to generate more efficient code:

1. Move `p1` and `p2` inside the body of `a`.
2. Replace `std::bit_cast` with `static_cast`.
3. Remove the cast altogether.

Things get terribly worse if `p1` and `p2` are made `static` and moved inside the body of `a`.

Given that the compiler can get confused by a "no-op" `std::bit_cast`, I wonder if it would do the same for more interesting code than this toy example.

https://godbolt.org/z/daWe5Yod8
Comment 1 Drea Pinski 2024-02-04 04:04:09 UTC
void f();
static auto const p2 = __builtin_bit_cast(void(*)(), (&f));


Even  causes the front-end to emit a dynamic initializer for p2.

There is definitely 2 issues here, one for the above and one for the original code.

Note bit_cast is not a const expression due to being a pointer type and that is what causes the front-end to emit dynamic initializer.

But I wonder if the front-end could try to do it without the dynamic initializer.

Anyways confirmed.

Note there is another bug about converting dynamic initializers to static initializers (PR 4131 and PR 102876).