diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 8 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 31 |
3 files changed, 37 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8afb6f8..5fd4298 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2010-07-02 Richard Guenther <rguenther@suse.de> + * tree-ssa-structalias.c (find_func_aliases): Handle + pointer alignment via BIT_AND_EXPR. + * tree-vrp.c (extract_range_from_binary_expr): Likewise. + +2010-07-02 Richard Guenther <rguenther@suse.de> + * tree-data-ref.c (initialize_data_dependence_relation): Handle mismatching number of dimensions properly. diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 77ff17a..b0efcfa 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4395,6 +4395,14 @@ find_func_aliases (gimple origt) if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR) get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), gimple_assign_rhs2 (t), &rhsc); + else if (gimple_assign_rhs_code (t) == BIT_AND_EXPR + && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) + { + /* Aligning a pointer via a BIT_AND_EXPR is offsetting + the pointer. Handle it by offsetting it by UNKNOWN. */ + get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), + NULL_TREE, &rhsc); + } else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t)) && !(POINTER_TYPE_P (gimple_expr_type (t)) && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 4f5db80..74b3a7a 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2188,15 +2188,30 @@ extract_range_from_binary_expr (value_range_t *vr, return; } - gcc_assert (code == POINTER_PLUS_EXPR); - /* For pointer types, we are really only interested in asserting - whether the expression evaluates to non-NULL. */ - if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) - set_value_range_to_nonnull (vr, expr_type); - else if (range_is_null (&vr0) && range_is_null (&vr1)) - set_value_range_to_null (vr, expr_type); + if (code == POINTER_PLUS_EXPR) + { + /* For pointer types, we are really only interested in asserting + whether the expression evaluates to non-NULL. */ + if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) + set_value_range_to_nonnull (vr, expr_type); + else if (range_is_null (&vr0) && range_is_null (&vr1)) + set_value_range_to_null (vr, expr_type); + else + set_value_range_to_varying (vr); + } + else if (code == BIT_AND_EXPR) + { + /* For pointer types, we are really only interested in asserting + whether the expression evaluates to non-NULL. */ + if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1)) + set_value_range_to_nonnull (vr, expr_type); + else if (range_is_null (&vr0) || range_is_null (&vr1)) + set_value_range_to_null (vr, expr_type); + else + set_value_range_to_varying (vr); + } else - set_value_range_to_varying (vr); + gcc_unreachable (); return; } |