http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46088
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> 2010-11-11 11:29:52 UTC --- Created attachment 22373 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=22373 gcc46-pr46088.patch Untested fix. I went through ix86_binary_operator_ok: /* Both source operands cannot be in memory. */ if (MEM_P (src1) && MEM_P (src2)) return false; doesn't apply, because src2 is known to be const_1_to_{31,63}_operand, i.e. CONST_INT. /* Canonicalize operand order for commutative operators. */ if (ix86_swap_binary_operands_p (code, mode, operands)) { rtx temp = src1; src1 = src2; src2 = temp; } doesn't apply, the shifts aren't commutative. /* If the destination is memory, we must have a matching source operand. */ if (MEM_P (dst) && !rtx_equal_p (dst, src1)) return false; doesn't apply, dst is either missing (but then will be scratch_operand), or is a scratch_operand already. /* Source 1 cannot be a constant. */ if (CONSTANT_P (src1)) return false; doesn't apply, src1 is known to be nonimmediate_operand, i.e. && ! CONSTANT_P (op). /* Source 1 cannot be a non-matching memory. */ if (MEM_P (src1) && !rtx_equal_p (dst, src1)) { /* Support "andhi/andsi/anddi" as a zero-extending move. */ return (code == AND && ... is the only one that applies, and dst is known not to be a MEM and code is known not to be AND. That said, if you prefer to still do ix86_binary_operator_ok, there are other options, like: - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + && (GET_CODE (PATTERN (insn)) == SET + ? !MEM_P (operands[1]) + : ix86_binary_operator_ok (<CODE>, <MODE>mode, operands))" - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + && ((!reload_completed && GET_CODE (PATTERN (insn)) == SET) + ? !MEM_P (operands[1]) + : ix86_binary_operator_ok (<CODE>, <MODE>mode, operands))"