re PR target/9786 (Ice in fixup_abnormal_edges with -fnon-call-exceptions -O2)

PR target/9786
	* reg-stack.c (convert_regs_1): Purge possible dead eh edges
	after potential deletion of trapping insn. Avoids later ICE
	from call to fixup_abnormal_edges.
	(convert_regs_2): Stack the current block successors before
	processing this block, that is, before the potential deletion of
	dead edges by convert_regs_1, because these edges have been used
	to initialize the predecessors count.

From-SVN: r71644
This commit is contained in:
Eric Botcazou 2003-09-22 06:59:51 +00:00
parent 316b38c83c
commit de582cfbb9
4 changed files with 80 additions and 3 deletions

View file

@ -1,3 +1,14 @@
2003-09-22 Olivier Hainque <hainque@act-europe.fr>
PR target/9786
* reg-stack.c (convert_regs_1): Purge possible dead eh edges
after potential deletion of trapping insn. Avoids later ICE
from call to fixup_abnormal_edges.
(convert_regs_2): Stack the current block successors before
processing this block, that is, before the potential deletion of
dead edges by convert_regs_1, because these edges have been used
to initialize the predecessors count.
2003-09-22 Eric Botcazou <ebotcazou@libertysurf.fr>
* real.c: Fix several nits in the head comment.

View file

@ -2638,11 +2638,12 @@ convert_regs_1 (FILE *file, basic_block block)
{
struct stack_def regstack;
block_info bi = BLOCK_INFO (block);
int inserted, reg;
int deleted, inserted, reg;
rtx insn, next;
edge e, beste = NULL;
inserted = 0;
deleted = 0;
any_malformed_asm = false;
/* Find the edge we will copy stack from. It should be the most frequent
@ -2715,6 +2716,7 @@ convert_regs_1 (FILE *file, basic_block block)
print_stack (file, &regstack);
}
subst_stack_regs (insn, &regstack);
deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn));
}
}
while (next);
@ -2754,8 +2756,23 @@ convert_regs_1 (FILE *file, basic_block block)
nan);
insn = emit_insn_after (set, insn);
subst_stack_regs (insn, &regstack);
deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn));
}
}
/* Amongst the insns possibly deleted during the substitution process above,
might have been the only trapping insn in the block. We purge the now
possibly dead EH edges here to avoid an ICE from fixup_abnormal_edges,
called at the end of convert_regs. The order in which we process the
blocks ensures that we never delete an already processed edge.
??? We are normally supposed not to delete trapping insns, so we pretend
that the insns deleted above don't actually trap. It would have been
better to detect this earlier and avoid creating the EH edge in the first
place, still, but we don't have enough information at that time. */
if (deleted)
purge_dead_edges (block);
/* Something failed if the stack lives don't match. If we had malformed
asms, we zapped the instruction itself, but that didn't produce the
@ -2800,6 +2817,10 @@ convert_regs_2 (FILE *file, basic_block block)
basic_block *stack, *sp;
int inserted;
/* We process the blocks in a top-down manner, in a way such that one block
is only processed after all its predecessors. The number of predecessors
of every block has already been computed. */
stack = xmalloc (sizeof (*stack) * n_basic_blocks);
sp = stack;
@ -2811,9 +2832,13 @@ convert_regs_2 (FILE *file, basic_block block)
edge e;
block = *--sp;
inserted |= convert_regs_1 (file, block);
BLOCK_INFO (block)->done = 1;
/* Processing "block" is achieved by convert_regs_1, which may purge
some dead EH outgoing edge after the possible deletion of the
trapping insn inside the block. Since the number of predecessors of
"block"'s successors has been computed based on the initial edge set,
we check for the possiblity to process some of these successors
before such an edge deletion may happen. */
for (e = block->succ; e ; e = e->succ_next)
if (! (e->flags & EDGE_DFS_BACK))
{
@ -2821,6 +2846,9 @@ convert_regs_2 (FILE *file, basic_block block)
if (!BLOCK_INFO (e->dest)->predecessors)
*sp++ = e->dest;
}
inserted |= convert_regs_1 (file, block);
BLOCK_INFO (block)->done = 1;
}
while (sp != stack);

View file

@ -1,3 +1,7 @@
2003-09-22 Eric Botcazou <ebotcazou@libertysurf.fr>
* g++.dg/opt/reg-stack2.C: New test.
2003-09-21 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
* g++.dg/eh/delayslot1.C: New test.

View file

@ -0,0 +1,34 @@
// PR target/9786
// Origin: <nick@ilm.com>
// This used to fail on x86 because the reg-stack pass deleted
// an insn that could seemingly trap (but actually doesn't)
// without updating the CFG.
// { dg-do compile }
// { dg-options "-O2 -fnon-call-exceptions" }
struct D1 {
float l;
D1 GS() const {D1 d;float f=.299*l;d.l=f;return d;}
static D1 G() {return D1();}
};
struct D2 {
D1 g;
D2(const D1& gi) : g(gi) {}
D2 GS() const {return D2(g.GS());}
};
class A {
public:
virtual ~A() {}
};
class B : public A {
public:
B(const D2& mi);
D2 fm;
};
B::B(const D2 &mi) : fm(mi.GS()) {}