From 960670fc656e0024b5843553a8d536d387048610 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 24 Jan 2004 20:54:58 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76522 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++++ gcc/cse.c | 48 +++++++++++++++++++++++++++------------ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/20040124-1.c | 25 ++++++++++++++++++++ 4 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20040124-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 54e0d4f1d84..6aad8de208b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-01-24 Ian Lance Taylor + + 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 * emit-rtl.c (change_address, adjust_address_1, offset_address, diff --git a/gcc/cse.c b/gcc/cse.c index 90c67c05f17..266170ba353 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 ed7cb61ae4c..dd33a2e2f2d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-01-24 Ian Lance Taylor + + * gcc.dg/20040124-1.c: New test. + 2004-01-24 Jakub Jelinek * 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 00000000000..a508237eddd --- /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; +} -- 2.11.0