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 <[email protected]>
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" } } */