https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126451
Bug ID: 126451
Summary: Suboptimal codegen produces redundant instruction
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: dr.xiaosa at gmail dot com
Target Milestone: ---
https://godbolt.org/z/von61fza4
===
#include <cstdint>
enum class test_enum : unsigned {
flag0 = 0, flag1, flag2, flag3, flag4, flag5 = 7, flag6, flag7, flag8,
flag9
};
constexpr std::uint16_t MASK = 0xF9F;
struct bit_flag {
std::uint16_t rep = 0;
bit_flag() = default;
static bit_flag from_rep_unchecked(std::uint16_t r) noexcept {
bit_flag b;
b.rep = r;
return b;
}
bit_flag(test_enum e) noexcept
: bit_flag(from_rep_unchecked(
static_cast<unsigned>(e) <= 11 && ((std::uint16_t(1) <<
static_cast<unsigned>(e)) & MASK) != 0
? std::uint16_t(1) << static_cast<unsigned>(e) : 0))
{}
bool any_of(bit_flag other) const noexcept {
return (rep & other.rep) != 0;
}
bool test(test_enum e) const noexcept {
return any_of(e);
}
};
bool test_bit(bit_flag f, test_enum e) noexcept {
return f.test(e);
}
===
On GCC 16.1 and trunk with -O3 enabled, one brunch of test_bit looks like:
===
.L4:
xor eax, eax
test di, ax
setne al
ret
===