diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/loop-iv.c | 12 | ||||
-rw-r--r-- | gcc/loop-unswitch.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr58997.c | 19 |
5 files changed, 52 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 468b185..72f93f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-11-05 Jakub Jelinek <jakub@redhat.com> + + 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 <amacleod@redhat.com> * 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 b9bc334..97aa52f 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 3bdb10a..219c943 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 6146163..f49141a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-05 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/58997 + * gcc.c-torture/compile/pr58997.c: New test. + 2013-11-05 Paolo Carlini <paolo.carlini@oracle.com> 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 0000000..2c7a0f8 --- /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) + ; + } +} |