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];
+ }

Reply via email to