From c4d5c5e6ac73cac2b89d039eff9874ff80742589 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 16 Dec 2016 09:38:18 +0000 Subject: [PATCH] re PR middle-end/71632 (hang at -O3 on x86_64-linux-gnu) 2016-12-16 Richard Biener 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. From-SVN: r243737 --- gcc/ChangeLog | 6 +++++ gcc/expr.c | 11 +++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/pr71632.c | 53 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr71632.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ebbc1c..ca4f4f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-12-16 Richard Biener + + PR middle-end/71632 + * expr.c (expand_cond_expr_using_cmove): Bail out early if + we end up recursing via TER. + 2016-12-15 Martin Sebor PR bootstrap/78817 diff --git a/gcc/expr.c b/gcc/expr.c index 88da8dd..32aa237 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e4eca52..8de3e18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-12-16 Richard Biener + + PR middle-end/71632 + * gcc.dg/pr71632.c: New testcase. + 2016-12-15 Andrew Senkevich * gcc.target/i386/avx512bw-kmovd-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr71632.c b/gcc/testsuite/gcc.dg/pr71632.c new file mode 100644 index 0000000..e8d5cc5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr71632.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-if-convert" } */ + +void +foo (double d, double *p, double *q) +{ + int i; + for (i = 0; i < 64; i++) + { + double t1 = d > p[0] ? 1.0 : 0.0; + double t2 = t1 > p[1] ? 1.0 : 0.0; + double t3 = t2 > p[2] ? 1.0 : 0.0; + double t4 = t3 > p[3] ? 1.0 : 0.0; + double t5 = t4 > p[4] ? 1.0 : 0.0; + double t6 = t5 > p[5] ? 1.0 : 0.0; + double t7 = t6 > p[6] ? 1.0 : 0.0; + double t8 = t7 > p[7] ? 1.0 : 0.0; + double t9 = t8 > p[8] ? 1.0 : 0.0; + double t10 = t9 > p[9] ? 1.0 : 0.0; + double t11 = t10 > p[10] ? 1.0 : 0.0; + double t12 = t11 > p[11] ? 1.0 : 0.0; + double t13 = t12 > p[12] ? 1.0 : 0.0; + double t14 = t13 > p[13] ? 1.0 : 0.0; + double t15 = t14 > p[14] ? 1.0 : 0.0; + double t16 = t15 > p[15] ? 1.0 : 0.0; + double t17 = t16 > p[16] ? 1.0 : 0.0; + double t18 = t17 > p[17] ? 1.0 : 0.0; + double t19 = t18 > p[18] ? 1.0 : 0.0; + double t20 = t19 > p[19] ? 1.0 : 0.0; + double t21 = t20 > p[20] ? 1.0 : 0.0; + double t22 = t21 > p[21] ? 1.0 : 0.0; + double t23 = t22 > p[22] ? 1.0 : 0.0; + double t24 = t23 > p[23] ? 1.0 : 0.0; + double t25 = t24 > p[24] ? 1.0 : 0.0; + double t26 = t25 > p[25] ? 1.0 : 0.0; + double t27 = t26 > p[26] ? 1.0 : 0.0; + double t28 = t27 > p[27] ? 1.0 : 0.0; + double t29 = t28 > p[28] ? 1.0 : 0.0; + double t30 = t29 > p[29] ? 1.0 : 0.0; + double t31 = t30 > p[30] ? 1.0 : 0.0; + double t32 = t31 > p[31] ? 1.0 : 0.0; + double t33 = t32 > p[32] ? 1.0 : 0.0; + double t34 = t33 > p[33] ? 1.0 : 0.0; + double t35 = t34 > p[34] ? 1.0 : 0.0; + double t36 = t35 > p[35] ? 1.0 : 0.0; + double t37 = t36 > p[36] ? 1.0 : 0.0; + double t38 = t37 > p[37] ? 1.0 : 0.0; + double t39 = t38 > p[38] ? 1.0 : 0.0; + *q = t39; + p += 39; + q++; + } +} -- 2.7.4