re PR rtl-optimization/60131 (RTL check fail in rhs_regno)

PR rtl-optimization/60131
	* ree.c (get_extended_src_reg): New function.
	(combine_reaching_defs): Use it rather than assuming location
	of REG.
	(find_and_remove_re): Verify first operand of extension is
	a REG before adding the insns to the copy list.

	PR rtl-optimization/60131
	* g++.dg/torture/pr60131.C: New test.

From-SVN: r207792
This commit is contained in:
Jeff Law 2014-02-14 13:26:31 -07:00 committed by Jeff Law
parent 88f7c49a8b
commit 059742a47f
4 changed files with 67 additions and 7 deletions

View File

@ -1,3 +1,12 @@
2014-02-14 Jeff Law <law@redhat.com>
PR rtl-optimization/60131
* ree.c (get_extended_src_reg): New function.
(combine_reaching_defs): Use it rather than assuming location
of REG.
(find_and_remove_re): Verify first operand of extension is
a REG before adding the insns to the copy list.
2014-02-14 Roland McGrath <mcgrathr@google.com>
* configure.ac (HAVE_AS_IX86_UD2): New test for 'ud2' mnemonic.

View File

@ -670,6 +670,18 @@ merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
return false;
}
/* Given SRC, which should be one or more extensions of a REG, strip
away the extensions and return the REG. */
static inline rtx
get_extended_src_reg (rtx src)
{
while (GET_CODE (src) == SIGN_EXTEND || GET_CODE (src) == ZERO_EXTEND)
src = XEXP (src, 0);
gcc_assert (REG_P (src));
return src;
}
/* This function goes through all reaching defs of the source
of the candidate for elimination (CAND) and tries to combine
the extension with the definition instruction. The changes
@ -698,17 +710,23 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
/* If the destination operand of the extension is a different
register than the source operand, then additional restrictions
are needed. */
if ((REGNO (SET_DEST (PATTERN (cand->insn)))
!= REGNO (XEXP (SET_SRC (PATTERN (cand->insn)), 0))))
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)))))
{
/* In theory we could handle more than one reaching def, it
just makes the code to update the insn stream more complex. */
if (state->defs_list.length () != 1)
return false;
/* We require the candidate not already be modified. This may
be overly conservative. */
/* 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)).
Handling that case shouldn't be terribly difficult, but the code
here and the code to emit copies would need auditing. Until
we see a need, this is the safe thing to do. */
if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
return false;
@ -999,8 +1017,13 @@ find_and_remove_re (void)
if (dump_file)
fprintf (dump_file, "Eliminated the extension.\n");
num_realized++;
if (REGNO (SET_DEST (PATTERN (curr_cand->insn)))
!= REGNO (XEXP (SET_SRC (PATTERN (curr_cand->insn)), 0)))
/* If the RHS of the current candidate is not (extend (reg)), then
we do not allow the optimization of extensions where
the source and destination registers do not match. Thus
checking REG_P here is correct. */
if (REG_P (XEXP (SET_SRC (PATTERN (curr_cand->insn)), 0))
&& (REGNO (SET_DEST (PATTERN (curr_cand->insn)))
!= REGNO (XEXP (SET_SRC (PATTERN (curr_cand->insn)), 0))))
{
reinsn_copy_list.safe_push (curr_cand->insn);
reinsn_copy_list.safe_push (state.defs_list[0]);

View File

@ -1,3 +1,8 @@
2014-02-14 Jeff Law <law@redhat.com>
PR rtl-optimization/60131
* g++.dg/torture/pr60131.C: New test.
2014-02-14 Ian Bolton <ian.bolton@arm.com>
* gcc.target/arm/pr59858.c: Skip if -mfloat-abi=hard specified

View File

@ -0,0 +1,23 @@
// { dg-do compile }
struct A { short a; };
int **b;
unsigned long c;
bool foo ();
unsigned bar (unsigned i);
extern void baz () __attribute__((noreturn));
int *
test (unsigned x, struct A *y)
{
unsigned v;
if (foo () || y[x].a == -1)
{
c = bar (x);
return 0;
}
v = y[x].a;
if (v >= 23)
baz ();
return b[v];
}