Patchwork [RFA] Minor fix to aliasing machinery

login
register
mail settings
Submitter Marc Glisse
Date Nov. 8, 2013, 11:18 p.m.
Message ID <alpine.DEB.2.02.1311090010290.7142@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/289938/
State New
Headers show

Comments

Marc Glisse - Nov. 8, 2013, 11:18 p.m.
On Wed, 6 Nov 2013, Richard Biener wrote:

> So the only thing that remains is the mem_ref_offset thing and yes, I guess
> I'd prefer to use double-ints because we deal with bit offsets in the end.

Here it is (bootstrap+testsuite on x86_64-unknown-linux-gnu). It feels
rather artificial to do this small bit of computation with double_int
when so much else assumes HWI is enough, but why not...

2013-11-09  Marc Glisse  <marc.glisse@inria.fr>
             Jeff Law  <law@redhat.com>

gcc/
         * tree-ssa-alias.c (stmt_kills_ref_p_1): Use
         ao_ref_init_from_ptr_and_size for builtins.

gcc/testsuite/
         * gcc.dg/tree-ssa/alias-27.c: New testcase.
Richard Guenther - Nov. 11, 2013, 11:42 a.m.
On Sat, Nov 9, 2013 at 12:18 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Wed, 6 Nov 2013, Richard Biener wrote:
>
>> So the only thing that remains is the mem_ref_offset thing and yes, I
>> guess
>> I'd prefer to use double-ints because we deal with bit offsets in the end.
>
>
> Here it is (bootstrap+testsuite on x86_64-unknown-linux-gnu). It feels
> rather artificial to do this small bit of computation with double_int
> when so much else assumes HWI is enough, but why not...

Ok.

Thanks,
Richard.

> 2013-11-09  Marc Glisse  <marc.glisse@inria.fr>
>
>             Jeff Law  <law@redhat.com>
>
> gcc/
>         * tree-ssa-alias.c (stmt_kills_ref_p_1): Use
>         ao_ref_init_from_ptr_and_size for builtins.
>
> gcc/testsuite/
>         * gcc.dg/tree-ssa/alias-27.c: New testcase.
>
> --
> Marc Glisse
>
> Index: gcc/testsuite/gcc.dg/tree-ssa/alias-27.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/tree-ssa/alias-27.c    (revision 0)
> +++ gcc/testsuite/gcc.dg/tree-ssa/alias-27.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: gcc/testsuite/gcc.dg/tree-ssa/alias-27.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-ssa-alias.c
> ===================================================================
> --- gcc/tree-ssa-alias.c        (revision 204608)
> +++ gcc/tree-ssa-alias.c        (working copy)
> @@ -2001,23 +2001,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.  */
> @@ -2090,37 +2091,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;
>               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))
> +             tree rbase = ref->base;
> +             double_int roffset = double_int::from_shwi (ref->offset);
> +             ao_ref dref;
> +             ao_ref_init_from_ptr_and_size (&dref, dest, len);
> +             tree base = ao_ref_base (&dref);
> +             double_int offset = double_int::from_shwi (dref.offset);
> +             double_int bpu = double_int::from_uhwi (BITS_PER_UNIT);
> +             if (!base || dref.size == -1)
> +               return false;
> +             if (TREE_CODE (base) == MEM_REF)
> +               {
> +                 if (TREE_CODE (rbase) != MEM_REF)
> +                   return false;
> +                 // Compare pointers.
> +                 offset += bpu * mem_ref_offset (base);
> +                 roffset += bpu * mem_ref_offset (rbase);
> +                 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)))
> +                 double_int size = bpu * tree_to_double_int (len);
> +                 double_int rsize = double_int::from_uhwi (ref->max_size);
> +                 if (offset.sle (roffset)
> +                     && (roffset + rsize).sle (offset + size))
>                     return true;
>                 }
>               break;
>             }
>
>           case BUILT_IN_VA_END:
>             {
>               tree ptr = gimple_call_arg (stmt, 0);
>               if (TREE_CODE (ptr) == ADDR_EXPR)
>                 {
>

Patch

Index: gcc/testsuite/gcc.dg/tree-ssa/alias-27.c

===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/alias-27.c	(revision 0)

+++ gcc/testsuite/gcc.dg/tree-ssa/alias-27.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: gcc/testsuite/gcc.dg/tree-ssa/alias-27.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-ssa-alias.c

===================================================================
--- gcc/tree-ssa-alias.c	(revision 204608)

+++ gcc/tree-ssa-alias.c	(working copy)

@@ -2001,23 +2001,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.  */
@@ -2090,37 +2091,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;

 	      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))

+	      tree rbase = ref->base;

+	      double_int roffset = double_int::from_shwi (ref->offset);

+	      ao_ref dref;

+	      ao_ref_init_from_ptr_and_size (&dref, dest, len);

+	      tree base = ao_ref_base (&dref);

+	      double_int offset = double_int::from_shwi (dref.offset);

+	      double_int bpu = double_int::from_uhwi (BITS_PER_UNIT);

+	      if (!base || dref.size == -1)

+		return false;

+	      if (TREE_CODE (base) == MEM_REF)

+		{

+		  if (TREE_CODE (rbase) != MEM_REF)

+		    return false;

+		  // Compare pointers.

+		  offset += bpu * mem_ref_offset (base);

+		  roffset += bpu * mem_ref_offset (rbase);

+		  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)))

+		  double_int size = bpu * tree_to_double_int (len);

+		  double_int rsize = double_int::from_uhwi (ref->max_size);

+		  if (offset.sle (roffset)

+		      && (roffset + rsize).sle (offset + size))

 		    return true;
 		}
 	      break;
 	    }
 
 	  case BUILT_IN_VA_END:
 	    {
 	      tree ptr = gimple_call_arg (stmt, 0);
 	      if (TREE_CODE (ptr) == ADDR_EXPR)
 		{