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
===

Reply via email to