Re: [PATCH] PR60092 - lower posix_memalign to make align-info accessible
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
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
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
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
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
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
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
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
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
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.