middle-end/102285 - refine .DEFERRED_INIT expansion

This refines the way we figure whether we are facing a register
that cannot be initialized by emitting a memset away from inspecting
expanded RTL of the LHS to using the predicates expand_assignment
is using to detect decls or MEM_REFs with non-memory DECL_RTL.

2021-10-04  Richard Biener  <rguenther@suse.de>

	* expr.h (non_mem_decl_p): Declare.
	(mem_ref_refers_to_non_mem_p): Likewise.
	* expr.c (non_mem_decl_p): Export.
	(mem_ref_refers_to_non_mem_p): Likewise.
	* internal-fn.c (expand_DEFERRED_INIT): Do not expand the LHS
	but check the base with mem_ref_refers_to_non_mem_p
	and non_mem_decl_p.

	* c-c++-common/pr102285.c: New testcase.
This commit is contained in:
Richard Biener 2021-10-04 11:34:27 +02:00
parent 55a3be2f52
commit 7e0c050080
4 changed files with 20 additions and 4 deletions

View File

@ -5305,7 +5305,7 @@ get_bit_range (poly_uint64_pod *bitstart, poly_uint64_pod *bitend, tree exp,
has non-BLKmode. DECL_RTL must not be a MEM; if
DECL_RTL was not set yet, return false. */
static inline bool
bool
non_mem_decl_p (tree base)
{
if (!DECL_P (base)
@ -5322,7 +5322,7 @@ non_mem_decl_p (tree base)
/* Returns true if REF refers to an object that does not
reside in memory and has non-BLKmode. */
static inline bool
bool
mem_ref_refers_to_non_mem_p (tree ref)
{
tree base;

View File

@ -346,4 +346,7 @@ extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
/* Return an rtx for the size in bytes of the value of an expr. */
extern rtx expr_size (tree);
extern bool mem_ref_refers_to_non_mem_p (tree);
extern bool non_mem_decl_p (tree);
#endif /* GCC_EXPR_H */

View File

@ -3015,8 +3015,11 @@ expand_DEFERRED_INIT (internal_fn, gcall *stmt)
reg_lhs = true;
else
{
rtx tem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
reg_lhs = !MEM_P (tem);
tree lhs_base = lhs;
while (handled_component_p (lhs_base))
lhs_base = TREE_OPERAND (lhs_base, 0);
reg_lhs = (mem_ref_refers_to_non_mem_p (lhs_base)
|| non_mem_decl_p (lhs_base));
}
if (!reg_lhs)

View File

@ -0,0 +1,10 @@
/* { dg-do compile } */
/* { dg-options "-O -ftrivial-auto-var-init=zero -Wuninitialized" } */
int
qy (void)
{
int tw = 4;
int fb[tw];
return fb[2]; /* { dg-warning "uninitialized" } */
}