This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFA][PATCH] Minor fix to aliasing machinery
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Jeff Law <law at redhat dot com>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 30 Oct 2013 17:14:34 +0100 (CET)
- Subject: Re: [RFA][PATCH] Minor fix to aliasing machinery
- Authentication-results: sourceware.org; auth=none
- References: <52702A5D dot 6030101 at redhat dot com> <alpine dot DEB dot 2 dot 10 dot 1310292254130 dot 4124 at laptop-mg dot saclay dot inria dot fr> <CAFiYyc1KVe0y0n2CwAwdV0hKG-RpPKXEE73gcanmP4mjGpxCYg at mail dot gmail dot com>
On Wed, 30 Oct 2013, Richard Biener wrote:
Btw, get_addr_base_and_unit_offset may also return an offsetted
MEM_REF (from &MEM [p_3, 17] for example). As we are interested in
pointers this could be handled by not requiring a memory reference
but extracting the base address and offset, covering more cases.
I tried the attached patch, and it almost worked, except for one fortran
testcase (widechar_intrinsics_10.f90):
! { dg-do run }
! { dg-options "-fbackslash" }
implicit none
character(kind=1,len=3) :: s1(3)
s1 = [ "abc", "def", "ghi" ]
if (any (cshift (s1, -1) /= [ s1(3), s1(1:2) ])) call abort
end
we end up with a double array_ref, one of variable index, and
get_ref_base_and_extent signals that by returning as size the size of the
whole declaration (the double-array). However,
ao_ref_init_from_ptr_and_size happily ignores the last two parameters of
get_ref_base_and_extent and continues as if nothing was wrong (I don't
know how to easily check that something went wrong either). Whether we
think this is a good/bad patch for memcpy, we have a latent bug that the
recent patches are making more visible.
--
Marc Glisse
Index: testsuite/gcc.dg/tree-ssa/alias-26.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/alias-26.c (revision 0)
+++ testsuite/gcc.dg/tree-ssa/alias-26.c (working copy)
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+void f (long *p) {
+ *p = 42;
+ p[4] = 42;
+ __builtin_memset (p, 0, 100);
+}
+
+/* { dg-final { scan-tree-dump-not "= 42" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Property changes on: testsuite/gcc.dg/tree-ssa/alias-26.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision URL
\ No newline at end of property
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c (revision 204199)
+++ tree-ssa-alias.c (working copy)
@@ -1982,23 +1982,24 @@ stmt_may_clobber_ref_p (gimple stmt, tre
return stmt_may_clobber_ref_p_1 (stmt, &r);
}
/* If STMT kills the memory reference REF return true, otherwise
return false. */
static bool
stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
{
/* For a must-alias check we need to be able to constrain
- the access properly. */
- ao_ref_base (ref);
- if (ref->max_size == -1)
+ the access properly.
+ FIXME: except for BUILTIN_FREE. */
+ if (!ao_ref_base (ref)
+ || ref->max_size == -1)
return false;
if (gimple_has_lhs (stmt)
&& TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
/* The assignment is not necessarily carried out if it can throw
and we can catch it in the current function where we could inspect
the previous value.
??? We only need to care about the RHS throwing. For aggregate
assignments or similar calls and non-call exceptions the LHS
might throw as well. */
@@ -2071,37 +2072,47 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref
case BUILT_IN_MEMPCPY:
case BUILT_IN_MEMMOVE:
case BUILT_IN_MEMSET:
case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMPCPY_CHK:
case BUILT_IN_MEMMOVE_CHK:
case BUILT_IN_MEMSET_CHK:
{
tree dest = gimple_call_arg (stmt, 0);
tree len = gimple_call_arg (stmt, 2);
- tree base = NULL_TREE;
- HOST_WIDE_INT offset = 0;
+ tree rbase = ref->base;
+ HOST_WIDE_INT roffset = ref->offset;
if (!host_integerp (len, 0))
return false;
- if (TREE_CODE (dest) == ADDR_EXPR)
- base = get_addr_base_and_unit_offset (TREE_OPERAND (dest, 0),
- &offset);
- else if (TREE_CODE (dest) == SSA_NAME)
- base = dest;
- if (base
- && base == ao_ref_base (ref))
+ ao_ref dref;
+ ao_ref_init_from_ptr_and_size (&dref, dest, len);
+ tree base = ao_ref_base (&dref);
+ HOST_WIDE_INT offset = dref.offset;
+ if (!base)
+ return false;
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ if (TREE_CODE (rbase) != MEM_REF)
+ return false;
+ // Compare pointers.
+ offset += BITS_PER_UNIT
+ * TREE_INT_CST_LOW (TREE_OPERAND (base, 1));
+ roffset += BITS_PER_UNIT
+ * TREE_INT_CST_LOW (TREE_OPERAND (rbase, 1));
+ base = TREE_OPERAND (base, 0);
+ rbase = TREE_OPERAND (rbase, 0);
+ }
+ if (base == rbase)
{
- HOST_WIDE_INT size = TREE_INT_CST_LOW (len);
- if (offset <= ref->offset / BITS_PER_UNIT
- && (offset + size
- >= ((ref->offset + ref->max_size + BITS_PER_UNIT - 1)
- / BITS_PER_UNIT)))
+ HOST_WIDE_INT size = BITS_PER_UNIT * TREE_INT_CST_LOW (len);
+ if (offset <= roffset
+ && offset + size >= (roffset + ref->max_size))
return true;
}
break;
}
case BUILT_IN_VA_END:
{
tree ptr = gimple_call_arg (stmt, 0);
if (TREE_CODE (ptr) == ADDR_EXPR)
{