tree-optimization/105562 - avoid uninit diagnostic with better FRE

We can avoid some uninit diagnostics by making FRE disambiguate
against CLOBBERs since any aliasing there would invoke undefined
behavior for a read we are looking up.

2022-05-12  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/105562
	* tree-ssa-sccvn.cc (vn_reference_lookup_3): Disambiguate
	against all CLOBBER defs if there's not an obvious must-alias
	and we are not doing redundant store elimination.
	(vn_walk_cb_data::redundant_store_removal_p): New field.
	(vn_reference_lookup_pieces): Initialize it.
	(vn_reference_lookup): Add argument to specify if we are
	doing redundant store removal.
	(eliminate_dom_walker::eliminate_stmt): Specify we do.
	* tree-ssa-sccvn.h (vn_reference_lookup): Adjust.

	* g++.dg/warn/uninit-pr105562.C: New testcase.
This commit is contained in:
Richard Biener 2022-05-12 12:13:29 +02:00
parent 78c8b0b980
commit 94b8a37fa1
3 changed files with 40 additions and 9 deletions

View File

@ -0,0 +1,10 @@
// { dg-require-effective-target c++11 }
// { dg-options "-O -Wall -fno-strict-aliasing" }
#include <regex>
int main()
{
std::regex a(".");
std::regex b(std::move(a));
}

View File

@ -1799,11 +1799,13 @@ struct pd_data
struct vn_walk_cb_data
{
vn_walk_cb_data (vn_reference_t vr_, tree orig_ref_, tree *last_vuse_ptr_,
vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_)
vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_,
bool redundant_store_removal_p_)
: vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
mask (mask_), masked_result (NULL_TREE), vn_walk_kind (vn_walk_kind_),
tbaa_p (tbaa_p_), saved_operands (vNULL), first_set (-2),
first_base_set (-2), known_ranges (NULL)
tbaa_p (tbaa_p_), redundant_store_removal_p (redundant_store_removal_p_),
saved_operands (vNULL), first_set (-2), first_base_set (-2),
known_ranges (NULL)
{
if (!last_vuse_ptr)
last_vuse_ptr = &last_vuse;
@ -1862,6 +1864,7 @@ struct vn_walk_cb_data
tree masked_result;
vn_lookup_kind vn_walk_kind;
bool tbaa_p;
bool redundant_store_removal_p;
vec<vn_reference_op_s> saved_operands;
/* The VDEFs of partial defs we come along. */
@ -2620,6 +2623,19 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
return NULL;
}
/* When the def is a CLOBBER we can optimistically disambiguate
against it since any overlap it would be undefined behavior.
Avoid this for obvious must aliases to save compile-time though.
We also may not do this when the query is used for redundant
store removal. */
if (!data->redundant_store_removal_p
&& gimple_clobber_p (def_stmt)
&& !operand_equal_p (ao_ref_base (&lhs_ref), base, OEP_ADDRESS_OF))
{
*disambiguate_only = TR_DISAMBIGUATE;
return NULL;
}
/* Besides valueizing the LHS we can also use access-path based
disambiguation on the original non-valueized ref. */
if (!ref->ref
@ -3604,7 +3620,8 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set,
{
ao_ref r;
unsigned limit = param_sccvn_max_alias_queries_per_access;
vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE);
vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true, NULL_TREE,
false);
vec<vn_reference_op_s> ops_for_ref;
if (!valueized_p)
ops_for_ref = vr1.operands;
@ -3649,12 +3666,14 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set,
MASK is either NULL_TREE, or can be an INTEGER_CST if the result of the
load is bitwise anded with MASK and so we are only interested in a subset
of the bits and can ignore if the other bits are uninitialized or
not initialized with constants. */
not initialized with constants. When doing redundant store removal
the caller has to set REDUNDANT_STORE_REMOVAL_P. */
tree
vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vn_reference_t *vnresult, bool tbaa_p,
tree *last_vuse_ptr, tree mask)
tree *last_vuse_ptr, tree mask,
bool redundant_store_removal_p)
{
vec<vn_reference_op_s> operands;
struct vn_reference_s vr1;
@ -3732,7 +3751,8 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vr1.type, ops_for_ref))
ao_ref_init (&r, op);
vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
last_vuse_ptr, kind, tbaa_p, mask);
last_vuse_ptr, kind, tbaa_p, mask,
redundant_store_removal_p);
wvnresult
= ((vn_reference_t)
@ -6592,7 +6612,8 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
tree val = NULL_TREE;
if (lookup_lhs)
val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt),
VN_WALKREWRITE, &vnresult, false);
VN_WALKREWRITE, &vnresult, false,
NULL, NULL_TREE, true);
if (TREE_CODE (rhs) == SSA_NAME)
rhs = VN_INFO (rhs)->valnum;
if (val

View File

@ -265,7 +265,7 @@ tree vn_reference_lookup_pieces (tree, alias_set_type, alias_set_type, tree,
vec<vn_reference_op_s> ,
vn_reference_t *, vn_lookup_kind);
tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *, bool,
tree * = NULL, tree = NULL_TREE);
tree * = NULL, tree = NULL_TREE, bool = false);
void vn_reference_lookup_call (gcall *, vn_reference_t *, vn_reference_t);
vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, alias_set_type,
tree, vec<vn_reference_op_s>,