diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-02-08 10:09:01 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-02-08 10:09:01 +0100 |
commit | 8fcbce729d0ccd6881e479af9eec694abec61ee5 (patch) | |
tree | f4136c704d65e778659cad96324aa2c41d89c897 /gcc/tree-ssa-ccp.c | |
parent | 451bdd23084ab3282aa438f8d2808ea091cc0758 (diff) | |
download | gcc-8fcbce729d0ccd6881e479af9eec694abec61ee5.zip gcc-8fcbce729d0ccd6881e479af9eec694abec61ee5.tar.gz gcc-8fcbce729d0ccd6881e479af9eec694abec61ee5.tar.bz2 |
re PR middle-end/60092 (posix_memalign not recognized to derive alias and alignment info)
PR middle-end/60092
* tree-ssa-ccp.c (surely_varying_stmt_p): Don't return true
if TYPE_ATTRIBUTES (gimple_call_fntype ()) contain
assume_aligned or alloc_align attributes.
(bit_value_assume_aligned): Add ATTR, PTRVAL and ALLOC_ALIGN
arguments. Handle also assume_aligned and alloc_align attributes.
(evaluate_stmt): Adjust bit_value_assume_aligned caller.
Handle calls to functions with assume_aligned or alloc_align
attributes.
* doc/extend.texi: Document assume_aligned and alloc_align
attributes.
c-family/
* c-common.c (handle_alloc_size_attribute): Use tree_fits_uhwi_p
and tree_to_uhwi.
(handle_alloc_align_attribute, handle_assume_aligned_attribute): New
functions.
(c_common_attribute_table): Add alloc_align and assume_aligned
attributes.
testsuite/
* gcc.dg/attr-alloc_align-1.c: New test.
* gcc.dg/attr-alloc_align-2.c: New test.
* gcc.dg/attr-alloc_align-3.c: New test.
* gcc.dg/attr-assume_aligned-1.c: New test.
* gcc.dg/attr-assume_aligned-2.c: New test.
* gcc.dg/attr-assume_aligned-3.c: New test.
From-SVN: r207628
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 110 |
1 files changed, 88 insertions, 22 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 493bbcb..eeefeaf 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -738,13 +738,18 @@ surely_varying_stmt_p (gimple stmt) return true; /* If it is a call and does not return a value or is not a - builtin and not an indirect call, it is varying. */ + builtin and not an indirect call or a call to function with + assume_aligned/alloc_align attribute, it is varying. */ if (is_gimple_call (stmt)) { - tree fndecl; + tree fndecl, fntype = gimple_call_fntype (stmt); if (!gimple_call_lhs (stmt) || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE - && !DECL_BUILT_IN (fndecl))) + && !DECL_BUILT_IN (fndecl) + && !lookup_attribute ("assume_aligned", + TYPE_ATTRIBUTES (fntype)) + && !lookup_attribute ("alloc_align", + TYPE_ATTRIBUTES (fntype)))) return true; } @@ -1476,40 +1481,86 @@ bit_value_binop (enum tree_code code, tree type, tree rhs1, tree rhs2) return val; } -/* Return the propagation value when applying __builtin_assume_aligned to - its arguments. */ +/* Return the propagation value for __builtin_assume_aligned + and functions with assume_aligned or alloc_aligned attribute. + For __builtin_assume_aligned, ATTR is NULL_TREE, + for assume_aligned attribute ATTR is non-NULL and ALLOC_ALIGNED + is false, for alloc_aligned attribute ATTR is non-NULL and + ALLOC_ALIGNED is true. */ static prop_value_t -bit_value_assume_aligned (gimple stmt) +bit_value_assume_aligned (gimple stmt, tree attr, prop_value_t ptrval, + bool alloc_aligned) { - tree ptr = gimple_call_arg (stmt, 0), align, misalign = NULL_TREE; - tree type = TREE_TYPE (ptr); + tree align, misalign = NULL_TREE, type; unsigned HOST_WIDE_INT aligni, misaligni = 0; - prop_value_t ptrval = get_value_for_expr (ptr, true); prop_value_t alignval; double_int value, mask; prop_value_t val; + + if (attr == NULL_TREE) + { + tree ptr = gimple_call_arg (stmt, 0); + type = TREE_TYPE (ptr); + ptrval = get_value_for_expr (ptr, true); + } + else + { + tree lhs = gimple_call_lhs (stmt); + type = TREE_TYPE (lhs); + } + if (ptrval.lattice_val == UNDEFINED) return ptrval; gcc_assert ((ptrval.lattice_val == CONSTANT && TREE_CODE (ptrval.value) == INTEGER_CST) || ptrval.mask.is_minus_one ()); - align = gimple_call_arg (stmt, 1); - if (!tree_fits_uhwi_p (align)) - return ptrval; - aligni = tree_to_uhwi (align); - if (aligni <= 1 - || (aligni & (aligni - 1)) != 0) - return ptrval; - if (gimple_call_num_args (stmt) > 2) + if (attr == NULL_TREE) { - misalign = gimple_call_arg (stmt, 2); - if (!tree_fits_uhwi_p (misalign)) + /* Get aligni and misaligni from __builtin_assume_aligned. */ + align = gimple_call_arg (stmt, 1); + if (!tree_fits_uhwi_p (align)) return ptrval; - misaligni = tree_to_uhwi (misalign); - if (misaligni >= aligni) + aligni = tree_to_uhwi (align); + if (gimple_call_num_args (stmt) > 2) + { + misalign = gimple_call_arg (stmt, 2); + if (!tree_fits_uhwi_p (misalign)) + return ptrval; + misaligni = tree_to_uhwi (misalign); + } + } + else + { + /* Get aligni and misaligni from assume_aligned or + alloc_align attributes. */ + if (TREE_VALUE (attr) == NULL_TREE) + return ptrval; + attr = TREE_VALUE (attr); + align = TREE_VALUE (attr); + if (!tree_fits_uhwi_p (align)) return ptrval; + aligni = tree_to_uhwi (align); + if (alloc_aligned) + { + if (aligni == 0 || aligni > gimple_call_num_args (stmt)) + return ptrval; + align = gimple_call_arg (stmt, aligni - 1); + if (!tree_fits_uhwi_p (align)) + return ptrval; + aligni = tree_to_uhwi (align); + } + else if (TREE_CHAIN (attr) && TREE_VALUE (TREE_CHAIN (attr))) + { + misalign = TREE_VALUE (TREE_CHAIN (attr)); + if (!tree_fits_uhwi_p (misalign)) + return ptrval; + misaligni = tree_to_uhwi (misalign); + } } + if (aligni <= 1 || (aligni & (aligni - 1)) != 0 || misaligni >= aligni) + return ptrval; + align = build_int_cst_type (type, -aligni); alignval = get_value_for_expr (align, true); bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask, @@ -1708,12 +1759,27 @@ evaluate_stmt (gimple stmt) break; case BUILT_IN_ASSUME_ALIGNED: - val = bit_value_assume_aligned (stmt); + val = bit_value_assume_aligned (stmt, NULL_TREE, val, false); break; default:; } } + if (is_gimple_call (stmt) && gimple_call_lhs (stmt)) + { + tree fntype = gimple_call_fntype (stmt); + if (fntype) + { + tree attrs = lookup_attribute ("assume_aligned", + TYPE_ATTRIBUTES (fntype)); + if (attrs) + val = bit_value_assume_aligned (stmt, attrs, val, false); + attrs = lookup_attribute ("alloc_align", + TYPE_ATTRIBUTES (fntype)); + if (attrs) + val = bit_value_assume_aligned (stmt, attrs, val, true); + } + } is_constant = (val.lattice_val == CONSTANT); } |