Commit d0cc1b79 by Jakub Jelinek

cselib, reload: Fix cselib ICE on m68k/microblaze [PR94526]

The following testcase ICEs on m68k (and another one Jeff mailed me
privately on microblaze).
The problem is that reload creates two DEBUG_INSNs with the same
value of (plus:P (reg:P sp) (const_int 0)), we compute correctly the
same hash value for them, but then don't find them in the cselib hash table,
as rtx_equal_for_cselib_1 thinks it is different from (reg:P sp),
and trigger an assertion failure that requires that from two different debug
insns one doesn't add locations to VALUEs.

The patch has two fixes for this, each fixes the ICE on both targets
separately, but I think we want both.

The cselib.c change ensures that rtx_equal_for_cselib_1 considers
(value:P sp_derived_value) and (plus:P (reg:P sp) (const_int 0)) equivalent.

The reload1.c change makes sure we don't create those bogus plus 0
expressions.  I understand the reasons for creating them, but they don't
really apply to DEBUG_INSNs; we don't have validity matching there, all we
care is that the expressions aren't arbitrarily deep, but it is just fine
to fold x + 0 into just x in there.

2020-04-08  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/94526
	* cselib.c (autoinc_split): Handle e->val_rtx being SP_DERIVED_VALUE_P
	with zero offset.
	* reload1.c (eliminate_regs_1): Avoid creating
	(plus (reg) (const_int 0)) in DEBUG_INSNs.

	* gcc.dg/pr94526.c: New test.
parent f52eb4f9
2020-04-08 Jakub Jelinek <jakub@redhat.com> 2020-04-08 Jakub Jelinek <jakub@redhat.com>
PR middle-end/94526
* cselib.c (autoinc_split): Handle e->val_rtx being SP_DERIVED_VALUE_P
with zero offset.
* reload1.c (eliminate_regs_1): Avoid creating
(plus (reg) (const_int 0)) in DEBUG_INSNs.
PR tree-optimization/94524 PR tree-optimization/94524
* tree-vect-generic.c (expand_vector_divmod): If any elt of op1 is * tree-vect-generic.c (expand_vector_divmod): If any elt of op1 is
negative for signed TRUNC_MOD_EXPR, multiply with absolute value of negative for signed TRUNC_MOD_EXPR, multiply with absolute value of
......
...@@ -884,21 +884,29 @@ autoinc_split (rtx x, rtx *off, machine_mode memmode) ...@@ -884,21 +884,29 @@ autoinc_split (rtx x, rtx *off, machine_mode memmode)
else else
e = cselib_lookup (x, GET_MODE (x), 0, memmode); e = cselib_lookup (x, GET_MODE (x), 0, memmode);
if (e) if (e)
for (struct elt_loc_list *l = e->locs; l; l = l->next) {
if (GET_CODE (l->loc) == PLUS if (SP_DERIVED_VALUE_P (e->val_rtx)
&& GET_CODE (XEXP (l->loc, 0)) == VALUE && (*off == NULL_RTX || *off == const0_rtx))
&& SP_DERIVED_VALUE_P (XEXP (l->loc, 0))
&& CONST_INT_P (XEXP (l->loc, 1)))
{ {
if (*off == NULL_RTX) *off = NULL_RTX;
*off = XEXP (l->loc, 1); return e->val_rtx;
else
*off = plus_constant (Pmode, *off,
INTVAL (XEXP (l->loc, 1)));
if (*off == const0_rtx)
*off = NULL_RTX;
return XEXP (l->loc, 0);
} }
for (struct elt_loc_list *l = e->locs; l; l = l->next)
if (GET_CODE (l->loc) == PLUS
&& GET_CODE (XEXP (l->loc, 0)) == VALUE
&& SP_DERIVED_VALUE_P (XEXP (l->loc, 0))
&& CONST_INT_P (XEXP (l->loc, 1)))
{
if (*off == NULL_RTX)
*off = XEXP (l->loc, 1);
else
*off = plus_constant (Pmode, *off,
INTVAL (XEXP (l->loc, 1)));
if (*off == const0_rtx)
*off = NULL_RTX;
return XEXP (l->loc, 0);
}
}
} }
return x; return x;
} }
......
...@@ -2607,8 +2607,9 @@ eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn, ...@@ -2607,8 +2607,9 @@ eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn,
structure of the insn in a way that reload can't handle. structure of the insn in a way that reload can't handle.
We special-case the commonest situation in We special-case the commonest situation in
eliminate_regs_in_insn, so just replace a PLUS with a eliminate_regs_in_insn, so just replace a PLUS with a
PLUS here, unless inside a MEM. */ PLUS here, unless inside a MEM. In DEBUG_INSNs, it is
if (mem_mode != 0 always ok to replace a PLUS with just a REG. */
if ((mem_mode != 0 || (insn && DEBUG_INSN_P (insn)))
&& CONST_INT_P (XEXP (x, 1)) && CONST_INT_P (XEXP (x, 1))
&& known_eq (INTVAL (XEXP (x, 1)), -ep->previous_offset)) && known_eq (INTVAL (XEXP (x, 1)), -ep->previous_offset))
return ep->to_rtx; return ep->to_rtx;
......
2020-04-08 Jakub Jelinek <jakub@redhat.com> 2020-04-08 Jakub Jelinek <jakub@redhat.com>
PR middle-end/94526
* gcc.dg/pr94526.c: New test.
PR tree-optimization/94524 PR tree-optimization/94524
* gcc.c-torture/execute/pr94524-1.c: New test. * gcc.c-torture/execute/pr94524-1.c: New test.
* gcc.c-torture/execute/pr94524-2.c: New test. * gcc.c-torture/execute/pr94524-2.c: New test.
......
/* PR middle-end/94526 */
/* { dg-do compile } */
/* { dg-options "-O2 -g" } */
struct S { int val[8 * sizeof (int)]; };
void
foo (struct S *x)
{
struct S *a = x;
}
void baz (struct S);
void
bar (void)
{
struct S b;
foo (&b);
baz (b);
}
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