Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard.
2016-03-01 Richard Biener <rguent...@suse.de> PR middle-end/70022 * fold-const.c (fold_indirect_ref_1): Fix range checking for vector BIT_FIELD_REF extract. * gcc.dg/pr70022.c: New testcase. Index: gcc/fold-const.c =================================================================== *** gcc/fold-const.c (revision 233840) --- gcc/fold-const.c (working copy) *************** fold_indirect_ref_1 (location_t loc, tre *** 14218,14234 **** 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); ! } /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ else if (TREE_CODE (op00type) == COMPLEX_TYPE --- 14218,14237 ---- if (TREE_CODE (op00type) == VECTOR_TYPE && type == TREE_TYPE (op00type)) { tree part_width = TYPE_SIZE (type); ! 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 Index: gcc/testsuite/gcc.dg/pr70022.c =================================================================== *** gcc/testsuite/gcc.dg/pr70022.c (revision 0) --- gcc/testsuite/gcc.dg/pr70022.c (working copy) *************** *** 0 **** --- 1,9 ---- + /* { dg-do compile } */ + + typedef int v4si __attribute__ ((vector_size (16))); + + int + foo (v4si v) + { + return v[~0UL]; + }