]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorMartin Liska <mliska@suse.cz>
Tue, 14 Feb 2017 10:45:31 +0000 (11:45 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 14 Feb 2017 10:45:31 +0000 (10:45 +0000)
2016-03-01  Richard Biener  <rguenther@suse.de>

2017-02-14  Martin Liska  <mliska@suse.cz>

Backport from mainline
2016-03-01  Richard Biener  <rguenther@suse.de>

PR middle-end/70022
PR target/79498
* fold-const.c (fold_indirect_ref_1): Fix range checking for
vector BIT_FIELD_REF extract.

From-SVN: r245426

gcc/ChangeLog
gcc/fold-const.c

index 1f02d717b6be3513be4520a93bf5a08eb6fc9f79..c7452e1b3cc77703193acc88fec00c345ca526a1 100644 (file)
@@ -1,3 +1,13 @@
+2017-02-14  Martin Liska  <mliska@suse.cz>
+
+       Backport from mainline
+       2016-03-01  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70022
+       PR target/79498
+       * fold-const.c (fold_indirect_ref_1): Fix range checking for
+       vector BIT_FIELD_REF extract.
+
 2017-02-14  Martin Liska  <mliska@suse.cz>
 
        Backport from mainline
index fa58a5a6aab6ce2bfe1acf9891d9ae6d3da03923..7adefba83cbc1244dbcff239bf785654cc07a08c 100644 (file)
@@ -15942,17 +15942,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