Commit 0d732cca by Jeff Law Committed by Jeff Law

re PR rtl-optimization/61094 (-O3 insn Internal compiler error in…

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
parent a2adad8b
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.
......
......@@ -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
......
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.
......
/* { 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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment