diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-12-23 10:43:36 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-12-23 10:43:36 +0100 |
commit | cb29234501cd27d2d78a4a3040cc6a0890c96b32 (patch) | |
tree | df4e9bbf3472530f8b153c1b519009b9a1e5a557 | |
parent | 7eab6e7b91cdf2dbd17595eac46173e3ce65dd84 (diff) | |
download | gcc-cb29234501cd27d2d78a4a3040cc6a0890c96b32.zip gcc-cb29234501cd27d2d78a4a3040cc6a0890c96b32.tar.gz gcc-cb29234501cd27d2d78a4a3040cc6a0890c96b32.tar.bz2 |
re PR target/25005 (ICE in extract_constrain_insn_cached, at recog.c:2002)
PR target/25005
* regrename.c (replace_oldest_value_reg): Use validate_change with
IN_GROUP set to 1 instead of doing direct modifications.
(copyprop_hardreg_forward_1): Likewise. If any replace_oldest_*
replacements have been performed on an instruction, use
apply_change_group ().
* g++.dg/opt/pr25005.C: New test.
From-SVN: r109013
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/regrename.c | 49 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr25005.C | 34 |
4 files changed, 84 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b64d26..524b84a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-12-23 Jakub Jelinek <jakub@redhat.com> + + PR target/25005 + * regrename.c (replace_oldest_value_reg): Use validate_change with + IN_GROUP set to 1 instead of doing direct modifications. + (copyprop_hardreg_forward_1): Likewise. If any replace_oldest_* + replacements have been performed on an instruction, use + apply_change_group (). + 2005-12-23 Hans-Peter Nilsson <hp@axis.com> * config/cris/arit.c (do_31div): Clarify what "31" refers to. diff --git a/gcc/regrename.c b/gcc/regrename.c index c9e1ac5..a73e5f7 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -1408,7 +1408,7 @@ replace_oldest_value_reg (rtx *loc, enum reg_class cl, rtx insn, fprintf (dump_file, "insn %u: replaced reg %u with %u\n", INSN_UID (insn), REGNO (*loc), REGNO (new)); - *loc = new; + validate_change (insn, loc, new, 1); return true; } return false; @@ -1574,8 +1574,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) { int n_ops, i, alt, predicated; - bool is_asm; + bool is_asm, any_replacements; rtx set; + bool replaced[MAX_RECOG_OPERANDS]; if (! INSN_P (insn)) { @@ -1687,11 +1688,13 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) } no_move_special_case: + any_replacements = false; + /* For each input operand, replace a hard register with the eldest live copy that's in an appropriate register class. */ for (i = 0; i < n_ops; i++) { - bool replaced = false; + replaced[i] = false; /* Don't scan match_operand here, since we've no reg class information to pass down. Any operands that we could @@ -1708,37 +1711,57 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) if (recog_data.operand_type[i] == OP_IN) { if (recog_op_alt[i][alt].is_address) - replaced + replaced[i] = replace_oldest_value_addr (recog_data.operand_loc[i], recog_op_alt[i][alt].cl, VOIDmode, insn, vd); else if (REG_P (recog_data.operand[i])) - replaced + replaced[i] = replace_oldest_value_reg (recog_data.operand_loc[i], recog_op_alt[i][alt].cl, insn, vd); else if (MEM_P (recog_data.operand[i])) - replaced = replace_oldest_value_mem (recog_data.operand[i], - insn, vd); + replaced[i] = replace_oldest_value_mem (recog_data.operand[i], + insn, vd); } else if (MEM_P (recog_data.operand[i])) - replaced = replace_oldest_value_mem (recog_data.operand[i], - insn, vd); + replaced[i] = replace_oldest_value_mem (recog_data.operand[i], + insn, vd); /* If we performed any replacement, update match_dups. */ - if (replaced) + if (replaced[i]) { int j; rtx new; - changed = true; - new = *recog_data.operand_loc[i]; recog_data.operand[i] = new; for (j = 0; j < recog_data.n_dups; j++) if (recog_data.dup_num[j] == i) - *recog_data.dup_loc[j] = new; + validate_change (insn, recog_data.dup_loc[j], new, 1); + + any_replacements = true; + } + } + + if (any_replacements) + { + if (! apply_change_group ()) + { + for (i = 0; i < n_ops; i++) + if (replaced[i]) + { + rtx old = *recog_data.operand_loc[i]; + recog_data.operand[i] = old; + } + + if (dump_file) + fprintf (dump_file, + "insn %u: reg replacements not verified\n", + INSN_UID (insn)); } + else + changed = true; } did_replacement: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 87557d8..a61ab6f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-12-23 Jakub Jelinek <jakub@redhat.com> + + PR target/25005 + * g++.dg/opt/pr25005.C: New test. + 2005-12-22 Mark Mitchell <mark@codesourcery.com> PR c++/25369 diff --git a/gcc/testsuite/g++.dg/opt/pr25005.C b/gcc/testsuite/g++.dg/opt/pr25005.C new file mode 100644 index 0000000..f62f8a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr25005.C @@ -0,0 +1,34 @@ +// PR target/25005 +// { dg-options "-O2 -funroll-loops" } +// { dg-do compile } + +inline void *operator new (__SIZE_TYPE__, void *__p) throw() { return __p; } + +struct M { ~M() { } }; + +struct P +{ + P () { v[0] = 0; v[1] = 0; v[2] = 0; } + P (const P &x) { for (int i = 0; i < 3; ++i) v[i] = x.v[i]; } + double v[3]; +}; + +struct V : public M +{ + V (const P *x, const P *y) + { + P *b = this->a = ::new P[2]; + for (; x != y; ++x, ++b) + ::new (b) P(*x); + } + P *a; +}; + +void bar (const V &); + +void +foo () +{ + const P d[2] = { P(), P() }; + bar (V (&d[0], &d[2])); +} |