diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c index c46ac18fd9a..87a7a7a19c8 100644 --- a/gcc/testsuite/gcc.dg/pr81192.c +++ b/gcc/testsuite/gcc.dg/pr81192.c @@ -25,12 +25,16 @@ void __GIMPLE(ssa, startwith("pre")) fn2 () if (j_6(D) != _Literal (int)2147483647) goto __BB4; else - goto __BB5; + goto __BB9; __BB(4): iftmp2_8 = j_6(D) + _Literal (int)1; goto __BB5; + __BB(9): + iftmp2_8 = j_6(D) + _Literal (int)1; + goto __BB5; + __BB(5): b_lsm6_10 = _Literal (int)2147483647; goto __BB6; diff --git a/gcc/testsuite/gcc.dg/pr98845.c b/gcc/testsuite/gcc.dg/pr98845.c new file mode 100644 index 00000000000..074c979678f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98845.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-dce -fno-tree-dse" } */ + +int n; + +__attribute__ ((returns_twice)) void +foo (void); + +void +bar (void); + +void +quux (int x) +{ + if (x) + ++x; + else + { + if (n) + { + x = 1; + foo (); + } + else + bar (); + + if (n) + { + ++x; + ++n; + } + } +} diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc index d897970079c..857e91c206b 100644 --- a/gcc/tree-ssa-tail-merge.cc +++ b/gcc/tree-ssa-tail-merge.cc @@ -336,10 +336,13 @@ stmt_local_def (gimple *stmt) def_bb = gimple_bb (stmt); + bool any_use = false; FOR_EACH_IMM_USE_FAST (use_p, iter, val) { if (is_gimple_debug (USE_STMT (use_p))) continue; + + any_use = true; bb = gimple_bb (USE_STMT (use_p)); if (bb == def_bb) continue; @@ -351,6 +354,11 @@ stmt_local_def (gimple *stmt) return false; } + /* When there is no use avoid making the stmt live on other paths. + This can happen with DCE disabled or not done as seen in PR98845. */ + if (!any_use) + return false; + return true; }