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; + }