https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122541
--- Comment #10 from Niklas Gürtler <profclonk at gmail dot com> ---
I applied this workaround to a larger codebase:
unsigned int test1 (unsigned int x) {
x &= 0xFFFFFFFE;
return x | 0x80000000;
}
But this unfortunately INCREASED the code size: Because most of the bitmasks
for the "AND" operations in my code differ from each other, the compiler then
loads/applies each bitmask individually (as immediate or from literal pool).
This is technically the most correct way, but the "wrong" old behaviour meant
that several bitmasks were identical (as the compiler tries to zero more bits)
which allowed to use one common bitmask for several "AND" operations.
Perhaps ideally the compiler could deduce a set of possible bitmasks, find the
smallest common superset for all "AND" operations close to each other, and only
load this one bitmask into a register and perform AND/BIC with register
(instead of AND/BIC with immediate).