Commit 42aa5124 by Richard Henderson Committed by Richard Henderson

re PR debug/50132 (ICE: in maybe_record_trace_start, at dwarf2cfi.c:2234 with…

re PR debug/50132 (ICE: in maybe_record_trace_start, at dwarf2cfi.c:2234 with -fno-asynchronous-unwind-tables and long double)

PR 50132
PR 49864
        * cfgcleanup.c (old_insns_match_p): Don't allow cross-jump for
        non-constant stack adjutment.
        * expr.c (find_args_size_adjust): Break out from ...
        (fixup_args_size_notes): ... here.
        * rtl.h (find_args_size_adjust): Declare.

From-SVN: r178084
parent 0ab71f30
2011-08-25 Richard Henderson <rth@redhat.com>
PR 50132
PR 49864
* cfgcleanup.c (old_insns_match_p): Don't allow cross-jump for
non-constant stack adjutment.
* expr.c (find_args_size_adjust): Break out from ...
(fixup_args_size_notes): ... here.
* rtl.h (find_args_size_adjust): Declare.
2011-08-25 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (isa): Add sse2, sse2_noavx, sse3,
......
......@@ -1081,13 +1081,22 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
/* ??? Do not allow cross-jumping between different stack levels. */
p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
if (p1)
if (p1 && p2)
{
p1 = XEXP (p1, 0);
if (p2)
p2 = XEXP (p2, 0);
if (!rtx_equal_p (p1, p2))
return dir_none;
/* ??? Worse, this adjustment had better be constant lest we
have differing incoming stack levels. */
if (!frame_pointer_needed
&& find_args_size_adjust (i1) == HOST_WIDE_INT_MIN)
return dir_none;
}
else if (p1 || p2)
return dir_none;
p1 = PATTERN (i1);
p2 = PATTERN (i2);
......
......@@ -3548,21 +3548,12 @@ mem_autoinc_base (rtx mem)
verified, via immediate operand or auto-inc. If the adjustment
cannot be trivially extracted, the return value is INT_MIN. */
int
fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
HOST_WIDE_INT
find_args_size_adjust (rtx insn)
{
int args_size = end_args_size;
bool saw_unknown = false;
rtx insn;
for (insn = last; insn != prev; insn = PREV_INSN (insn))
{
rtx dest, set, pat;
HOST_WIDE_INT this_delta = 0;
int i;
if (!NONDEBUG_INSN_P (insn))
continue;
pat = PATTERN (insn);
set = NULL;
......@@ -3572,7 +3563,7 @@ fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
/* We have to allow non-call_pop patterns for the case
of emit_single_push_insn of a TLS address. */
if (GET_CODE (pat) != PARALLEL)
continue;
return 0;
/* All call_pop have a stack pointer adjust in the parallel.
The call itself is always first, and the stack adjust is
......@@ -3588,7 +3579,7 @@ fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
}
/* We'd better have found the stack pointer adjust. */
if (i == 0)
continue;
return 0;
/* Fall through to process the extracted SET and DEST
as if it was a standalone insn. */
}
......@@ -3612,22 +3603,21 @@ fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
break;
/* We do not expect an auto-inc of the sp in the parallel. */
gcc_checking_assert (mem_autoinc_base (dest)
!= stack_pointer_rtx);
gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
!= stack_pointer_rtx);
}
if (i < 0)
continue;
return 0;
}
else
continue;
return 0;
dest = SET_DEST (set);
/* Look for direct modifications of the stack pointer. */
if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
{
gcc_assert (!saw_unknown);
/* Look for a trivial adjustment, otherwise assume nothing. */
/* Note that the SPU restore_stack_block pattern refers to
the stack pointer in V4SImode. Consider that non-trivial. */
......@@ -3635,44 +3625,74 @@ fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
&& GET_CODE (SET_SRC (set)) == PLUS
&& XEXP (SET_SRC (set), 0) == stack_pointer_rtx
&& CONST_INT_P (XEXP (SET_SRC (set), 1)))
this_delta = INTVAL (XEXP (SET_SRC (set), 1));
return INTVAL (XEXP (SET_SRC (set), 1));
/* ??? Reload can generate no-op moves, which will be cleaned
up later. Recognize it and continue searching. */
else if (rtx_equal_p (dest, SET_SRC (set)))
this_delta = 0;
return 0;
else
saw_unknown = true;
return HOST_WIDE_INT_MIN;
}
else
{
rtx mem, addr;
/* Otherwise only think about autoinc patterns. */
else if (mem_autoinc_base (dest) == stack_pointer_rtx)
if (mem_autoinc_base (dest) == stack_pointer_rtx)
{
rtx addr = XEXP (dest, 0);
gcc_assert (!saw_unknown);
mem = dest;
gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
!= stack_pointer_rtx);
}
else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
mem = SET_SRC (set);
else
return 0;
addr = XEXP (mem, 0);
switch (GET_CODE (addr))
{
case PRE_INC:
case POST_INC:
this_delta = GET_MODE_SIZE (GET_MODE (dest));
break;
return GET_MODE_SIZE (GET_MODE (mem));
case PRE_DEC:
case POST_DEC:
this_delta = -GET_MODE_SIZE (GET_MODE (dest));
break;
return -GET_MODE_SIZE (GET_MODE (mem));
case PRE_MODIFY:
case POST_MODIFY:
addr = XEXP (addr, 1);
gcc_assert (GET_CODE (addr) == PLUS);
gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
gcc_assert (CONST_INT_P (XEXP (addr, 1)));
this_delta = INTVAL (XEXP (addr, 1));
break;
return INTVAL (XEXP (addr, 1));
default:
gcc_unreachable ();
}
}
else
}
int
fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
{
int args_size = end_args_size;
bool saw_unknown = false;
rtx insn;
for (insn = last; insn != prev; insn = PREV_INSN (insn))
{
HOST_WIDE_INT this_delta;
if (!NONDEBUG_INSN_P (insn))
continue;
this_delta = find_args_size_adjust (insn);
if (this_delta == 0)
continue;
gcc_assert (!saw_unknown);
if (this_delta == HOST_WIDE_INT_MIN)
saw_unknown = true;
add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (args_size));
#ifdef STACK_GROWS_DOWNWARD
this_delta = -this_delta;
......
......@@ -2508,6 +2508,7 @@ extern void emit_jump (rtx);
/* In expr.c */
extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
unsigned int, int);
extern HOST_WIDE_INT find_args_size_adjust (rtx);
extern int fixup_args_size_notes (rtx, rtx, int);
/* In cfgrtl.c */
......
/* { dg-do compile } */
/* { dg-options "-Os -fno-asynchronous-unwind-tables -g" } */
void bar (long double n);
void foo (int c)
{
if (c)
bar (0);
}
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