diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-16 09:38:18 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-12-16 09:38:18 +0000 |
commit | 7874b640075a793f860a5df1c80f1ac384582424 (patch) | |
tree | 5ca4810e059a745910ac4104d358ec371aca2b33 /gcc/expr.c | |
parent | 44fd6016d8c1f7de81fcf486487b7db156131818 (diff) |
2016-12-16 Richard Biener <rguenther@suse.de>
PR middle-end/71632
* expr.c (expand_cond_expr_using_cmove): Bail out early if
we end up recursing via TER.
* gcc.dg/pr71632.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243737 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 88da8dd4a3f..32aa237c6fa 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8096,6 +8096,15 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, int unsignedp = TYPE_UNSIGNED (type); machine_mode mode = TYPE_MODE (type); machine_mode orig_mode = mode; + static bool expanding_cond_expr_using_cmove = false; + + /* Conditional move expansion can end up TERing two operands which, + when recursively hitting conditional expressions can result in + exponential behavior if the cmove expansion ultimatively fails. + It's hardly profitable to TER a cmove into a cmove so avoid doing + that by failing early if we end up recursing. */ + if (expanding_cond_expr_using_cmove) + return NULL_RTX; /* If we cannot do a conditional move on the mode, try doing it with the promoted mode. */ @@ -8109,6 +8118,7 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, else temp = assign_temp (type, 0, 1); + expanding_cond_expr_using_cmove = true; start_sequence (); expand_operands (treeop1, treeop2, temp, &op1, &op2, EXPAND_NORMAL); @@ -8143,6 +8153,7 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, if (comparison_mode == VOIDmode) comparison_mode = TYPE_MODE (TREE_TYPE (treeop0)); } + expanding_cond_expr_using_cmove = false; if (GET_MODE (op1) != mode) op1 = gen_lowpart (mode, op1); |