http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49472

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |aoliva at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-06-20 
16:07:45 UTC ---
We seem to be oscillating on
exprA = (div:DF (reg:DF 98) (reg:DF 96))
exprB = (div:DF (const_double:DF 1.0e+0 [0x0.8p+1]) (reg:DF 90 [ powroot.4 ]))

op0:
(mult:DF exprA (neg:DF exprA))
op1:
exprB

and:
op0:
(mult:DF exprB (neg:DF exprA))
op1:
exprA

and:
op0:
(mult:DF exprA (neg:DF exprB))
op1:
exprA

(and then back to the first op0/op1 form) in:
1799      /* Canonicalize "(x op c) op y" as "(x op y) op c".  */
1800      if (swap_commutative_operands_p (XEXP (op0, 1), op1))
1801        {
1802          tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
1803          return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
1804        }

(each new occurrence of this is 7 frames deeper in the backtrace).
Not sure if this might be "fixed" by Alex' patch for PR48866 (if we generate
more debug temps, supposedly the expressions wouldn't be so large and we
wouldn't hit this.

Anyway, the issue here is that swap_commutative_operands_p thinks it is better
to have the negation in the second operand instead of second operand of the
first operand, but when we built it that way, MULT case in
simplify_binary_operation_1 attempts to move the NEG from the second operand to
the first one:
      if (GET_CODE (op1) == NEG)
        {
          rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
          if (temp)
            return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
        }
then simplify_unary_operation_1 does:
689      /* (neg (mult A B)) becomes (mult (neg A) B).
690         This works even for floating-point values.  */
691      if (GET_CODE (op) == MULT
692          && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
693        {
694          temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
695          return simplify_gen_binary (MULT, mode, temp, XEXP (op, 1));
696        }
and finally simplify_binary_operation_1 does:
1840  /* Make sure the constant is second.  */
1841  if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
1842      && swap_commutative_operands_p (op0, op1))
1843    {
1844      tem = op0, op0 = op1, op1 = tem;
1845    }

Reply via email to