This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR 58958: wrong aliasing info
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Marc Glisse <marc dot glisse at inria dot fr>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 4 Nov 2013 11:55:30 +0100
- Subject: Re: PR 58958: wrong aliasing info
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot DEB dot 2 dot 02 dot 1311012323530 dot 24250 at stedding dot saclay dot inria dot fr>
On Fri, Nov 1, 2013 at 11:39 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> the issue was described in the PR and the message linked from there.
> ao_ref_init_from_ptr_and_size calls get_ref_base_and_extent, which may
> detect an array_ref of variable index, but ao_ref_init_from_ptr_and_size
> never learns of it and uses the offset+size as if they were meaningful.
Well... it certainly learns of it, but it chooses to ignore...
if (TREE_CODE (ptr) == ADDR_EXPR)
- ref->base = get_ref_base_and_extent (TREE_OPERAND (ptr, 0),
- &ref->offset, &t1, &t2);
+ {
+ ref->base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (ptr, 0),
+ &t, 0, &safe);
+ ref->offset = BITS_PER_UNIT * t;
+ }
safe == (t1 != -1 && t1 == t2)
note that ao_ref_init_from_ptr_and_size gets the size fed in as argument
so I fail to see why it matters at all ...? That is, if you feed in a wrong
size then it's the callers error.
Richard.
> Bootstrap+testsuite on x86_64-unknown-linux-gnu.
>
> 2013-11-04 Marc Glisse <marc.glisse@inria.fr>
>
> PR tree-optimization/
> gcc/
> * tree-dfa.h (get_addr_base_and_unit_offset_1): Add error reporting.
> * tree-ssa-alias.c (ao_ref_init_from_ptr_and_size): Use
> get_addr_base_and_unit_offset_1 instead of get_ref_base_and_extent.
>
> gcc/testsuite/
> * gcc.dg/tree-ssa/pr58958.c: New file.
>
> --
> Marc Glisse
> Index: gcc/testsuite/gcc.dg/tree-ssa/pr58958.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/pr58958.c (revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/pr58958.c (working copy)
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +double a[10];
> +int f(int n){
> + a[3]=9;
> + __builtin_memset(&a[n],3,sizeof(double));
> + return a[3]==9;
> +}
> +
> +/* { dg-final { scan-tree-dump " == 9" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
>
> Property changes on: gcc/testsuite/gcc.dg/tree-ssa/pr58958.c
> ___________________________________________________________________
> Added: svn:keywords
> ## -0,0 +1 ##
> +Author Date Id Revision URL
> \ No newline at end of property
> Added: svn:eol-style
> ## -0,0 +1 ##
> +native
> \ No newline at end of property
> Index: gcc/tree-dfa.h
> ===================================================================
> --- gcc/tree-dfa.h (revision 204302)
> +++ gcc/tree-dfa.h (working copy)
> @@ -30,65 +30,70 @@ extern tree ssa_default_def (struct func
> extern void set_ssa_default_def (struct function *, tree, tree);
> extern tree get_or_create_ssa_default_def (struct function *, tree);
> extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
> HOST_WIDE_INT *, HOST_WIDE_INT *);
> extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *);
> extern bool stmt_references_abnormal_ssa_name (gimple);
> extern void dump_enumerated_decls (FILE *, int);
>
> /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET
> that
> denotes the starting address of the memory access EXP.
> - Returns NULL_TREE if the offset is not constant or any component
> - is not BITS_PER_UNIT-aligned.
> + If the offset is not constant or any component is not
> BITS_PER_UNIT-aligned,
> + sets *SAFE to false or returns NULL_TREE if SAFE is NULL.
> VALUEIZE if non-NULL is used to valueize SSA names. It should return
> its argument or a constant if the argument is known to be constant. */
> /* ??? This is a static inline here to avoid the overhead of the indirect
> calls
> to VALUEIZE. But is this overhead really that significant? And should
> we
> perhaps just rely on WHOPR to specialize the function? */
>
> static inline tree
> get_addr_base_and_unit_offset_1 (tree exp, HOST_WIDE_INT *poffset,
> - tree (*valueize) (tree))
> + tree (*valueize) (tree), bool *safe = NULL)
> {
> HOST_WIDE_INT byte_offset = 0;
> + bool issafe = true;
>
> /* Compute cumulative byte-offset for nested component-refs and
> array-refs,
> and find the ultimate containing object. */
> while (1)
> {
> switch (TREE_CODE (exp))
> {
> case BIT_FIELD_REF:
> {
> HOST_WIDE_INT this_off = TREE_INT_CST_LOW (TREE_OPERAND (exp,
> 2));
> if (this_off % BITS_PER_UNIT)
> - return NULL_TREE;
> - byte_offset += this_off / BITS_PER_UNIT;
> + issafe = false;
> + else
> + byte_offset += this_off / BITS_PER_UNIT;
> }
> break;
>
> case COMPONENT_REF:
> {
> tree field = TREE_OPERAND (exp, 1);
> tree this_offset = component_ref_field_offset (exp);
> HOST_WIDE_INT hthis_offset;
>
> if (!this_offset
> || TREE_CODE (this_offset) != INTEGER_CST
> || (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
> % BITS_PER_UNIT))
> - return NULL_TREE;
> -
> - hthis_offset = TREE_INT_CST_LOW (this_offset);
> - hthis_offset += (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET
> (field))
> - / BITS_PER_UNIT);
> - byte_offset += hthis_offset;
> + issafe = false;
> + else
> + {
> + hthis_offset = TREE_INT_CST_LOW (this_offset);
> + hthis_offset +=
> + (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field))
> + / BITS_PER_UNIT);
> + byte_offset += hthis_offset;
> + }
> }
> break;
>
> case ARRAY_REF:
> case ARRAY_RANGE_REF:
> {
> tree index = TREE_OPERAND (exp, 1);
> tree low_bound, unit_size;
>
> if (valueize
> @@ -102,21 +107,21 @@ get_addr_base_and_unit_offset_1 (tree ex
> && (unit_size = array_ref_element_size (exp),
> TREE_CODE (unit_size) == INTEGER_CST))
> {
> HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
>
> hindex -= TREE_INT_CST_LOW (low_bound);
> hindex *= TREE_INT_CST_LOW (unit_size);
> byte_offset += hindex;
> }
> else
> - return NULL_TREE;
> + issafe = false;
> }
> break;
>
> case REALPART_EXPR:
> break;
>
> case IMAGPART_EXPR:
> byte_offset += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE
> (exp)));
> break;
>
> @@ -148,37 +153,48 @@ get_addr_base_and_unit_offset_1 (tree ex
> {
> tree base = TREE_OPERAND (exp, 0);
> if (valueize
> && TREE_CODE (base) == SSA_NAME)
> base = (*valueize) (base);
>
> /* Hand back the decl for MEM[&decl, off]. */
> if (TREE_CODE (base) == ADDR_EXPR)
> {
> if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
> - return NULL_TREE;
> - if (!integer_zerop (TMR_OFFSET (exp)))
> + issafe = false;
> + else if (!integer_zerop (TMR_OFFSET (exp)))
> {
> double_int off = mem_ref_offset (exp);
> gcc_assert (off.high == -1 || off.high == 0);
> byte_offset += off.to_shwi ();
> }
> exp = TREE_OPERAND (base, 0);
> }
> goto done;
> }
>
> default:
> goto done;
> }
>
> exp = TREE_OPERAND (exp, 0);
> }
> done:
>
> - *poffset = byte_offset;
> - return exp;
> + if (issafe)
> + {
> + *poffset = byte_offset;
> + return exp;
> + }
> + else if (safe)
> + {
> + *safe = false;
> + *poffset = 0;
> + return exp;
> + }
> + else
> + return NULL_TREE;
> }
>
>
>
> #endif /* GCC_TREE_DFA_H */
> Index: gcc/tree-ssa-alias.c
> ===================================================================
> --- gcc/tree-ssa-alias.c (revision 204302)
> +++ gcc/tree-ssa-alias.c (working copy)
> @@ -559,49 +559,54 @@ ao_ref_alias_set (ao_ref *ref)
> }
>
> /* Init an alias-oracle reference representation from a gimple pointer
> PTR and a gimple size SIZE in bytes. If SIZE is NULL_TREE the the
> size is assumed to be unknown. The access is assumed to be only
> to or after of the pointer target, not before it. */
>
> void
> ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size)
> {
> - HOST_WIDE_INT t1, t2, extra_offset = 0;
> + HOST_WIDE_INT t, extra_offset = 0;
> + bool safe = true;
> ref->ref = NULL_TREE;
> if (TREE_CODE (ptr) == SSA_NAME)
> {
> gimple stmt = SSA_NAME_DEF_STMT (ptr);
> if (gimple_assign_single_p (stmt)
> && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
> ptr = gimple_assign_rhs1 (stmt);
> else if (is_gimple_assign (stmt)
> && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
> && host_integerp (gimple_assign_rhs2 (stmt), 0)
> - && (t1 = int_cst_value (gimple_assign_rhs2 (stmt))) >= 0)
> + && (t = int_cst_value (gimple_assign_rhs2 (stmt))) >= 0)
> {
> ptr = gimple_assign_rhs1 (stmt);
> - extra_offset = BITS_PER_UNIT * t1;
> + extra_offset = BITS_PER_UNIT * t;
> }
> }
>
> if (TREE_CODE (ptr) == ADDR_EXPR)
> - ref->base = get_ref_base_and_extent (TREE_OPERAND (ptr, 0),
> - &ref->offset, &t1, &t2);
> + {
> + ref->base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (ptr, 0),
> + &t, 0, &safe);
> + ref->offset = BITS_PER_UNIT * t;
> + }
> else
> {
> ref->base = build2 (MEM_REF, char_type_node,
> ptr, null_pointer_node);
> ref->offset = 0;
> }
> ref->offset += extra_offset;
> - if (size
> + if (safe
> + && size
> && host_integerp (size, 0)
> && TREE_INT_CST_LOW (size) * BITS_PER_UNIT / BITS_PER_UNIT
> == TREE_INT_CST_LOW (size))
> ref->max_size = ref->size = TREE_INT_CST_LOW (size) * BITS_PER_UNIT;
> else
> ref->max_size = ref->size = -1;
> ref->ref_alias_set = 0;
> ref->base_alias_set = 0;
> ref->volatile_p = false;
> }
>