Commit 11ef0b22 by Aldy Hernandez Committed by Jeff Law

re PR middle-end/81897 (spurious -Wmaybe-uninitialized warning)

	PR middle-end/81897
	* tree-ssa-uninit.c (compute_control_dep_chain): Do not bail on
	basic blocks with a small number of successors.
	(convert_control_dep_chain_into_preds): Improve handling of
	forwarder blocks.
	(dump_predicates): Split apart into...
	(dump_pred_chain): ...here...
	(dump_pred_info): ...and here.
	(can_one_predicate_be_invalidated_p): Add debugging printfs.
	(can_chain_union_be_invalidated_p): Improve check for invalidation
	of paths.
	(uninit_uses_cannot_happen): Avoid unnecessary if
	convert_control_dep_chain_into_preds yielded nothing.

	PR middle-end/81897
	* gcc.dg/uninit-pr81897.c: New test.

From-SVN: r256320
parent f59d4026
2018-01-06 Aldy Hernandez <aldyh@redhat.com>
PR middle-end/81897
* tree-ssa-uninit.c (compute_control_dep_chain): Do not bail on
basic blocks with a small number of successors.
(convert_control_dep_chain_into_preds): Improve handling of
forwarder blocks.
(dump_predicates): Split apart into...
(dump_pred_chain): ...here...
(dump_pred_info): ...and here.
(can_one_predicate_be_invalidated_p): Add debugging printfs.
(can_chain_union_be_invalidated_p): Improve check for invalidation
of paths.
(uninit_uses_cannot_happen): Avoid unnecessary if
convert_control_dep_chain_into_preds yielded nothing.
2018-01-06 Martin Sebor <msebor@redhat.com> 2018-01-06 Martin Sebor <msebor@redhat.com>
PR tree-optimization/83640 PR tree-optimization/83640
......
2018-01-06 Aldy Hernandez <aldyh@redhat.com>
PR middle-end/81897
* gcc.dg/uninit-pr81897.c: New test.
2018-01-06 Martin Sebor <msebor@redhat.com> 2018-01-06 Martin Sebor <msebor@redhat.com>
PR tree-optimization/83640 PR tree-optimization/83640
......
/* { dg-do compile } */
/* { dg-options "-O2 -Wuninitialized" } */
int f(void);
static inline void rcu_read_unlock(void)
{
static _Bool __warned;
if (f() && !__warned && !f()) {
__warned = 1;
}
}
int inet6_rtm_getroute(void)
{
int dst;
int fibmatch = f();
if (!fibmatch)
dst = f();
rcu_read_unlock();
if (fibmatch)
dst = 0;
return dst;
}
...@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa.h" #include "tree-ssa.h"
#include "params.h" #include "params.h"
#include "tree-cfg.h" #include "tree-cfg.h"
#include "cfghooks.h"
/* This implements the pass that does predicate aware warning on uses of /* This implements the pass that does predicate aware warning on uses of
possibly uninitialized variables. The pass first collects the set of possibly uninitialized variables. The pass first collects the set of
...@@ -543,9 +544,6 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb, ...@@ -543,9 +544,6 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
bool found_cd_chain = false; bool found_cd_chain = false;
size_t cur_chain_len = 0; size_t cur_chain_len = 0;
if (EDGE_COUNT (bb->succs) < 2)
return false;
if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS)) if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
return false; return false;
++*num_calls; ++*num_calls;
...@@ -671,11 +669,9 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains, ...@@ -671,11 +669,9 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
e = one_cd_chain[j]; e = one_cd_chain[j];
guard_bb = e->src; guard_bb = e->src;
gsi = gsi_last_bb (guard_bb); gsi = gsi_last_bb (guard_bb);
if (gsi_end_p (gsi)) /* Ignore empty BBs as they're basically forwarder blocks. */
{ if (empty_block_p (guard_bb) && single_succ_p (guard_bb))
has_valid_pred = false; continue;
break;
}
cond_stmt = gsi_stmt (gsi); cond_stmt = gsi_stmt (gsi);
if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2) if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2)
/* Ignore EH edge. Can add assertion on the other edge's flag. */ /* Ignore EH edge. Can add assertion on the other edge's flag. */
...@@ -916,38 +912,49 @@ find_def_preds (pred_chain_union *preds, gphi *phi) ...@@ -916,38 +912,49 @@ find_def_preds (pred_chain_union *preds, gphi *phi)
return has_valid_pred; return has_valid_pred;
} }
/* Dump a pred_info. */
static void
dump_pred_info (pred_info one_pred)
{
if (one_pred.invert)
fprintf (dump_file, " (.NOT.) ");
print_generic_expr (dump_file, one_pred.pred_lhs);
fprintf (dump_file, " %s ", op_symbol_code (one_pred.cond_code));
print_generic_expr (dump_file, one_pred.pred_rhs);
}
/* Dump a pred_chain. */
static void
dump_pred_chain (pred_chain one_pred_chain)
{
size_t np = one_pred_chain.length ();
for (size_t j = 0; j < np; j++)
{
dump_pred_info (one_pred_chain[j]);
if (j < np - 1)
fprintf (dump_file, " (.AND.) ");
else
fprintf (dump_file, "\n");
}
}
/* Dumps the predicates (PREDS) for USESTMT. */ /* Dumps the predicates (PREDS) for USESTMT. */
static void static void
dump_predicates (gimple *usestmt, pred_chain_union preds, const char *msg) dump_predicates (gimple *usestmt, pred_chain_union preds, const char *msg)
{ {
size_t i, j;
pred_chain one_pred_chain = vNULL;
fprintf (dump_file, "%s", msg); fprintf (dump_file, "%s", msg);
print_gimple_stmt (dump_file, usestmt, 0); if (usestmt)
fprintf (dump_file, "is guarded by :\n\n"); {
print_gimple_stmt (dump_file, usestmt, 0);
fprintf (dump_file, "is guarded by :\n\n");
}
size_t num_preds = preds.length (); size_t num_preds = preds.length ();
/* Do some dumping here: */ for (size_t i = 0; i < num_preds; i++)
for (i = 0; i < num_preds; i++)
{ {
size_t np; dump_pred_chain (preds[i]);
one_pred_chain = preds[i];
np = one_pred_chain.length ();
for (j = 0; j < np; j++)
{
pred_info one_pred = one_pred_chain[j];
if (one_pred.invert)
fprintf (dump_file, " (.NOT.) ");
print_generic_expr (dump_file, one_pred.pred_lhs);
fprintf (dump_file, " %s ", op_symbol_code (one_pred.cond_code));
print_generic_expr (dump_file, one_pred.pred_rhs);
if (j < np - 1)
fprintf (dump_file, " (.AND.) ");
else
fprintf (dump_file, "\n");
}
if (i < num_preds - 1) if (i < num_preds - 1)
fprintf (dump_file, "(.OR.)\n"); fprintf (dump_file, "(.OR.)\n");
else else
...@@ -2259,12 +2266,19 @@ normalize_preds (pred_chain_union preds, gimple *use_or_def, bool is_use) ...@@ -2259,12 +2266,19 @@ normalize_preds (pred_chain_union preds, gimple *use_or_def, bool is_use)
} }
/* Return TRUE if PREDICATE can be invalidated by any individual /* Return TRUE if PREDICATE can be invalidated by any individual
predicate in WORKLIST. */ predicate in USE_GUARD. */
static bool static bool
can_one_predicate_be_invalidated_p (pred_info predicate, can_one_predicate_be_invalidated_p (pred_info predicate,
pred_chain use_guard) pred_chain use_guard)
{ {
if (dump_file && dump_flags & TDF_DETAILS)
{
fprintf (dump_file, "Testing if this predicate: ");
dump_pred_info (predicate);
fprintf (dump_file, "\n...can be invalidated by a USE guard of: ");
dump_pred_chain (use_guard);
}
for (size_t i = 0; i < use_guard.length (); ++i) for (size_t i = 0; i < use_guard.length (); ++i)
{ {
/* NOTE: This is a very simple check, and only understands an /* NOTE: This is a very simple check, and only understands an
...@@ -2273,7 +2287,15 @@ can_one_predicate_be_invalidated_p (pred_info predicate, ...@@ -2273,7 +2287,15 @@ can_one_predicate_be_invalidated_p (pred_info predicate,
invalidate with say [i > 5] or [i == 8]. There is certainly invalidate with say [i > 5] or [i == 8]. There is certainly
room for improvement here. */ room for improvement here. */
if (pred_neg_p (predicate, use_guard[i])) if (pred_neg_p (predicate, use_guard[i]))
return true; {
if (dump_file && dump_flags & TDF_DETAILS)
{
fprintf (dump_file, " Predicate was invalidated by: ");
dump_pred_info (use_guard[i]);
fputc ('\n', dump_file);
}
return true;
}
} }
return false; return false;
} }
...@@ -2287,12 +2309,22 @@ can_chain_union_be_invalidated_p (pred_chain_union uninit_pred, ...@@ -2287,12 +2309,22 @@ can_chain_union_be_invalidated_p (pred_chain_union uninit_pred,
{ {
if (uninit_pred.is_empty ()) if (uninit_pred.is_empty ())
return false; return false;
if (dump_file && dump_flags & TDF_DETAILS)
dump_predicates (NULL, uninit_pred,
"Testing if anything here can be invalidated: ");
for (size_t i = 0; i < uninit_pred.length (); ++i) for (size_t i = 0; i < uninit_pred.length (); ++i)
{ {
pred_chain c = uninit_pred[i]; pred_chain c = uninit_pred[i];
for (size_t j = 0; j < c.length (); ++j) size_t j;
if (!can_one_predicate_be_invalidated_p (c[j], use_guard)) for (j = 0; j < c.length (); ++j)
return false; if (can_one_predicate_be_invalidated_p (c[j], use_guard))
break;
/* If we were unable to invalidate any predicate in C, then there
is a viable path from entry to the PHI where the PHI takes
an uninitialized value and continues to a use of the PHI. */
if (j == c.length ())
return false;
} }
return true; return true;
} }
...@@ -2334,7 +2366,7 @@ uninit_uses_cannot_happen (gphi *phi, unsigned uninit_opnds, ...@@ -2334,7 +2366,7 @@ uninit_uses_cannot_happen (gphi *phi, unsigned uninit_opnds,
/* Build the control dependency chain for uninit operand `i'... */ /* Build the control dependency chain for uninit operand `i'... */
uninit_preds = vNULL; uninit_preds = vNULL;
if (!compute_control_dep_chain (find_dom (e->src), if (!compute_control_dep_chain (ENTRY_BLOCK_PTR_FOR_FN (cfun),
e->src, dep_chains, &num_chains, e->src, dep_chains, &num_chains,
&cur_chain, &num_calls)) &cur_chain, &num_calls))
{ {
...@@ -2342,10 +2374,16 @@ uninit_uses_cannot_happen (gphi *phi, unsigned uninit_opnds, ...@@ -2342,10 +2374,16 @@ uninit_uses_cannot_happen (gphi *phi, unsigned uninit_opnds,
break; break;
} }
/* ...and convert it into a set of predicates. */ /* ...and convert it into a set of predicates. */
convert_control_dep_chain_into_preds (dep_chains, num_chains, bool has_valid_preds
&uninit_preds); = convert_control_dep_chain_into_preds (dep_chains, num_chains,
&uninit_preds);
for (size_t j = 0; j < num_chains; ++j) for (size_t j = 0; j < num_chains; ++j)
dep_chains[j].release (); dep_chains[j].release ();
if (!has_valid_preds)
{
ret = false;
break;
}
simplify_preds (&uninit_preds, NULL, false); simplify_preds (&uninit_preds, NULL, false);
uninit_preds = normalize_preds (uninit_preds, NULL, false); uninit_preds = normalize_preds (uninit_preds, NULL, false);
......
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