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 15:12:39.117394523 +0100 *************** *** 1,5 **** /* { dg-do compile } */ ! /* { dg-options "-O2 -fdump-tree-cddce1" } */ extern int posix_memalign(void **memptr, __SIZE_TYPE__ alignment, __SIZE_TYPE__ size); --- 1,5 ---- /* { dg-do compile } */ ! /* { dg-options "-O2 -fdump-tree-dce2" } */ extern int posix_memalign(void **memptr, __SIZE_TYPE__ alignment, __SIZE_TYPE__ size); *************** int foo (int *p) *** 20,24 **** /* There should be only one load from *p left. All stores and all other loads should be removed. */ ! /* { dg-final { scan-tree-dump-times "\\\*\[^ \]" 1 "cddce1" } } */ ! /* { dg-final { cleanup-tree-dump "cddce1" } } */ --- 20,24 ---- /* There should be only one load from *p left. All stores and all other loads should be removed. */ ! /* { dg-final { scan-tree-dump-times "\\\*\[^ \]" 1 "dce2" } } */ ! /* { dg-final { cleanup-tree-dump "dce2" } } */ 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" } } */