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 (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" } } */