Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-12 Thread Andreas Krebbel
On 07/02/14 10:33, Richard Biener wrote:
 + 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);
 + }

Hi,

creating a new var for the output parameter throws away the value already in 
there.  But this value
must not change when posix_memalign e.g. returns with ENOMEM.  It breaks the 
glibc posix_memalign
testcase on s390 (somewhat reduced here):

typedef unsigned long size_t;
extern int posix_memalign(void **memptr, size_t alignment, size_t size);
extern void abort(void);
int
main (void)
{
  void *p;
  int ret;

  p = 0;
  ret = posix_memalign (p, sizeof (void *), -1);
  if (p != 0)
abort ();
  return 0;
}

.c.170r.expand

main ()
{
  void * D.1395;
  void * D.1394;
  int ret;
  void * p;
  int D.1393;
  void * p.0;
  void * _2;
  void * _3;
  void * p.0_4;
  int _5;

;;   basic block 2, loop depth 0
;;pred:   ENTRY
  p = 0B;
  ret_1 = posix_memalign (D.1395, 4, 4294967295);
  _2 = D.1395;
  _3 = __builtin_assume_aligned (_2, 4);
  MEM[(void *)p] = _3;
  p.0_4 = p;
  if (p.0_4 != 0B)
goto bb 3;
  else
goto bb 4;
;;succ:   3
;;4

;;   basic block 3, loop depth 0
;;pred:   2
  abort ();
;;succ:

;;   basic block 4, loop depth 0
;;pred:   2
  _5 = 0;
  p ={v} {CLOBBER};
;;succ:   5

;;   basic block 5, loop depth 0
;;pred:   4
L3:
  return _5;
;;succ:   EXIT

}



Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-12 Thread Richard Biener
On Wed, 12 Feb 2014, Andreas Krebbel wrote:

 On 07/02/14 10:33, Richard Biener wrote:
  + 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);
  + }
 
 Hi,
 
 creating a new var for the output parameter throws away the value already in 
 there.  But this value
 must not change when posix_memalign e.g. returns with ENOMEM.  It breaks the 
 glibc posix_memalign
 testcase on s390 (somewhat reduced here):

Bah.  I am testing the following.

Richard.

2014-02-12  Richard Biener  rguent...@suse.de

PR middle-end/60092
* gimple-low.c (lower_builtin_posix_memalign): Initialize the new
temporary properly.
(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
*** 786,792 
   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);
--- 787,793 
   tem = __builtin_assume_aligned (tem, align);
   *ptr = tem;
 or to
!  void *tem = ptr;
   posix_memalign (tem, align, size);
   ttem = tem;
   ttem = __builtin_assume_aligned (ttem, align);
*** lower_builtin_posix_memalign (gimple_stm
*** 806,811 
--- 807,819 
tree tem = create_tmp_var (ptr_type_node, NULL);
TREE_ADDRESSABLE (tem) = 1;
gimple_call_set_arg (stmt, 0, build_fold_addr_expr (tem));
+   /* Initialize tem, ptr has to be unchanged if posix_memalloc fails.  */
+   stmt = gimple_build_assign (ptr,
+ fold_build2 (MEM_REF, ptr_type_node, pptr,
+  build_int_cst (ptr_type_node, 
0)));
+   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+   stmt = gimple_build_assign (tem, ptr);
+   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
stmt = gimple_build_assign (ptr, tem);
  }
else
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;
+ }


Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-12 Thread Jakub Jelinek
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).

Jakub


Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-12 Thread Richard Biener
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  rguent...@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 

Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-12 Thread Richard Biener
On Wed, 12 Feb 2014, Richard Biener wrote:

 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.

Ok, I've analyzed what happens here and it's a pass ordering issue

  NEXT_PASS (pass_build_ealias);
  NEXT_PASS (pass_sra_early);
  NEXT_PASS (pass_fre);

PTA can figure out all points-to sets properly but when SRA
scalarizes the struct with the two posix_memaligned pointers
the replacements get written into SSA form and PHI nodes are
inserted for them (as assignment is now conditional).  That
process cannot reliably (and does never) set points-to info
for those vars.  FRE then fails to disambiguate.

Now, there is no reason why pass_build_ealias should be before
pass_sra_early - in fact that's a useless pessimization.

But as the testcase was supposed to test field-sensitive points-to
I chose to disable SRA for the testcase (and queue pass interchange
for 4.10 - unless you think it's ok now - I think it's harmless
and should only improve early FRE results when SRA happens).

Patch below in testing now.

Thanks,
Richard.

2014-02-12  Richard Biener  rguent...@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/torture/pr60092.c: New testcase.
* gcc.dg/tree-ssa/alias-31.c: Disable SRA.

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 

Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-12 Thread Jakub Jelinek
On Wed, Feb 12, 2014 at 11:42:09AM +0100, Richard Biener wrote:
 But as the testcase was supposed to test field-sensitive points-to
 I chose to disable SRA for the testcase (and queue pass interchange
 for 4.10 - unless you think it's ok now - I think it's harmless
 and should only improve early FRE results when SRA happens).

Yeah, I'd prefer to queue pass reorderings to 5.0 at this point.
 
 Patch below in testing now.

LGTM.

 2014-02-12  Richard Biener  rguent...@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/torture/pr60092.c: New testcase.
   * gcc.dg/tree-ssa/alias-31.c: Disable SRA.

Jakub


Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-07 Thread Richard Biener
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 

Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-07 Thread Jakub Jelinek
On Fri, Feb 07, 2014 at 10:33:45AM +0100, Richard Biener wrote:
 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.

Ok.

Jakub


[PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-06 Thread Richard Biener

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

Bootstrap / regtest on x86_64-unknown-linux-gnu pending.

Thanks,
Richard.

2014-02-06  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/tree-ssa/alias-31.c: Adjust.
* 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:12:39.116394523 +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,812 
/* 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 (align);
+  *ptr = tem;
+so we can get at the alignment of *ptr 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_var (ptr_type_node, NULL);
+   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/tree-ssa/alias-31.c
===
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/alias-31.c 2014-02-06 
15:11:55.881397499 +0100
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/alias-31.c  2014-02-06 

Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible

2014-02-06 Thread Richard Biener
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.

Richard.