This adds a builtin for C11 aligned_alloc and support for it in the alias and alignment tracking machinery.
Bootstrap and regtest in progress on x86_64-unknown-linux-gnu. Ok for trunk? Thanks, Richard. 2014-02-06 Richard Biener <rguent...@suse.de> PR middle-end/60092 * builtins.def (DEF_C11_BUILTIN): Add. (BUILT_IN_ALIGNED_ALLOC): Likewise. * coretypes.h (enum function_class): Add function_c11_misc. * tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Handle BUILT_IN_ALIGNED_ALLOC like BUILT_IN_MALLOC. (call_may_clobber_ref_p_1): Likewise. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise. (mark_all_reaching_defs_necessary_1): Likewise. (propagate_necessity): Likewise. (eliminate_unnecessary_stmts): Likewise. * tree-ssa-ccp.c (evaluate_stmt): Handle BUILT_IN_ALIGNED_ALLOC. ada/ * gcc-interface/utils.c: Define flag_isoc11. lto/ * lto-lang.c: Define flag_isoc11. * gcc.dg/tree-ssa/alias-32.c: New testcase. * gcc.dg/vect/pr60092.c: Likewise. Index: trunk/gcc/builtins.def =================================================================== *** trunk.orig/gcc/builtins.def 2014-02-06 12:46:01.085000256 +0100 --- trunk/gcc/builtins.def 2014-02-06 13:13:06.499888349 +0100 *************** along with GCC; see the file COPYING3. *** 111,116 **** --- 111,123 ---- DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true) + /* Like DEF_LIB_BUILTIN, except that the function is only a part of + the standard in C11 or above. */ + #undef DEF_C11_BUILTIN + #define DEF_C11_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, !flag_isoc11, ATTRS, targetm.libc_has_function (function_c11_misc), true) + /* Like DEF_C99_BUILTIN, but for complex math functions. */ #undef DEF_C99_COMPL_BUILTIN #define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ *************** DEF_C99_BUILTIN (BUILT_IN_ACOSH, *** 223,228 **** --- 230,236 ---- DEF_C99_BUILTIN (BUILT_IN_ACOSHF, "acoshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_BUILTIN (BUILT_IN_ACOSHL, "acoshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSL, "acosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) + DEF_C11_BUILTIN (BUILT_IN_ALIGNED_ALLOC, "aligned_alloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LIST) DEF_LIB_BUILTIN (BUILT_IN_ASIN, "asin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINF, "asinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_BUILTIN (BUILT_IN_ASINH, "asinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) Index: trunk/gcc/coretypes.h =================================================================== *** trunk.orig/gcc/coretypes.h 2014-01-07 10:20:00.549453955 +0100 --- trunk/gcc/coretypes.h 2014-02-06 13:10:03.472900950 +0100 *************** enum function_class { *** 194,200 **** function_c94, function_c99_misc, function_c99_math_complex, ! function_sincos }; /* Memory model types for the __atomic* builtins. --- 194,201 ---- function_c94, function_c99_misc, function_c99_math_complex, ! function_sincos, ! function_c11_misc }; /* Memory model types for the __atomic* builtins. Index: trunk/gcc/tree-ssa-alias.c =================================================================== *** trunk.orig/gcc/tree-ssa-alias.c 2014-02-06 12:43:34.450010352 +0100 --- trunk/gcc/tree-ssa-alias.c 2014-02-06 13:14:08.669884068 +0100 *************** ref_maybe_used_by_call_p_1 (gimple call, *** 1516,1521 **** --- 1516,1522 ---- case BUILT_IN_FREE: case BUILT_IN_MALLOC: case BUILT_IN_POSIX_MEMALIGN: + case BUILT_IN_ALIGNED_ALLOC: case BUILT_IN_CALLOC: case BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: *************** call_may_clobber_ref_p_1 (gimple call, a *** 1826,1831 **** --- 1827,1833 ---- /* Allocating memory does not have any side-effects apart from being the definition point for the pointer. */ case BUILT_IN_MALLOC: + case BUILT_IN_ALIGNED_ALLOC: case BUILT_IN_CALLOC: case BUILT_IN_STRDUP: case BUILT_IN_STRNDUP: Index: trunk/gcc/tree-ssa-dce.c =================================================================== *** trunk.orig/gcc/tree-ssa-dce.c 2014-01-07 10:20:02.520453869 +0100 --- trunk/gcc/tree-ssa-dce.c 2014-02-06 13:16:20.570874987 +0100 *************** mark_stmt_if_obviously_necessary (gimple *** 231,236 **** --- 231,237 ---- switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_MALLOC: + case BUILT_IN_ALIGNED_ALLOC: case BUILT_IN_CALLOC: case BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: *************** mark_all_reaching_defs_necessary_1 (ao_r *** 573,578 **** --- 574,580 ---- switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_MALLOC: + case BUILT_IN_ALIGNED_ALLOC: case BUILT_IN_CALLOC: case BUILT_IN_ALLOCA: case BUILT_IN_ALLOCA_WITH_ALIGN: *************** propagate_necessity (bool aggressive) *** 776,782 **** && is_gimple_call (def_stmt = SSA_NAME_DEF_STMT (ptr)) && (def_callee = gimple_call_fndecl (def_stmt)) && DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL ! && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC)) continue; } --- 778,785 ---- && is_gimple_call (def_stmt = SSA_NAME_DEF_STMT (ptr)) && (def_callee = gimple_call_fndecl (def_stmt)) && DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL ! && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC ! || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC)) continue; } *************** propagate_necessity (bool aggressive) *** 822,827 **** --- 825,831 ---- && (DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET || DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET_CHK || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC + || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALIGNED_ALLOC || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END *************** eliminate_unnecessary_stmts (void) *** 1229,1235 **** special logic we apply to malloc/free pair removal. */ && (!(call = gimple_call_fndecl (stmt)) || DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL ! || (DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC && DECL_FUNCTION_CODE (call) != BUILT_IN_ALLOCA && (DECL_FUNCTION_CODE (call) --- 1233,1240 ---- special logic we apply to malloc/free pair removal. */ && (!(call = gimple_call_fndecl (stmt)) || DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL ! || (DECL_FUNCTION_CODE (call) != BUILT_IN_ALIGNED_ALLOC ! && DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC && DECL_FUNCTION_CODE (call) != BUILT_IN_ALLOCA && (DECL_FUNCTION_CODE (call) Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/alias-32.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/alias-32.c 2014-02-06 13:32:26.430808489 +0100 *************** *** 0 **** --- 1,20 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-tree-cddce1" } */ + + int bar (short *p) + { + int res = *p; + struct { int *q1; int *q2; } q; + q.q1 = __builtin_aligned_alloc (128, 128 * sizeof (int)); + q.q2 = __builtin_aligned_alloc (128, 128 * sizeof (int)); + *q.q1 = 1; + *q.q2 = 2; + return res + *p + *q.q1 + *q.q2; + } + + /* There should be only one load from *p left. All stores and all + other loads should be removed. Likewise the calls to aligned_alloc. */ + + /* { dg-final { scan-tree-dump-times "\\\*\[^ \]" 1 "cddce1" } } */ + /* { dg-final { scan-tree-dump-not "aligned_alloc" "cddce1" } } */ + /* { dg-final { cleanup-tree-dump "cddce1" } } */ Index: trunk/gcc/testsuite/gcc.dg/vect/pr60092.c =================================================================== *** /dev/null 1970-01-01 00:00:00.000000000 +0000 --- trunk/gcc/testsuite/gcc.dg/vect/pr60092.c 2014-02-06 14:13:06.902640465 +0100 *************** *** 0 **** --- 1,18 ---- + /* { dg-do compile } */ + /* { dg-require-effective-target vect_int } */ + + int *foo (int n) + { + int *p = __builtin_aligned_alloc (256, n * sizeof (int)); + int *q = __builtin_aligned_alloc (256, n * sizeof (int)); + 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" } } */ Index: trunk/gcc/tree-ssa-ccp.c =================================================================== *** trunk.orig/gcc/tree-ssa-ccp.c 2014-02-06 14:01:08.558689922 +0100 --- trunk/gcc/tree-ssa-ccp.c 2014-02-06 14:01:14.286689528 +0100 *************** evaluate_stmt (gimple stmt) *** 1711,1716 **** --- 1711,1735 ---- val = bit_value_assume_aligned (stmt); break; + case BUILT_IN_ALIGNED_ALLOC: + { + tree align = get_constant_value (gimple_call_arg (stmt, 0)); + if (align + && tree_fits_uhwi_p (align)) + { + unsigned HOST_WIDE_INT aligni = tree_to_uhwi (align); + if (aligni > 1 + /* align must be power-of-two */ + && (aligni & (aligni - 1)) == 0) + { + val.lattice_val = CONSTANT; + val.value = build_int_cst (ptr_type_node, 0); + val.mask = double_int::from_shwi (-aligni); + } + } + break; + } + default:; } } Index: trunk/gcc/ada/gcc-interface/utils.c =================================================================== *** trunk.orig/gcc/ada/gcc-interface/utils.c 2014-01-28 10:50:00.929016277 +0100 --- trunk/gcc/ada/gcc-interface/utils.c 2014-02-06 14:24:03.248595277 +0100 *************** def_builtin_1 (enum built_in_function fn *** 6532,6537 **** --- 6532,6538 ---- static int flag_isoc94 = 0; static int flag_isoc99 = 0; + static int flag_isoc11 = 0; /* Install what the common builtins.def offers. */ Index: trunk/gcc/lto/lto-lang.c =================================================================== *** trunk.orig/gcc/lto/lto-lang.c 2014-02-06 10:41:15.412515636 +0100 --- trunk/gcc/lto/lto-lang.c 2014-02-06 14:25:12.254590526 +0100 *************** static GTY(()) tree signed_size_type_nod *** 192,197 **** --- 192,198 ---- /* Flags needed to process builtins.def. */ int flag_isoc94; int flag_isoc99; + int flag_isoc11; /* Attribute handlers. */