https://gcc.gnu.org/bugzilla/show_bug.cgi?id=15184
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |law at redhat dot com --- Comment #29 from Jeffrey A. Law <law at redhat dot com> --- I can certainly understand wanting to handle this in the bswap pass and if you can make it fly there, that's obviously good. But I also wonder if we're just being dumb in combine and the x86 backend in terms of recognizing when a blob of RTL really just represents a bitfield insertion. Isn't the first case just: (define_insn_and_split "" [(set (match_operand:SI 0 "register_operand") (ior:SI (and:SI (match_operand:SI 1 "register_operand") (match_operand 3 "const_int_operand")) (zero_extend:SI (match_operand 2 "register_operand"))))] "INTVAL (operands[3]) == ~GET_MODE_MASK (GET_MODE (operands[2]))" "#" "" [(set (match_dup 0) (match_dup 1)) (set (zero_extract (match_dup 0) (match_dup 4) (const_int 0)) (match_dup 2))] "{ operands[4] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[2]))); }") The second case is similar, except we have another AND expression rather than the zero_extend in the pattern because we're inserting into a middle byte. Cases #3 and #4 appear to be more complex, but that may be a failing in the combine simplifications and canonicalization. I haven't looked deeply yet.