https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71002
--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> --- So optimize_bit_field_compare does make a difference implementation-wise (but not really fixes the undefinedness in the boost code wrt the access of the non-active union-member when reading from is_short). optimize_bit_field_compare turns ((const struct string *) this)->m_repr.s.h.is_short != 0 into (BIT_FIELD_REF <*(const struct string *) this, 8, 0> & 1) != 0 where the former memory access uses alias-set zero because of c-common.c:c_common_get_alias_set handling of union-accesses: /* Permit type-punning when accessing a union, provided the access is directly through the union. For example, this code does not permit taking the address of a union member and then storing through it. Even the type-punning allowed here is a GCC extension, albeit a common and useful one; the C standard says that such accesses have implementation-defined behavior. */ for (u = t; TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; u = TREE_OPERAND (u, 0)) if (TREE_CODE (u) == COMPONENT_REF && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) return 0; (which is something I am trying to get rid of for quite some time ...) And the latter gets alias-set (that of type 'string') (which I think is the better behavior, even if "miscompiling" this case). Not applying optimize_bit_field_compare also gets us better optimization, removing dead code already at the early GIMPLE level.