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 }