[Bug middle-end/86909] New: Missing common subexpression elimination for types other than int
antoshkka at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Aug 10 10:50:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86909
Bug ID: 86909
Summary: Missing common subexpression elimination for types
other than int
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: antoshkka at gmail dot com
Target Milestone: ---
Consider the following minimized example of the std::variant visitation:
using size_t = unsigned long long;
struct A {};
static const size_t variant_npos = -1;
struct variant {
A a;
using __index_type = unsigned char; // !!!!
__index_type _M_index;
size_t index() const noexcept {
return (_M_index == __index_type(variant_npos) ? variant_npos :
_M_index);
}
};
template<size_t _Np>
static A* get_if(variant* __ptr) noexcept {
return (__ptr->index() == _Np ? &__ptr->a : nullptr);
}
A* foo(variant& in) {
int i = in.index();
if (i==0) return get_if<0>(&in);
if (i==1) return get_if<1>(&in);
if (i==2) return get_if<2>(&in);
if (i==3) return get_if<3>(&in);
if (i==4) return get_if<4>(&in);
if (i==5) return get_if<5>(&in);
if (i==6) return get_if<6>(&in);
return get_if<7>(&in);
}
GCC generates assembly with multiple comparisons:
foo(variant&):
<...>
cmp ecx, 1
je .L4
cmp ecx, 2
je .L4
cmp ecx, 3
je .L4
cmp ecx, 4
je .L4
cmp ecx, 5
je .L4
cmp ecx, 6
je .L4
cmp dl, 7
je .L4
Clang eliminates the subexpressions:
foo(variant&): # @foo(variant&)
movzx ecx, byte ptr [rdi + 1]
cmp cl, -1
mov edx, -1
cmovne edx, ecx
cmp edx, 7
jb .LBB0_2
mov dl, 7
.LBB0_2:
xor eax, eax
cmp cl, dl
cmove rax, rdi
ret
Note that if we change `__index_type` to `int` then GCC generates great
assembly:
foo(variant&):
mov edx, DWORD PTR [rdi+4]
xor eax, eax
cmp edx, -1
je .L1
cmp edx, 7
cmovbe rax, rdi
.L1:
ret
More information about the Gcc-bugs
mailing list