>> @@ -671,11 +668,9 @@ convert_control_dep_chain_into_preds (vec<edge> >> *dep_chains, >> e = one_cd_chain[j]; >> guard_bb = e->src; >> gsi = gsi_last_bb (guard_bb); >> + /* Ignore empty BBs as they're basically forwarder blocks. */ >> if (gsi_end_p (gsi)) >> - { >> - has_valid_pred = false; >> - break; >> - } >> + continue; >> cond_stmt = gsi_stmt (gsi); >> if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2) >> /* Ignore EH edge. Can add assertion on the other edge's flag. */ > ISTM that you want to use empty_block_p (bb) && single_succ_p (bb) to > detect the forwarder block. Otherwise ISTM that labels and debug > statements would affect the uninit analysis.
We still need to check for gsi_end_p() because guard_bb can have no statements but be considered non empty according to empty_block_p(). This is the case with a seemingly empty basic block that actually has an incoming PHI. Jakub suggested the following patch which fixes the new ICE in the PR. I've adjusted the comments accordingly. OK?
gcc/ PR middle-end/81897 * tree-ssa-uninit.c (convert_control_dep_chain_into_preds): Skip empty blocks. diff --git a/gcc/testsuite/gcc.dg/uninit-pr81897-2.c b/gcc/testsuite/gcc.dg/uninit-pr81897-2.c new file mode 100644 index 00000000000..3960af454e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr81897-2.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-tree-ccp -Wmaybe-uninitialized" } */ + +int oo; + +void +pc (int *tt) +{ + int cf = 0; + + if (*tt != 0) + { + if (0) + { + int *qg; + int uj = 0; + + t6: + tt = &cf; + if (oo != 0) + { + ++uj; /* { dg-warning "may be used uninit" } */ + *qg = !!oo && !!uj; /* { dg-warning "may be used uninit" } */ + } + } + cf = 0; + goto t6; + } + + if (oo != 0) + { + *tt = 1; + goto t6; + } +} diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 38239476286..8ccbc85970a 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -669,9 +669,16 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains, e = one_cd_chain[j]; guard_bb = e->src; gsi = gsi_last_bb (guard_bb); - /* Ignore empty BBs as they're basically forwarder blocks. */ + /* Ignore empty forwarder blocks. */ if (empty_block_p (guard_bb) && single_succ_p (guard_bb)) continue; + /* An empty basic block here is likely a PHI, and is not one + of the cases we handle below. */ + if (gsi_end_p (gsi)) + { + has_valid_pred = false; + break; + } cond_stmt = gsi_stmt (gsi); if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2) /* Ignore EH edge. Can add assertion on the other edge's flag. */