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))"

Reply via email to