mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 06:50:27 +08:00
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
This commit is contained in:
parent
7eab6e7b91
commit
cb29234501
@ -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.
|
||||
|
@ -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,39 +1711,59 @@ 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:
|
||||
/* Clobber call-clobbered registers. */
|
||||
if (CALL_P (insn))
|
||||
|
@ -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
|
||||
|
34
gcc/testsuite/g++.dg/opt/pr25005.C
Normal file
34
gcc/testsuite/g++.dg/opt/pr25005.C
Normal file
@ -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]));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user