diff options
author | Richard Guenther <rguenther@suse.de> | 2012-07-18 10:46:05 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-07-18 10:46:05 +0000 |
commit | 4c9bcf893467201acbdc6944c8c2d0cbe67972dc (patch) | |
tree | a29a811549836915e77e5838f455d345d6548dd7 /gcc | |
parent | b0f4a35f73d421cac856149de1756a51d833adb3 (diff) | |
download | gcc-4c9bcf893467201acbdc6944c8c2d0cbe67972dc.zip gcc-4c9bcf893467201acbdc6944c8c2d0cbe67972dc.tar.gz gcc-4c9bcf893467201acbdc6944c8c2d0cbe67972dc.tar.bz2 |
re PR tree-optimization/53970 (-ftree-vectorization does not handle well unaligned data)
2012-07-18 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53970
* tree.h (contains_packed_reference): Remove.
* expr.c (contains_packed_reference): Likewise.
* tree-vect-data-refs.c (not_size_aligned): New function.
(vector_alignment_reachable_p): Use it.
(vect_supportable_dr_alignment): Likewise.
* g++.dg/torture/pr53970.C: New testcase.
From-SVN: r189609
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/expr.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr53970.C | 17 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 24 | ||||
-rw-r--r-- | gcc/tree.h | 6 |
6 files changed, 47 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff47965..eda5fb6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2012-07-18 Richard Guenther <rguenther@suse.de> + PR tree-optimization/53970 + * tree.h (contains_packed_reference): Remove. + * expr.c (contains_packed_reference): Likewise. + * tree-vect-data-refs.c (not_size_aligned): New function. + (vector_alignment_reachable_p): Use it. + (vect_supportable_dr_alignment): Likewise. + +2012-07-18 Richard Guenther <rguenther@suse.de> + * tree.h (get_object_or_type_alignment): Remove. * builtins.c (get_object_alignment_2): New function copied from get_object_alignment_1. Take extra argument to indicate whether @@ -6709,47 +6709,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, return exp; } -/* Given an expression EXP that may be a COMPONENT_REF, an ARRAY_REF or an - ARRAY_RANGE_REF, look for whether EXP or any nested component-refs within - EXP is marked as PACKED. */ - -bool -contains_packed_reference (const_tree exp) -{ - bool packed_p = false; - - while (1) - { - switch (TREE_CODE (exp)) - { - case COMPONENT_REF: - { - tree field = TREE_OPERAND (exp, 1); - packed_p = DECL_PACKED (field) - || TYPE_PACKED (TREE_TYPE (field)) - || TYPE_PACKED (TREE_TYPE (exp)); - if (packed_p) - goto done; - } - break; - - case BIT_FIELD_REF: - case ARRAY_REF: - case ARRAY_RANGE_REF: - case REALPART_EXPR: - case IMAGPART_EXPR: - case VIEW_CONVERT_EXPR: - break; - - default: - goto done; - } - exp = TREE_OPERAND (exp, 0); - } - done: - return packed_p; -} - /* Return a tree of sizetype representing the size, in bytes, of the element of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5477d41..b046c68 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-18 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/53970 + * g++.dg/torture/pr53970.C: New testcase. + 2012-07-18 Oleg Endo <olegendo@gcc.gnu.org> PR target/38621 diff --git a/gcc/testsuite/g++.dg/torture/pr53970.C b/gcc/testsuite/g++.dg/torture/pr53970.C new file mode 100644 index 0000000..53cbc1f --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr53970.C @@ -0,0 +1,17 @@ +// { dg-do run } + +#pragma pack(1) +struct mystruct { + char c; + unsigned long l[1024]; +}; +#pragma pack() + +int main(int argc, char **argv) +{ + mystruct *a = new mystruct; + unsigned long i; + for (i = 0; i < 1024; ++i) + a->l[i] = 0xdeadbeaf; + return 0; +} diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index dd0752e..147fa90 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -1131,6 +1131,18 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) return true; } +/* Given an memory reference EXP return whether its alignment is less + than its size. */ + +static bool +not_size_aligned (tree exp) +{ + if (!host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)) + return true; + + return (tree_low_cst (TYPE_SIZE (TREE_TYPE (exp)), 1) + > get_object_alignment (exp)); +} /* Function vector_alignment_reachable_p @@ -1184,12 +1196,8 @@ vector_alignment_reachable_p (struct data_reference *dr) if (!known_alignment_for_access_p (dr)) { - tree type = (TREE_TYPE (DR_REF (dr))); - bool is_packed = contains_packed_reference (DR_REF (dr)); - - if (compare_tree_int (TYPE_SIZE (type), TYPE_ALIGN (type)) > 0) - is_packed = true; - + tree type = TREE_TYPE (DR_REF (dr)); + bool is_packed = not_size_aligned (DR_REF (dr)); if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed); if (targetm.vectorize.vector_alignment_reachable (type, is_packed)) @@ -4863,7 +4871,7 @@ vect_supportable_dr_alignment (struct data_reference *dr, return dr_explicit_realign_optimized; } if (!known_alignment_for_access_p (dr)) - is_packed = contains_packed_reference (DR_REF (dr)); + is_packed = not_size_aligned (DR_REF (dr)); if (targetm.vectorize. support_vector_misalignment (mode, type, @@ -4877,7 +4885,7 @@ vect_supportable_dr_alignment (struct data_reference *dr, tree type = (TREE_TYPE (DR_REF (dr))); if (!known_alignment_for_access_p (dr)) - is_packed = contains_packed_reference (DR_REF (dr)); + is_packed = not_size_aligned (DR_REF (dr)); if (targetm.vectorize. support_vector_misalignment (mode, type, @@ -5068,12 +5068,6 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, tree *, enum machine_mode *, int *, int *, bool); -/* Given an expression EXP that may be a COMPONENT_REF, an ARRAY_REF or an - ARRAY_RANGE_REF, look for whether EXP or any nested component-refs within - EXP is marked as PACKED. */ - -extern bool contains_packed_reference (const_tree exp); - /* Return a tree of sizetype representing the size, in bytes, of the element of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ |