<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62021>62021</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Unoptimized constexpr code for std::array
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
StefanoD
</td>
</tr>
</table>
<pre>
Hello,
forgive me when I can't be that precise. I just pasted some test code to [godbolt](https://godbolt.org/z/Mde6WdrbE) and compared the assembly output between GCC 12.2 and clang 16.0.0 and the assembly code of clang was about 3 times larger and I guess, that this code is less optimized.
Here the code:
```cpp
#include <array>
#include <algorithm>
#include <stdexcept>
#include <iostream>
template <typename Key, typename Value, std::size_t Size>
struct FlatMap {
constexpr explicit FlatMap(std::array<std::pair<Key, Value>, Size> data) :
m_data(std::move(data)) {}
constexpr Value at(const Key &key) const {
const auto itr =
std::find_if(begin(m_data), end(m_data),
[&key](const auto &v) { return v.first == key; });
if (itr != end(m_data)) {
return itr->second;
}
throw std::range_error("Not Found");
}
private:
std::array<std::pair<Key, Value>, Size> m_data;
};
enum Foo
{
P, N, B, R, Q, K, p, n, b, r, q, k
};
constexpr FlatMap<char, Foo, 12> map {
{{
{'P', P},
{'N', N},
{'B', B},
{'R', R},
{'Q', Q},
{'K', K},
{'p', p},
{'n', n},
{'b', b},
{'r', r},
{'q', q},
{'k', k}
}}
};
int main()
{
std::cout << map.at('P') << std::endl;
return 0;
}
```
The assembly output of x86-64 GCC 12.2 with -O3 -std=c++20
```asm
main:
pushq %rbp
xorl %esi, %esi
movl $_ZSt4cout, %edi
pushq %rbx
subq $8, %rsp
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
movq %rax, %rbx
movq (%rax), %rax
movq -24(%rax), %rax
movq 240(%rbx,%rax), %rbp
testq %rbp, %rbp
je .L7
cmpb $0, 56(%rbp)
je .L3
movsbl 67(%rbp), %esi
.L4:
movq %rbx, %rdi
call std::basic_ostream<char, std::char_traits<char> >::put(char)
movq %rax, %rdi
call std::basic_ostream<char, std::char_traits<char> >::flush()
addq $8, %rsp
xorl %eax, %eax
popq %rbx
popq %rbp
ret
.L3:
movq %rbp, %rdi
call std::ctype<char>::_M_widen_init() const
movq 0(%rbp), %rax
movl $10, %esi
movq %rbp, %rdi
call *48(%rax)
movsbl %al, %esi
jmp .L4
.L7:
call std::__throw_bad_cast()
_GLOBAL__sub_I_main:
subq $8, %rsp
movl $_ZStL8__ioinit, %edi
call std::ios_base::Init::Init() [complete object constructor]
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
jmp __cxa_atexit
```
The assembly output of x86-64 clang 16.0.0 with -O3 -std=c++20:
```asm
main: # @main
pushq %r14
pushq %rbx
pushq %rax
movb $80, 7(%rsp)
leaq _ZL3map(%rip), %rdi
leaq 7(%rsp), %rsi
callq _ZNK7FlatMapIc3FooLm12EE2atERKc
movq _ZSt4cout@GOTPCREL(%rip), %rdi
movl %eax, %esi
callq _ZNSolsEi@PLT
movq %rax, %rbx
movq (%rax), %rax
movq -24(%rax), %rax
movq 240(%rbx,%rax), %r14
testq %r14, %r14
je .LBB0_5
cmpb $0, 56(%r14)
je .LBB0_3
movzbl 67(%r14), %eax
jmp .LBB0_4
.LBB0_3:
movq %r14, %rdi
callq _ZNKSt5ctypeIcE13_M_widen_initEv@PLT
movq (%r14), %rax
movq %r14, %rdi
movl $10, %esi
callq *48(%rax)
.LBB0_4:
movsbl %al, %esi
movq %rbx, %rdi
callq _ZNSo3putEc@PLT
movq %rax, %rdi
callq _ZNSo5flushEv@PLT
xorl %eax, %eax
addq $8, %rsp
popq %rbx
popq %r14
retq
.LBB0_5:
callq _ZSt16__throw_bad_castv@PLT
_ZNK7FlatMapIc3FooLm12EE2atERKc: # @_ZNK7FlatMapIc3FooLm12EE2atERKc
pushq %r14
pushq %rbx
pushq %rax
movzbl (%rsi), %eax
cmpb %al, (%rdi)
jne .LBB1_3
xorl %ecx, %ecx
jmp .LBB1_2
.LBB1_3:
movl $1, %ecx
cmpb %al, 8(%rdi)
je .LBB1_2
movl $2, %ecx
cmpb %al, 16(%rdi)
je .LBB1_2
movl $3, %ecx
cmpb %al, 24(%rdi)
je .LBB1_2
movl $4, %ecx
cmpb %al, 32(%rdi)
je .LBB1_2
movl $5, %ecx
cmpb %al, 40(%rdi)
je .LBB1_2
movl $6, %ecx
cmpb %al, 48(%rdi)
je .LBB1_2
movl $7, %ecx
cmpb %al, 56(%rdi)
je .LBB1_2
movl $8, %ecx
cmpb %al, 64(%rdi)
je .LBB1_2
movl $9, %ecx
cmpb %al, 72(%rdi)
je .LBB1_2
movl $10, %ecx
cmpb %al, 80(%rdi)
je .LBB1_2
movl $11, %ecx
cmpb %al, 88(%rdi)
jne .LBB1_14
.LBB1_2:
movl 4(%rdi,%rcx,8), %eax
addq $8, %rsp
popq %rbx
popq %r14
retq
.LBB1_14:
movl $16, %edi
callq __cxa_allocate_exception@PLT
movq %rax, %rbx
leaq .L.str(%rip), %rsi
movq %rax, %rdi
callq _ZNSt11range_errorC1EPKc@PLT
movq _ZTISt11range_error@GOTPCREL(%rip), %rsi
movq _ZNSt11range_errorD1Ev@GOTPCREL(%rip), %rdx
movq %rbx, %rdi
callq __cxa_throw@PLT
movq %rax, %r14
movq %rbx, %rdi
callq __cxa_free_exception@PLT
movq %r14, %rdi
callq _Unwind_Resume@PLT
_GLOBAL__sub_I_example.cpp: # @_GLOBAL__sub_I_example.cpp
pushq %rbx
leaq _ZStL8__ioinit(%rip), %rbx
movq %rbx, %rdi
callq _ZNSt8ios_base4InitC1Ev@PLT
movq _ZNSt8ios_base4InitD1Ev@GOTPCREL(%rip), %rdi
leaq __dso_handle(%rip), %rdx
movq %rbx, %rsi
popq %rbx
jmp __cxa_atexit@PLT # TAILCALL
_ZL3map:
.byte 80 # 0x50
.zero 3
.long 0 # 0x0
.byte 78 # 0x4e
.zero 3
.long 1 # 0x1
.byte 66 # 0x42
.zero 3
.long 2 # 0x2
.byte 82 # 0x52
.zero 3
.long 3 # 0x3
.byte 81 # 0x51
.zero 3
.long 4 # 0x4
.byte 75 # 0x4b
.zero 3
.long 5 # 0x5
.byte 112 # 0x70
.zero 3
.long 6 # 0x6
.byte 110 # 0x6e
.zero 3
.long 7 # 0x7
.byte 98 # 0x62
.zero 3
.long 8 # 0x8
.byte 114 # 0x72
.zero 3
.long 9 # 0x9
.byte 113 # 0x71
.zero 3
.long 10 # 0xa
.byte 107 # 0x6b
.zero 3
.long 11 # 0xb
.L.str:
.asciz "Not Found"
DW.ref.__gxx_personality_v0:
.quad __gxx_personality_v0
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWltz4jbf_zTKjSaMLR-5yEUgpM2EpmmyfTvTG49sC9CusRxJTkg-_TuSLZ8whn3aZ56dHQek_-H3P0sAFoJuc0JugLcA3t0VLuWO8ZtXSTY4Z3dXMUs_b34lWcYAWgLrDli3G8a39J3APYEfO5LDB5jgHKBAwphAucMSFpwkVJAZfIDfSyFhgYUkKRRsT6AkQsKEpQRKBoG32LI0ZpkE3h1A4U7KQgDnFqB7gO7rrRnjW4DuvwC6_y0l_l8pj1cAzSHOU5iwfYE5SaHcEYiFIPs4-4SslEWp4MgPQnL4y3IJbTRDFUeG8y20_Zk1s_RCj1MDY5ua6gMLiGNWSuhASfdEwAzzLeGa7wFuSyIEQMvKaLmjouKnAmZECMgKSff0i6SzynHV81fCiVaqaJWtnT3gW9X_pCjqFeTQPMnKlEDgLDHn-BM4q9G9bMs4lbv9iX0hU3JISCFP7FMmJCe4Yp93UUmyLzIsNZX8LEiO9wQ-kk9tunn_fzgriVoRMlVWObeCfpFIwlf6RRqVQvIykfA-w_I3XEAQLKp1CCFMWC4kORQckkOR0YQ2dACFjdTaBctmocCUA2dZ46lgOCv1utYMUyyxSpjG2XAfVWut2D17JwCFNammDhYguOv6oQ9Sa4JYAhTqReURCJD_QwGZV4R9Axt-iEvJIJUcAqfW0LptQ_M0ohuAwphsaQ5QaNDOlVEkTwdLtQBVwJV2XUodRQD577VFkBNZ8hy-zzaUK3zOHXDuoOJyFlDZi-bAGWCmGwhQqOEiW5EfYZgfG6r-1cqo5NfAWQmSsDw9kj50stxx9tG6g-N8SyLCOeMAhQChJybhPSsVBDREO5BVcPqOZVtk8J9kUW2uUadUNa_1k-TlHt4zZvY7uJ6VoCf1WKjHi3r8oR6P6lGoR64esXpw9XhTjx-nVLVZaCrEWSY7rDkVAqQangY9LLLKS4vRcHX3UfAMUKAEPeusWJ4jf6rJny4jX9Tkix55tfdS771cJuqPmvyPEVGP9d7jZaKKmry4jDyvyfPLyOOaPL6MnNfkfMSut3rv7TJRP2ryH02B6FJpquUowWgu4R7r7qNq7Dijm8JJ1HgEzhI4S5VtM90Qm_SZm62GnuRp1qvZuklYvcrqT8Musm8jg55t4CH0r323HfUfVO7g9e8OvNaa7xKAFgAtkDUQjcW-WtHWNo0CFqXYvUGAPB4XZu3AeKaWiKDKmfWrenPP3tWmG_39Kl3lFEOS0hGZB7MmylgtuWFNzoVRl-Asa90WY0GTqBnRTbW3cdhhHkmOqRRm21lB1cP0NisIx5LxKhyqneeyiawCXwHDB4OjhVhvhmZ_bkhwn-QauRdQIdeqqWKl64i8dbc6KTYhONr9TuBsHZh3yb6IlRstRej5RkPRmlgxOB0sIs6gH_RIB1Gdrd1OSjROihsntbH9d6NVlPpYobnmR_rxf13_JivFrlv7EOI0PZGobV00wEgT9IIVw5RvlxoJnEjjcWfU48U5ixN1EG1NqRaj36IPmpI8ojmt2lJ9LuspsEZSoJ-1urBta7TozwAE6Fa5rFMW_QQEyMPZkeDv-wKq5Kt9EnR80jc7ivRxKYpxGiVYyG7Mol_Wvy9u11Ekyjh6iPoN7nTf6XWydRhFlFXuG7azPhLKRBRjQap3D4qjfVW5HngLdV_LiCSQxd9JIqtoqCsB4-rYOkQQpYJFO5ynGWn0HwVmHOdYZ356laHB6Spgd_bq_diwiVRXgYmi5IAjLMmByv94UPWuoaeH1Ynr4XBqQYAcCFxLvz2aNrY7NYHatV7O63Ya6pw3PVJ022lG8BuM_l47e30_U_u0W0CNOzVhX4Rxay-VlLSnx6A-0D4kzj1j672NViuE5erlMekVXTtmXeuX3789L19W60kYJg26XWoEwCvLxIoC13pef5tovP-r6diGsp2Otnu8q4fdYmFF3vSEVLzzI6bulPzqTsmKfNjjq26lGJuOVUkZ6eQt2HQk-q_S0438IVnZTq97r95HY3KEaujQUzqnunqF50TnNob2bDvdyc-fGuq0c4pSrpKzidfwdlg9Pa6HHpqaylMtbmpitwnGiXzrOsQbjKiqQm1_OKB6IM8VfNvYLmwN_7DnfekwhnVvGsl0U0VNpMM6Jp0iyqsqspsqagKRNIFIDt2BUpGj1p32sHaqVD3m7sMJR_GQvvxWHjonz_ZHBJ6W55yT13TAaYBGnntOnoN-zmDvSGBfXtN7L5TnnwPo_mREgnMCvbGITAgMzwn0LwtJI3B-TmDwkzFp---JoIQ_GRT7fJmMR6WpW9vtViIaVmLXY3pA67IOx9rFv9xlNbSRvuCPn83fzEk1y1iCJYmqj_8pyy8_3ujD22w9E5KPna5Gxtypy2k1q6Rtdz7QXdqr58exmRf9_e1hQHvmnDdAcqxLH_XPnBWPjw4TQ1v7Vg-3s-5sAzoluCt3w8n5eE2cpf7MP2ieRi9ElHvSG7n9SyE5YHUhmyVF0Z22p4kmhmp9I-hfxo69fHR0Pnc0GtzZlvboWfDU7e7S60GFvnfh_MkMaVNwpLiPLo7aAu3wb7cP6-Xtem3ORNWVqq3zWfwpCQwtTWwdPKvZ-CKcweawPstYvoWGzFBV3EFYL7tkktuuyey-ct837KbfjnKjmgoNoJt1D00qd2oyZ8BuQHn2JLtrMPbZA8-sx5Pshszrs9u2QR-ccHzFbjzkD9lNQPxpzwdGSy9ucxM3f9p1hiwcajdOCSYDN6-p5kN2E5Jg2vWNkXggwDJm-dPOt02MazIz9PTgaUphhkVCv-DwS8AOx91fM042syjaHg5RQbhgOc6o_IzerW5FvZU4haNElSzzOctVeuOkc2eOr8iN7YfWPAi8wLna3VieGycedmN_E7hzK5i7tuslju95qRPMw-SK3iALOZZrhXZoI8-Z2Ruy2fgBclPX2-BgA1yL7DHNZln2vp8xvr2iQpTkxkcWsq8yHJNM6B9lIJSTD6g3lbHe3RW_UTzXcbkVwLUyKqRopUgqM3LzZ978-KDzlbX-dcKG8cH3oFclz24GP72gclfGs4TtAbpXsus_1wVn30kiAbrXiARA9xrx_wcAAP__c483_w">