From patchwork Wed Nov 7 22:21:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix PR middle-end/55219 Date: Wed, 07 Nov 2012 12:21:59 -0000 From: Eric Botcazou X-Patchwork-Id: 197734 Message-Id: <5336214.jMX7Aekqkv@polaris> To: gcc-patches@gcc.gnu.org This is a regression present on the mainline and 4.7 branch. For expressions of the form: h = (g ? c : g ? f : g ? e : g ? i : g ? f : g ? e : g ? d : x) + (a ? : a ? : a ? : a ? : a ? : a ? : a ? : a ? : a ? : a ? : a ? j : a ? : 0 ? : a ? : a ? : a ? : a ? : a ? : a ? k : a ? : x); there is a memory explosion in the folder: fold_binary_op_with_conditional_arg is distributing the + inside the conditional expressions at each level recursively. The transformation was originally applied only if the argument was TREE_CONSTANT, but during 4.7 development I extended it to more general arguments to help Ada. Fixed by disabling recursion entirely, as it was originally. Bootstrapped/regtested on x86_64-suse-linux, applied on mainline and 4.7 branch as obvious. 2012-11-07 Eric Botcazou PR middle-end/55219 * fold-const.c (fold_binary_op_with_conditional_arg): Do not fold if the argument is itself a conditional expression. 2012-11-07 Eric Botcazou * gcc.c-torture/compile/20121107-1.c: New test. Index: fold-const.c =================================================================== --- fold-const.c (revision 193280) +++ fold-const.c (working copy) @@ -5987,10 +5987,11 @@ fold_binary_op_with_conditional_arg (loc cond_code = VEC_COND_EXPR; /* This transformation is only worthwhile if we don't have to wrap ARG - in a SAVE_EXPR and the operation can be simplified on at least one - of the branches once its pushed inside the COND_EXPR. */ + in a SAVE_EXPR and the operation can be simplified without recursing + on at least one of the branches once its pushed inside the COND_EXPR. */ if (!TREE_CONSTANT (arg) && (TREE_SIDE_EFFECTS (arg) + || TREE_CODE (arg) == COND_EXPR || TREE_CODE (arg) == VEC_COND_EXPR || TREE_CONSTANT (true_value) || TREE_CONSTANT (false_value))) return NULL_TREE;