On Thu, 6 Feb 2014, Richard Biener wrote:

> On Thu, 6 Feb 2014, Richard Biener wrote:
> 
> > 
> > This re-writes posix_memalign calls to
> > 
> >       posix_memalign (ptr, align, size);
> >       tem = *ptr;
> >       tem = __builtin_assume_aligned (align);
> >       *ptr = tem;
> > 
> > during CF lowering (yeah, ok ...) to make alignment info accessible
> > to SSA based analysis.
> > 
> > I have to adjust the added alias-31.c testcase again because with
> > the above we end up with
> > 
> >   <bb 2>:
> >   res_3 = *p_2(D);
> >   posix_memalign (&q.q1, 128, 512);
> >   _5 = MEM[(void *)&q];
> >   _6 = __builtin_assume_aligned (_5, 128);
> >   MEM[(void *)&q] = _6;
> >   posix_memalign (&q.q2, 128, 512);
> >   _17 = res_3 + res_3;
> >   _20 = _17 + 1;
> >   _23 = _20 + 2;
> >   q ={v} {CLOBBER};
> >   return _23;
> > 
> > after early DCE.  This is because DCE only has "baby" DSE built-in
> > and the store to MEM[(void *)&q] which it doesn't remove keeps
> > the rest live.  DSE removes the store and the DCE following it
> > the rest.
> > 
> > Not sure if more sophisticated lowering is wanted here.  Special-casing
> > &... operands to posix_memalign as stated in the PR, generating
> > for posix_memalign (&ptr, 128, 512);
> > 
> >   posix_memalign (&tem, 128, 512);
> >   reg = tem;
> >   reg = __builtin_assume_aligned (reg, 128);
> >   ptr = reg;
> > 
> > instead would be possible (hoping for ptr to become non-address-taken).
> 
> Ok, doing that was simple and avoids pessimizing the testcase.

Thus like the following.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk
at this stage?

Thanks,
Richard.

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

        PR middle-end/60092
        * gimple-low.c (lower_builtin_posix_memalign): New function.
        (lower_stmt): Call it to lower posix_memalign in a way
        to make alignment info accessible.

        * gcc.dg/vect/pr60092-2.c: New testcase.

Index: trunk/gcc/gimple-low.c
===================================================================
*** trunk.orig/gcc/gimple-low.c 2014-02-06 15:06:39.013419315 +0100
--- trunk/gcc/gimple-low.c      2014-02-06 15:41:14.855276396 +0100
*************** static void lower_gimple_bind (gimple_st
*** 83,88 ****
--- 83,89 ----
  static void lower_try_catch (gimple_stmt_iterator *, struct lower_data *);
  static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
  static void lower_builtin_setjmp (gimple_stmt_iterator *);
+ static void lower_builtin_posix_memalign (gimple_stmt_iterator *);
  
  
  /* Lower the body of current_function_decl from High GIMPLE into Low
*************** lower_stmt (gimple_stmt_iterator *gsi, s
*** 327,338 ****
          }
  
        if (decl
!           && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
!           && DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
          {
!           lower_builtin_setjmp (gsi);
!           data->cannot_fallthru = false;
!           return;
          }
  
        if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
--- 328,346 ----
          }
  
        if (decl
!           && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
          {
!           if (DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
!             {
!               lower_builtin_setjmp (gsi);
!               data->cannot_fallthru = false;
!               return;
!             }
!           else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN)
!             {
!               lower_builtin_posix_memalign (gsi);
!               return;
!             }
          }
  
        if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
*************** lower_builtin_setjmp (gimple_stmt_iterat
*** 771,776 ****
--- 779,827 ----
    /* Remove the call to __builtin_setjmp.  */
    gsi_remove (gsi, false);
  }
+ 
+ /* Lower calls to posix_memalign to
+      posix_memalign (ptr, align, size);
+      tem = *ptr;
+      tem = __builtin_assume_aligned (tem, align);
+      *ptr = tem;
+    or to
+      void *tem;
+      posix_memalign (&tem, align, size);
+      ttem = tem;
+      ttem = __builtin_assume_aligned (ttem, align);
+      ptr = tem;
+    in case the first argument was &ptr.  That way we can get at the
+    alignment of the heap pointer in CCP.  */
+ 
+ static void
+ lower_builtin_posix_memalign (gimple_stmt_iterator *gsi)
+ {
+   gimple stmt = gsi_stmt (*gsi);
+   tree pptr = gimple_call_arg (stmt, 0);
+   tree align = gimple_call_arg (stmt, 1);
+   tree ptr = create_tmp_reg (ptr_type_node, NULL);
+   if (TREE_CODE (pptr) == ADDR_EXPR)
+     {
+       tree tem = create_tmp_var (ptr_type_node, NULL);
+       TREE_ADDRESSABLE (tem) = 1;
+       gimple_call_set_arg (stmt, 0, build_fold_addr_expr (tem));
+       stmt = gimple_build_assign (ptr, tem);
+     }
+   else
+     stmt = gimple_build_assign (ptr,
+                               fold_build2 (MEM_REF, ptr_type_node, pptr,
+                                            build_int_cst (ptr_type_node, 0)));
+   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+   stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_ASSUME_ALIGNED),
+                           2, ptr, align);
+   gimple_call_set_lhs (stmt, ptr);
+   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+   stmt = gimple_build_assign (fold_build2 (MEM_REF, ptr_type_node, pptr,
+                                          build_int_cst (ptr_type_node, 0)),
+                             ptr);
+   gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ }
  
  
  /* Record the variables in VARS into function FN.  */
Index: trunk/gcc/testsuite/gcc.dg/vect/pr60092-2.c
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/vect/pr60092-2.c 2014-02-06 15:15:10.167384123 
+0100
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_int } */
+ 
+ int *foo (int n)
+ {
+   int *p;
+   int *q;
+   void *tem;
+   if (posix_memalign (&tem, 256, n * sizeof (int)) != 0)
+     return (void *)0;
+   p = (int *)tem;
+   if (posix_memalign (&tem, 256, n * sizeof (int)) != 0)
+     return (void *)0;
+   q = (int *)tem;
+   bar (q);
+   int i;
+   for (i = 0; i < n; ++i)
+     p[i] = q[i] + q[i];
+   return p;
+ }
+ 
+ /* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
+ /* { dg-final { scan-tree-dump-not "Peeling for alignment will be applied" 
"vect" } } */
+ /* { dg-final { scan-tree-dump-not "Vectorizing an unaligned access" "vect" } 
} */
+ /* { dg-final { cleanup-tree-dump "vect" } } */

Reply via email to