On Thu, 6 Feb 2014, Jakub Jelinek wrote:

> On Thu, Feb 06, 2014 at 02:21:01PM +0100, Richard Biener wrote:
> > +     /* We marking allocated storage local, we deal with it becoming
> > +        global by escaping and setting of vars_contains_escaped_heap.  */
> 
> Did you mean By marking ..., or something else?

"We are marking ..."  cut&pasted and fixed both cases.

> > + extern int posix_memalign(void **memptr,
> > +                     __SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
> > + 
> > + int foo (int *p)
> > + {
> > +   int res = *p;
> > +   int *q;
> > +   posix_memalign ((void **)&q, 128, 128 * sizeof (int));
> 
> Do you really want to have strict aliasing violations in the testcase?
> I think one has to take address of a void * variable and if you want
> int *, then cast to int * afterwards.

Sure, I'll fix that (it doesn't matter for GCC luckily ;)).  I still
expect user code to be lazy ... (which is why GCC treats all pointer
types as having the same alias set)

> Also, I think for posix_memalign
> you really should be checking return value of the function.

Yeah.

Like the following - will commit after re-bootstrapping together
with the 3rd followup.

Richard.

2014-02-06  Richard Biener  <rguent...@suse.de>

        PR middle-end/60092
        * builtin-types.def (BT_FN_INT_PTRPTR_SIZE_SIZE): Add.
        * builtins.def (BUILT_IN_POSIX_MEMALIGN): Likewise.
        * tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
        Handle BUILT_IN_POSIX_MEMALIGN.
        (find_func_clobbers): Likewise.
        * tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Likewise.
        (call_may_clobber_ref_p_1): Likewise.

        * gcc.dg/tree-ssa/alias-30.c: New testcase.
        * gcc.dg/tree-ssa/alias-31.c: Likewise.

Index: gcc/builtin-types.def
===================================================================
*** gcc/builtin-types.def.orig  2014-02-06 12:43:09.585012064 +0100
--- gcc/builtin-types.def       2014-02-06 12:43:34.435010353 +0100
*************** DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I2_
*** 429,434 ****
--- 429,435 ----
  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4, 
BT_INT)
  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8, 
BT_INT)
  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, 
BT_I16, BT_INT)
+ DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTRPTR_SIZE_SIZE, BT_INT, BT_PTR_PTR, BT_SIZE, 
BT_SIZE)
  
  DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
                     BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
Index: gcc/builtins.def
===================================================================
*** gcc/builtins.def.orig       2014-02-06 12:43:09.586012064 +0100
--- gcc/builtins.def    2014-02-06 15:06:39.716419267 +0100
*************** DEF_GCC_BUILTIN        (BUILT_IN_POPCOUN
*** 755,760 ****
--- 755,761 ----
  DEF_GCC_BUILTIN        (BUILT_IN_POPCOUNTIMAX, "popcountimax", 
BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, 
ATTR_CONST_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_POPCOUNTLL, "popcountll", 
BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
+ DEF_EXT_LIB_BUILTIN    (BUILT_IN_POSIX_MEMALIGN, "posix_memalign", 
BT_FN_INT_PTRPTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
  DEF_GCC_BUILTIN        (BUILT_IN_PREFETCH, "prefetch", 
BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST)
  DEF_LIB_BUILTIN        (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, 
ATTR_NOTHROW_LEAF_LIST)
  DEF_GCC_BUILTIN        (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, 
ATTR_NORETURN_NOTHROW_LEAF_LIST)
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig     2014-02-06 12:43:09.597012063 +0100
--- gcc/tree-ssa-structalias.c  2014-02-06 15:07:22.987416288 +0100
*************** handle_lhs_call (gimple stmt, tree lhs,
*** 3982,3988 ****
        struct constraint_expr tmpc;
        rhsc.create (0);
        vi = make_heapvar ("HEAP");
!       /* We marking allocated storage local, we deal with it becoming
           global by escaping and setting of vars_contains_escaped_heap.  */
        DECL_EXTERNAL (vi->decl) = 0;
        vi->is_global_var = 0;
--- 3982,3988 ----
        struct constraint_expr tmpc;
        rhsc.create (0);
        vi = make_heapvar ("HEAP");
!       /* We are marking allocated storage local, we deal with it becoming
           global by escaping and setting of vars_contains_escaped_heap.  */
        DECL_EXTERNAL (vi->decl) = 0;
        vi->is_global_var = 0;
*************** find_func_aliases_for_builtin_call (gimp
*** 4231,4236 ****
--- 4231,4256 ----
          lhsc.release ();
          return true;
        }
+       case BUILT_IN_POSIX_MEMALIGN:
+         {
+         tree ptrptr = gimple_call_arg (t, 0);
+         get_constraint_for (ptrptr, &lhsc);
+         do_deref (&lhsc);
+         varinfo_t vi = make_heapvar ("HEAP");
+         /* We are marking allocated storage local, we deal with it becoming
+            global by escaping and setting of vars_contains_escaped_heap.  */
+         DECL_EXTERNAL (vi->decl) = 0;
+         vi->is_global_var = 0;
+         struct constraint_expr tmpc;
+         tmpc.var = vi->id;
+         tmpc.offset = 0;
+         tmpc.type = ADDRESSOF;
+         rhsc.safe_push (tmpc);
+         process_all_all_constraints (lhsc, rhsc);
+         lhsc.release ();
+         rhsc.release ();
+         return true;
+       }
        case BUILT_IN_ASSUME_ALIGNED:
        {
          tree res = gimple_call_lhs (t);
*************** find_func_clobbers (gimple origt)
*** 4960,4965 ****
--- 4980,4986 ----
             its argument.  */
          case BUILT_IN_MEMSET:
          case BUILT_IN_MEMSET_CHK:
+         case BUILT_IN_POSIX_MEMALIGN:
            {
              tree dest = gimple_call_arg (t, 0);
              unsigned i;
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig   2014-02-06 12:43:09.598012063 +0100
--- gcc/tree-ssa-alias.c        2014-02-06 15:06:39.716419267 +0100
*************** ref_maybe_used_by_call_p_1 (gimple call,
*** 1515,1520 ****
--- 1515,1521 ----
        /* The following builtins do not read from memory.  */
        case BUILT_IN_FREE:
        case BUILT_IN_MALLOC:
+       case BUILT_IN_POSIX_MEMALIGN:
        case BUILT_IN_CALLOC:
        case BUILT_IN_ALLOCA:
        case BUILT_IN_ALLOCA_WITH_ALIGN:
*************** call_may_clobber_ref_p_1 (gimple call, a
*** 1838,1843 ****
--- 1839,1854 ----
        case BUILT_IN_ALLOCA_WITH_ALIGN:
        case BUILT_IN_ASSUME_ALIGNED:
          return false;
+       /* But posix_memalign stores a pointer into the memory pointed to
+          by its first argument.  */
+       case BUILT_IN_POSIX_MEMALIGN:
+         {
+           tree ptrptr = gimple_call_arg (call, 0);
+           ao_ref dref;
+           ao_ref_init_from_ptr_and_size (&dref, ptrptr,
+                                          TYPE_SIZE_UNIT (ptr_type_node));
+           return refs_may_alias_p_1 (&dref, ref, false);
+         }
        /* Freeing memory kills the pointed-to memory.  More importantly
           the call has to serve as a barrier for moving loads and stores
           across it.  */
Index: gcc/testsuite/gcc.dg/tree-ssa/alias-30.c
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/tree-ssa/alias-30.c    2014-02-06 15:10:01.991405340 
+0100
***************
*** 0 ****
--- 1,22 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-fre-details" } */
+ 
+ extern int posix_memalign(void **memptr,
+                         __SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
+ 
+ int foo (int *p)
+ {
+   int res = *p;
+   int *q;
+   void *tem;
+   if (posix_memalign (&tem, 128, 128 * sizeof (int)) != 0)
+     return 0;
+   q = (int *)tem;
+   *q = 1;
+   return res + *p;
+ }
+ 
+ /* We should be able to CSE the load from *p in the return stmt.  */
+ 
+ /* { dg-final { scan-tree-dump "Replaced \\\*p" "fre1" } } */
+ /* { dg-final { cleanup-tree-dump "fre1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/alias-31.c
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/tree-ssa/alias-31.c    2014-02-06 15:11:55.881397499 
+0100
***************
*** 0 ****
--- 1,24 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-cddce1" } */
+ 
+ extern int posix_memalign(void **memptr,
+                         __SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
+ 
+ int foo (int *p)
+ {
+   int res = *p;
+   struct { void *q1; void *q2; } q;
+   if (posix_memalign (&q.q1, 128, 128 * sizeof (int)) != 0)
+     return 0;
+   if (posix_memalign (&q.q2, 128, 128 * sizeof (int)) != 0)
+     return 0;
+   *((int *)q.q1) = 1;
+   *((int *)q.q2) = 2;
+   return res + *p + *((int *)q.q1) + *((int *)q.q2);
+ }
+ 
+ /* There should be only one load from *p left.  All stores and all
+    other loads should be removed.  */
+ 
+ /* { dg-final { scan-tree-dump-times "\\\*\[^ \]" 1 "cddce1" } } */
+ /* { dg-final { cleanup-tree-dump "cddce1" } } */

Reply via email to