Fix -fcompare-debug issue in purge_dead_edges [PR95080]

The following testcase fails with -fcompare-debug, the bug used to be latent
since introduction of -fcompare-debug.
The loop at the start of purge_dead_edges behaves differently between -g0
and -g - if the last insn is a DEBUG_INSN, then it skips not just
DEBUG_INSNs but also NOTEs until it finds some other real insn (or bb head),
while with -g0 it will not skip any NOTEs, so if we have
real_insn
note
debug_insn // not present with -g0
then with -g it might remove useless REG_EH_REGION from real_insn, while
with -g0 it will not.

Yet another option would be not skipping NOTE_P in the loop; I couldn't find
in history rationale for why it is done.

2020-05-13  Jakub Jelinek  <jakub@redhat.com>

	PR debug/95080
	* cfgrtl.c (purge_dead_edges): Skip over debug and note insns even
	if the last insn is a note.

	* g++.dg/opt/pr95080.C: New test.
This commit is contained in:
Jakub Jelinek 2020-05-13 11:22:37 +02:00
parent c0c39a765b
commit 18edc19544
4 changed files with 49 additions and 1 deletions

View File

@ -1,5 +1,9 @@
2020-05-13 Jakub Jelinek <jakub@redhat.com>
PR debug/95080
* cfgrtl.c (purge_dead_edges): Skip over debug and note insns even
if the last insn is a note.
PR tree-optimization/95060
* tree-ssa-math-opts.c (convert_mult_to_fma_1): Fold a NEGATE_EXPR
if it is the single use of the FMA internal builtin.

View File

@ -3100,7 +3100,7 @@ purge_dead_edges (basic_block bb)
bool found;
edge_iterator ei;
if (DEBUG_INSN_P (insn) && insn != BB_HEAD (bb))
if ((DEBUG_INSN_P (insn) || NOTE_P (insn)) && insn != BB_HEAD (bb))
do
insn = PREV_INSN (insn);
while ((DEBUG_INSN_P (insn) || NOTE_P (insn)) && insn != BB_HEAD (bb));

View File

@ -1,5 +1,8 @@
2020-05-13 Jakub Jelinek <jakub@redhat.com>
PR debug/95080
* g++.dg/opt/pr95080.C: New test.
PR tree-optimization/95060
* gcc.target/i386/avx512f-pr95060.c: New test.
* gcc.target/i386/fma_double_1.c: Adjust expected insn counts.

View File

@ -0,0 +1,41 @@
// PR debug/95080
// { dg-do compile }
// { dg-options "-Og -fcse-follow-jumps -fnon-call-exceptions -fcompare-debug" }
char *a;
void baz ();
static inline bool
bar ()
{
int j = a[0] - 1;
switch (j)
{
case 0:
case 2:
return true;
default:
return false;
}
}
static inline bool
foo ()
{
if (bar ())
baz ();
return 0;
}
struct S
{
int h;
~S ();
};
S::~S ()
{
if (a[0] == 0)
foo () != h;
}