https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95929
--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> --- Here gcc does optimize the first f to (a != 0) ^ (b != 0). However, for the second f, it does indeed generate something that looks like the first f before optimization... The optimization for the first f is probably "(X && !Y) || (!X && Y) is X ^ Y" in fold-const.c, which may not have an equivalent in match.pd yet.