From 50fae5a679990a4bba7dc30de21e6d4132d778fb Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 5 Nov 2013 20:37:51 +0100 Subject: [PATCH] re PR rtl-optimization/58997 (ICE on valid code at -O3 on x86_64-linux-gnu (affecting gcc trunk and 4.8.2)) PR rtl-optimization/58997 * loop-iv.c (iv_subreg): For IV_UNKNOWN_EXTEND, expect get_iv_value to be in iv->mode rather than iv->extend_mode. (iv_extend): Likewise. Otherwise, if iv->extend != extend, use lowpart_subreg on get_iv_value before calling simplify_gen_unary. * loop-unswitch.c (may_unswitch_on): Make sure op[i] is in the right mode. * gcc.c-torture/compile/pr58997.c: New test. From-SVN: r204413 --- gcc/ChangeLog | 10 ++++++++++ gcc/loop-iv.c | 12 ++++++++++-- gcc/loop-unswitch.c | 11 ++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/compile/pr58997.c | 19 +++++++++++++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr58997.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 468b1856c4f..72f93f9d07e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-11-05 Jakub Jelinek + + PR rtl-optimization/58997 + * loop-iv.c (iv_subreg): For IV_UNKNOWN_EXTEND, expect + get_iv_value to be in iv->mode rather than iv->extend_mode. + (iv_extend): Likewise. Otherwise, if iv->extend != extend, + use lowpart_subreg on get_iv_value before calling simplify_gen_unary. + * loop-unswitch.c (may_unswitch_on): Make sure op[i] is in the right + mode. + 2013-11-05 Andrew MacLeod * gimple.h: Move some prototypes to gimple-expr.h and add to include diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index b9bc3348733..97aa52fc6dd 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -436,7 +436,9 @@ iv_subreg (struct rtx_iv *iv, enum machine_mode mode) && !iv->first_special) { rtx val = get_iv_value (iv, const0_rtx); - val = lowpart_subreg (mode, val, iv->extend_mode); + val = lowpart_subreg (mode, val, + iv->extend == IV_UNKNOWN_EXTEND + ? iv->mode : iv->extend_mode); iv->base = val; iv->extend = IV_UNKNOWN_EXTEND; @@ -476,8 +478,14 @@ iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, enum machine_mode mode && !iv->first_special) { rtx val = get_iv_value (iv, const0_rtx); + if (iv->extend_mode != iv->mode + && iv->extend != IV_UNKNOWN_EXTEND + && iv->extend != extend) + val = lowpart_subreg (iv->mode, val, iv->extend_mode); val = simplify_gen_unary (iv_extend_to_rtx_code (extend), mode, - val, iv->extend_mode); + val, + iv->extend == extend + ? iv->extend_mode : iv->mode); iv->base = val; iv->extend = IV_UNKNOWN_EXTEND; iv->mode = iv->extend_mode = mode; diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c index 3bdb10a4373..219c943545b 100644 --- a/gcc/loop-unswitch.c +++ b/gcc/loop-unswitch.c @@ -191,6 +191,7 @@ may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn) if (!test) return NULL_RTX; + mode = VOIDmode; for (i = 0; i < 2; i++) { op[i] = XEXP (test, i); @@ -205,11 +206,15 @@ may_unswitch_on (basic_block bb, struct loop *loop, rtx *cinsn) return NULL_RTX; op[i] = get_iv_value (&iv, const0_rtx); + if (iv.extend != IV_UNKNOWN_EXTEND + && iv.mode != iv.extend_mode) + op[i] = lowpart_subreg (iv.mode, op[i], iv.extend_mode); + if (mode == VOIDmode) + mode = iv.mode; + else + gcc_assert (mode == iv.mode); } - mode = GET_MODE (op[0]); - if (mode == VOIDmode) - mode = GET_MODE (op[1]); if (GET_MODE_CLASS (mode) == MODE_CC) { if (at != BB_END (bb)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 61461633e59..f49141a381c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-05 Jakub Jelinek + + PR rtl-optimization/58997 + * gcc.c-torture/compile/pr58997.c: New test. + 2013-11-05 Paolo Carlini PR c++/58724 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58997.c b/gcc/testsuite/gcc.c-torture/compile/pr58997.c new file mode 100644 index 00000000000..2c7a0f82c8a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr58997.c @@ -0,0 +1,19 @@ +/* PR rtl-optimization/58997 */ + +int a, b, c, e; +short d; +char h; + +void +foo () +{ + while (b) + { + d = a ? c : 1 % a; + c = d; + h = d; + if (!h) + while (e) + ; + } +}