re PR rtl-optimization/61094 (-O3 insn Internal compiler error in copyprop_hardreg_forward_1, at regcprop.c:775)

PR rtl-optimization/61094
	* ree.c (combine_reaching_defs): Do not reextend an insn if it
	was marked as do_no_reextend.  If a copy is needed to eliminate
	an extension, then mark it as do_not_reextend.

	PR rtl-optimization/61094
	* g++.dg/pr61094: New test.

From-SVN: r211142
This commit is contained in:
Jeff Law 2014-06-02 13:12:08 -06:00 committed by Jeff Law
parent a2adad8b0f
commit 0d732cca67
4 changed files with 83 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2014-06-02 Jeff Law <law@redhat.com>
PR rtl-optimization/61094
* ree.c (combine_reaching_defs): Do not reextend an insn if it
was marked as do_no_reextend. If a copy is needed to eliminate
an extension, then mark it as do_not_reextend.
2014-06-02 Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64.md (set_fpcr): Drop ISB after FPCR write.

View File

@ -507,6 +507,8 @@ struct ATTRIBUTE_PACKED ext_modified
/* Kind of modification of the insn. */
ENUM_BITFIELD(ext_modified_kind) kind : 2;
unsigned int do_not_reextend : 1;
/* True if the insn is scheduled to be deleted. */
unsigned int deleted : 1;
};
@ -712,8 +714,10 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
register than the source operand, then additional restrictions
are needed. Note we have to handle cases where we have nested
extensions in the source operand. */
if (REGNO (SET_DEST (PATTERN (cand->insn)))
!= REGNO (get_extended_src_reg (SET_SRC (PATTERN (cand->insn)))))
bool copy_needed
= (REGNO (SET_DEST (PATTERN (cand->insn)))
!= REGNO (get_extended_src_reg (SET_SRC (PATTERN (cand->insn)))));
if (copy_needed)
{
/* In theory we could handle more than one reaching def, it
just makes the code to update the insn stream more complex. */
@ -722,7 +726,7 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
/* We require the candidate not already be modified. It may,
for example have been changed from a (sign_extend (reg))
into (zero_extend (sign_extend (reg)).
into (zero_extend (sign_extend (reg))).
Handling that case shouldn't be terribly difficult, but the code
here and the code to emit copies would need auditing. Until
@ -777,6 +781,31 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
|| reg_set_between_p (SET_DEST (PATTERN (cand->insn)),
def_insn, cand->insn))
return false;
/* We must be able to copy between the two registers. Generate,
recognize and verify constraints of the copy. Also fail if this
generated more than one insn.
This generates garbage since we throw away the insn when we're
done, only to recreate it later if this test was successful. */
start_sequence ();
rtx sub_rtx = *get_sub_rtx (def_insn);
rtx pat = PATTERN (cand->insn);
rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
REGNO (XEXP (SET_SRC (pat), 0)));
rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
REGNO (SET_DEST (pat)));
emit_move_insn (new_dst, new_src);
rtx insn = get_insns();
end_sequence ();
if (NEXT_INSN (insn))
return false;
if (recog_memoized (insn) == -1)
return false;
extract_insn (insn);
if (!constrain_operands (1))
return false;
}
@ -843,11 +872,15 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
fprintf (dump_file, "All merges were successful.\n");
FOR_EACH_VEC_ELT (state->modified_list, i, def_insn)
if (state->modified[INSN_UID (def_insn)].kind == EXT_MODIFIED_NONE)
state->modified[INSN_UID (def_insn)].kind
= (cand->code == ZERO_EXTEND
? EXT_MODIFIED_ZEXT : EXT_MODIFIED_SEXT);
{
ext_modified *modified = &state->modified[INSN_UID (def_insn)];
if (modified->kind == EXT_MODIFIED_NONE)
modified->kind = (cand->code == ZERO_EXTEND ? EXT_MODIFIED_ZEXT
: EXT_MODIFIED_SEXT);
if (copy_needed)
modified->do_not_reextend = 1;
}
return true;
}
else

View File

@ -1,3 +1,8 @@
2014-06-02 Jeff Law <law@redhat.com>
PR rtl-optimization/61094
* g++.dg/pr61094: New test.
2014-06-02 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/xop-rotate1-vector.c (dg-options): Add -mno-avx2.

View File

@ -0,0 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O3" } */
template <typename> struct A {
unsigned _width, _height, _depth, _spectrum;
template <typename t> A(t p1) {
int a = p1.size();
if (a) {
_width = p1._width;
_depth = _height = _spectrum = p1._spectrum;
}
}
long size() { return (long)_width * _height * _depth * _spectrum; }
};
int d;
void fn1(void *);
A<int> *fn2();
void fn3() {
int b;
for (;;) {
A<char> c(*fn2());
fn1(&c);
if (d || !b)
throw;
}
}