diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ee5a2e50c47..c210534796ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-03-01 Richard Biener + + PR middle-end/70022 + * fold-const.c (fold_indirect_ref_1): Fix range checking for + vector BIT_FIELD_REF extract. + 2016-03-01 Richard Biener PR tree-optimization/69994 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5376d4d499c0..21241db5a49c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14218,17 +14218,20 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) if (TREE_CODE (op00type) == VECTOR_TYPE && type == TREE_TYPE (op00type)) { - HOST_WIDE_INT offset = tree_to_shwi (op01); tree part_width = TYPE_SIZE (type); - unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT; - unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; - tree index = bitsize_int (indexi); - - if (offset / part_widthi < TYPE_VECTOR_SUBPARTS (op00type)) - return fold_build3_loc (loc, - BIT_FIELD_REF, type, op00, - part_width, index); - + unsigned HOST_WIDE_INT max_offset + = (tree_to_uhwi (part_width) / BITS_PER_UNIT + * TYPE_VECTOR_SUBPARTS (op00type)); + if (tree_int_cst_sign_bit (op01) == 0 + && compare_tree_int (op01, max_offset) == -1) + { + unsigned HOST_WIDE_INT offset = tree_to_uhwi (op01); + unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; + tree index = bitsize_int (indexi); + return fold_build3_loc (loc, + BIT_FIELD_REF, type, op00, + part_width, index); + } } /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ else if (TREE_CODE (op00type) == COMPLEX_TYPE diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c0eaa55926b0..50991821f2ba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-03-01 Richard Biener + + PR middle-end/70022 + * gcc.dg/pr70022.c: New testcase. + 2016-03-01 Ilya Enkovich PR tree-optimization/69956 diff --git a/gcc/testsuite/gcc.dg/pr70022.c b/gcc/testsuite/gcc.dg/pr70022.c new file mode 100644 index 000000000000..c7e60b8f1534 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr70022.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ + +typedef int v4si __attribute__ ((vector_size (16))); + +int +foo (v4si v) +{ + return v[~0UL]; +}