aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@wasabisystems.com>2004-01-24 20:54:58 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2004-01-24 20:54:58 +0000
commit1f44254ccf5dca2edde504b4b1aa27715cf30717 (patch)
treeb55b45fc6481bcaff82c645136aa4dcc68c3903b
parentb5142d8ae86610ed587103b22c33e1f3b46e8edc (diff)
downloadgcc-1f44254ccf5dca2edde504b4b1aa27715cf30717.zip
gcc-1f44254ccf5dca2edde504b4b1aa27715cf30717.tar.gz
gcc-1f44254ccf5dca2edde504b4b1aa27715cf30717.tar.bz2
re PR bootstrap/13848 (bootstrap failure - ICE in ada/utils.c)
PR bootstrap/13848 * cse.c (cse_cc_succs): Change the mode of the source expression as soon as decide we need a new mode. Don't permit changing modes if we found a match in a successor block. (cse_condition_code_reg): Save original mode of source expression so that we know whether we have to change the mode in other insns. * gcc.dg/20040124-1.c: New test. From-SVN: r76522
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cse.c48
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/20040124-1.c25
4 files changed, 73 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 54e0d4f..6aad8de2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2004-01-24 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR bootstrap/13848
+ * cse.c (cse_cc_succs): Change the mode of the source expression
+ as soon as decide we need a new mode. Don't permit changing modes
+ if we found a match in a successor block.
+ (cse_condition_code_reg): Save original mode of source expression
+ so that we know whether we have to change the mode in other
+ insns.
+
2004-01-24 Jan Hubicka <jh@suse.cz>
* emit-rtl.c (change_address, adjust_address_1, offset_address,
diff --git a/gcc/cse.c b/gcc/cse.c
index 90c67c0..266170b 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -7790,7 +7790,7 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
found = true;
else if (GET_CODE (cc_src) == COMPARE
&& GET_CODE (SET_SRC (set)) == COMPARE
- && GET_MODE (cc_src) != set_mode
+ && mode != set_mode
&& rtx_equal_p (XEXP (cc_src, 0),
XEXP (SET_SRC (set), 0))
&& rtx_equal_p (XEXP (cc_src, 1),
@@ -7806,23 +7806,31 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
if (found)
{
found_equiv = true;
- if (insn_count < ARRAY_SIZE(insns))
+ if (insn_count < ARRAY_SIZE (insns))
{
insns[insn_count] = insn;
modes[insn_count] = set_mode;
last_insns[insn_count] = end;
++insn_count;
- /* Sanity check. */
- if (! can_change_mode && mode != comp_mode)
- abort ();
-
- mode = comp_mode;
+ if (mode != comp_mode)
+ {
+ if (! can_change_mode)
+ abort ();
+ mode = comp_mode;
+ PUT_MODE (cc_src, mode);
+ }
}
else
{
if (set_mode != mode)
- break;
+ {
+ /* We found a matching expression in the
+ wrong mode, but we don't have room to
+ store it in the array. Punt. This case
+ should be rare. */
+ break;
+ }
/* INSN sets CC_REG to a value equal to CC_SRC
with the right mode. We can simply delete
it. */
@@ -7851,8 +7859,16 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
further blocks and this block. */
if (insn == end)
{
- if (cse_cc_succs (e->dest, cc_reg, cc_src, false) != VOIDmode)
- found_equiv = true;
+ enum machine_mode submode;
+
+ submode = cse_cc_succs (e->dest, cc_reg, cc_src, false);
+ if (submode != VOIDmode)
+ {
+ if (submode != mode)
+ abort ();
+ found_equiv = true;
+ can_change_mode = false;
+ }
}
}
@@ -7916,6 +7932,7 @@ cse_condition_code_reg (void)
rtx cc_src_insn;
rtx cc_src;
enum machine_mode mode;
+ enum machine_mode orig_mode;
/* Look for blocks which end with a conditional jump based on a
condition code register. Then look for the instruction which
@@ -7972,12 +7989,15 @@ cse_condition_code_reg (void)
register is set, and CC_SRC is still meaningful at the end of
the basic block. */
+ orig_mode = GET_MODE (cc_src);
mode = cse_cc_succs (bb, cc_reg, cc_src, true);
- if (mode != GET_MODE (cc_src) && mode != VOIDmode)
+ if (mode != VOIDmode)
{
- PUT_MODE (cc_src, mode);
- cse_change_cc_mode_insns (cc_src_insn, NEXT_INSN (last_insn),
- gen_rtx_REG (mode, REGNO (cc_reg)));
+ if (mode != GET_MODE (cc_src))
+ abort ();
+ if (mode != orig_mode)
+ cse_change_cc_mode_insns (cc_src_insn, NEXT_INSN (last_insn),
+ gen_rtx_REG (mode, REGNO (cc_reg)));
}
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ed7cb61..dd33a2e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-01-24 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * gcc.dg/20040124-1.c: New test.
+
2004-01-24 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/20040123-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/20040124-1.c b/gcc/testsuite/gcc.dg/20040124-1.c
new file mode 100644
index 0000000..a508237
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20040124-1.c
@@ -0,0 +1,25 @@
+/* This code crashed with the cse_condition_code_reg() pass on i686. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int
+f1 (int a, int b)
+{
+ int i, j, k;
+
+ switch (b)
+ {
+ case (-9):
+ j = 4;
+ break;
+ case (-10):
+ j = 10;
+ break;
+ case (-8):
+ j = 15;
+ break;
+ }
+
+ i = f2 (f3 (b == (-9) ? k : a), j);
+
+ return 0;
+}