[PATCH] PR60092 - lower posix_memalign to make align-info accessible
Richard Biener
rguenther@suse.de
Wed Feb 12 10:09:00 GMT 2014
On Wed, 12 Feb 2014, Jakub Jelinek wrote:
> On Wed, Feb 12, 2014 at 10:30:01AM +0100, Richard Biener wrote:
> > Bah. I am testing the following.
>
> But then there is no guarantee that ptr is aligned after the call.
> char buf[32] __attribute__((aligned (32)));
> int
> foo (void)
> {
> void *ptr = buf + 1;
> posix_memalign (&ptr, 32, -1);
> /* Assume posix_memalign has failed. */
> return ((__UINTPTR_TYPE__)ptr) & 31;
> }
>
> This should return 1, but supposedly doesn't with the optimization.
> So, either we need to revert the lowering, or perhaps do it only if
> the original posix_memalign has a lhs and do it like:
> void *tmp;
> int res = posix_memalign (&tmp, align, size);
> if (!res)
> ptr = __builtin_assume_aligned (tmp, align);
> or so (no need to initialize tmp and copy it back for the failure case,
> but perhaps it would result in better code).
Yeah. It seems to work modulo alias-31.c (checking what happens here,
alias info looks good). Prelimiary patch below.
2014-02-12 Richard Biener <rguenther@suse.de>
PR middle-end/60092
* gimple-low.c (lower_builtin_posix_memalign): Lower conditional
of posix_memalign being successful.
(lower_stmt): Restrict lowering of posix_memalign to when
-ftree-bit-ccp is enabled.
* gcc.dg/pr60092.c: New testcase.
Index: gcc/gimple-low.c
===================================================================
*** gcc/gimple-low.c (revision 207714)
--- gcc/gimple-low.c (working copy)
*************** lower_stmt (gimple_stmt_iterator *gsi, s
*** 336,342 ****
data->cannot_fallthru = false;
return;
}
! else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN)
{
lower_builtin_posix_memalign (gsi);
return;
--- 336,343 ----
data->cannot_fallthru = false;
return;
}
! else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN
! && flag_tree_bit_ccp)
{
lower_builtin_posix_memalign (gsi);
return;
*************** lower_builtin_setjmp (gimple_stmt_iterat
*** 781,817 ****
}
/* 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);
--- 782,828 ----
}
/* Lower calls to posix_memalign to
! res = posix_memalign (ptr, align, size);
! if (res == 0)
! *ptr = __builtin_assume_aligned (*ptr, align);
or to
void *tem;
! res = posix_memalign (&tem, align, size);
! if (res == 0)
! ptr = __builtin_assume_aligned (tem, align);
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, call = gsi_stmt (*gsi);
! tree pptr = gimple_call_arg (call, 0);
! tree align = gimple_call_arg (call, 1);
! tree res = gimple_call_lhs (call);
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 (call, 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)));
+ if (res == NULL_TREE)
+ {
+ res = create_tmp_reg (integer_type_node, NULL);
+ gimple_call_set_lhs (call, res);
+ }
+ tree align_label = create_artificial_label (UNKNOWN_LOCATION);
+ tree noalign_label = create_artificial_label (UNKNOWN_LOCATION);
+ gimple cond = gimple_build_cond (EQ_EXPR, res, integer_zero_node,
+ align_label, noalign_label);
+ gsi_insert_after (gsi, cond, GSI_NEW_STMT);
+ gsi_insert_after (gsi, gimple_build_label (align_label), GSI_NEW_STMT);
gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_ASSUME_ALIGNED),
2, ptr, align);
*************** lower_builtin_posix_memalign (gimple_stm
*** 821,826 ****
--- 832,838 ----
build_int_cst (ptr_type_node, 0)),
ptr);
gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ gsi_insert_after (gsi, gimple_build_label (noalign_label), GSI_NEW_STMT);
}
Index: gcc/testsuite/gcc.dg/torture/pr60092.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr60092.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr60092.c (working copy)
***************
*** 0 ****
--- 1,21 ----
+ /* { dg-do run } */
+ /* { dg-require-weak "" } */
+
+ typedef __SIZE_TYPE__ size_t;
+ extern int posix_memalign(void **memptr, size_t alignment, size_t size) __attribute__((weak));
+ extern void abort(void);
+ int
+ main (void)
+ {
+ void *p;
+ int ret;
+
+ if (!posix_memalign)
+ return 0;
+
+ p = (void *)&ret;
+ ret = posix_memalign (&p, sizeof (void *), -1);
+ if (p != (void *)&ret)
+ abort ();
+ return 0;
+ }
More information about the Gcc-patches
mailing list