On Fri, 30 Mar 2012, Martin Jambor wrote: > Hi, > > when testing a patch of mine on sparc64-linux, I came across an Ada > bootstrap failure due to a structure DECL which was marked addressable > but had a register DECL_RTL (and therefore mem_ref_refers_to_non_mem_p > failed to trigger on it). > > Mode of the structure was TI (16 bytes int) and it was mistakenly > marked as addressable during expansion of an assignment statement in > which a 12 byte portion of it was copied to another structure with > BLKmode. Specifically, this happened because expand_assignment called > store_expr which loaded the required portion to temporary 12 byte > BLKmode MEM_P variable and then called emit_block_move from the > temporary to the destination. emit_block_move_hints then marked > MEM_EXPR of the temp as addressable because it handled the copy by > emitting a library call. And MEM_EXPR pointed to the DECL of the > source of the assignment which I believe is the bug, thus this patch > re-sets MEM_EXPR of temp in these cases. > > However, if anybody believes the main issue is elsewhere and another > component of this chain of events needs to be fixed, I'll be happy to > come up with another patch. so far this patch has passed bootstrap > and testing on x86_64-linux and helped my patch which uncovered this > issue to reach stage 3 of bootstrap. > > What do you think, is it OK for trunk?
Hmm, I think this should be done at the point we create the mem - where does that happen? Richard. > Thanks, > > Martin > > > 2012-03-30 Martin Jambor <mjam...@suse.cz> > > * expr.c (non_mem_decl_p): New function with half of previous > functionality of... > (mem_ref_refers_to_non_mem_p): ...this one. > (store_expr): Reset MEM_EXPR of temp if it refers to memory but the > original expression is based on a non-memory based declaration. > > Index: src/gcc/expr.c > =================================================================== > --- src.orig/gcc/expr.c > +++ src/gcc/expr.c > @@ -4479,6 +4479,24 @@ get_bit_range (unsigned HOST_WIDE_INT *b > *bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1; > } > > +/* Returns true if T is a DECL that does not reside in a memory and has a > + non-BLK mode. */ > + > +static bool > +non_mem_decl_p (tree t) > +{ > + if (!DECL_P (t)) > + return false; > + gcc_checking_assert (!TREE_ADDRESSABLE (t) > + || !DECL_RTL_SET_P (t) > + || MEM_P (DECL_RTL (t))); > + return (!TREE_ADDRESSABLE (t) > + && DECL_MODE (t) != BLKmode > + && DECL_RTL_SET_P (t) > + && !MEM_P (DECL_RTL (t))); > +} > + > + > /* Returns true if the MEM_REF REF refers to an object that does not > reside in memory and has non-BLKmode. */ > > @@ -4489,11 +4507,7 @@ mem_ref_refers_to_non_mem_p (tree ref) > if (TREE_CODE (base) != ADDR_EXPR) > return false; > base = TREE_OPERAND (base, 0); > - return (DECL_P (base) > - && !TREE_ADDRESSABLE (base) > - && DECL_MODE (base) != BLKmode > - && DECL_RTL_SET_P (base) > - && !MEM_P (DECL_RTL (base))); > + return non_mem_decl_p (base); > } > > /* Expand an assignment that stores the value of FROM into TO. If > NONTEMPORAL > @@ -5105,6 +5119,16 @@ store_expr (tree exp, rtx target, int ca > &alt_rtl); > } > > + /* When the original expression is a declaration not residing in memory but > + temp is a MEM RTX, we must dissociate it from the original expression or > + emit_block_move might mark it as addressable. */ > + if (MEM_P (temp)) > + { > + tree base = get_base_address (exp); > + if (base && non_mem_decl_p (base)) > + set_mem_expr (temp, NULL_TREE); > + } > + > /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not > the same as that of TARGET, adjust the constant. This is needed, for > example, in case it is a CONST_DOUBLE and we want only a word-sized > > -- Richard Guenther <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer