aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/loop-iv.c12
-rw-r--r--gcc/loop-unswitch.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr58997.c19
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)
+ ;
+ }
+}