Issue 164150
Summary constexpr structured bindings bad codegen P2686
Labels new issue
Assignees
Reporter ordinary-github-user
    `-std=c++26 -O3 -Wall -march=znver5 -fno-exceptions -fconstexpr-steps=4294967295 -fbracket-depth=4294967295`
```c
#include <array>
#include <cstdint>
using u8 = std::uint8_t;
template<u8 N>
struct Range
{
 template<std::size_t I>
    constexpr friend u8 get(Range) noexcept { return I; }
};
namespace std
{
    template<u8 N>
    struct tuple_size<Range<N>> {static constexpr std::size_t value = N;};
 template<std::size_t I, u8 N>
    struct tuple_element<I, Range<N>> {using type = u8;};
}
template<u8 x>constexpr u8 constant{x};
template<std::size_t L, std::size_t R>
__attribute__((always_inline)) inline constexpr std::array<u8, L+R> concat(const std::array<u8, L>& l, const std::array<u8, R>& r)
{
    static constexpr auto [...I] = Range<L>{};
    static constexpr auto [...J] = Range<R>{};
#if 0
    return { l[I]..., r[J]... };//bad codegen
#else
 return { l[constant<I>]..., r[constant<J>]... };//good codegen
#endif
}
auto test(const std::array<u8, 16>& l, const std::array<u8, 16>& r)
{
    return concat(l, r);
}
```
good codegen
```
test(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&):
  vmovups xmm0, xmmword ptr [rsi]
 vmovups xmm1, xmmword ptr [rdx]
  mov rax, rdi
  vmovups xmmword ptr [rdi + 16], xmm1
  vmovups xmmword ptr [rdi], xmm0
  ret
```
bad codegen
```
test(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&):
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I]
  mov rax, rdi
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.2)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 1], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.4)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 2], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.6)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 3], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.8)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 4], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.10)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 5], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.12)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 6], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.14)]
 movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 7], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.16)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 8], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.18)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 9], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.20)]
 movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 10], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.22)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 11], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.24)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 12], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.26)]
 movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 13], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.28)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 14], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.30)]
  movzx ecx, byte ptr [rsi + rcx]
  mov byte ptr [rdi + 15], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 16], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.32)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 17], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.34)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 18], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.36)]
 movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 19], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.38)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 20], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.40)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 21], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.42)]
 movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 22], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.44)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 23], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.46)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 24], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.48)]
 movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 25], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.50)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 26], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.52)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 27], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.54)]
 movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 28], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.56)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 29], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.58)]
  movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 30], cl
  movzx ecx, byte ptr [rip + reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.60)]
 movzx ecx, byte ptr [rdx + rcx]
  mov byte ptr [rdi + 31], cl
 ret
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I:
  .byte 0
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.2):
  .byte 1
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.4):
  .byte 2
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.6):
  .byte 3
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.8):
  .byte 4
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.10):
  .byte 5
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.12):
  .byte 6
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.14):
  .byte 7
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.16):
  .byte 8
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.18):
  .byte 9
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.20):
  .byte 10
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.22):
  .byte 11
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.24):
  .byte 12
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.26):
  .byte 13
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.28):
  .byte 14
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::I (.30):
  .byte 15
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J:
  .byte 0
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.32):
  .byte 1
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.34):
  .byte 2
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.36):
  .byte 3
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.38):
  .byte 4
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.40):
  .byte 5
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.42):
  .byte 6
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.44):
  .byte 7
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.46):
  .byte 8
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.48):
  .byte 9
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.50):
  .byte 10
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.52):
  .byte 11
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.54):
  .byte 12
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.56):
  .byte 13
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.58):
  .byte 14
reference temporary for std::array<unsigned char, 16ul + 16ul> concat<16ul, 16ul>(std::array<unsigned char, 16ul> const&, std::array<unsigned char, 16ul> const&)::J (.60):
  .byte 15
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to