re PR middle-end/70022 (ICE: in tree_to_shwi, at tree.c:7328 with out-of-bounds vecto...
authorRichard Biener <rguenther@suse.de>
Tue, 1 Mar 2016 13:32:13 +0000 (13:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 1 Mar 2016 13:32:13 +0000 (13:32 +0000)
2016-03-01  Richard Biener  <rguenther@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.

From-SVN: r233852

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr70022.c [new file with mode: 0644]

index 9ee5a2e..c210534 100644 (file)
@@ -1,5 +1,11 @@
 2016-03-01  Richard Biener  <rguenther@suse.de>
 
+       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  <rguenther@suse.de>
+
        PR tree-optimization/69994
        * tree-ssa-reassoc.c (ops_equal_values_p): Handle missing case.
 
index 5376d4d..21241db 100644 (file)
@@ -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
index c0eaa55..5099182 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-01  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70022
+       * gcc.dg/pr70022.c: New testcase.
+
 2016-03-01  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        PR tree-optimization/69956
diff --git a/gcc/testsuite/gcc.dg/pr70022.c b/gcc/testsuite/gcc.dg/pr70022.c
new file mode 100644 (file)
index 0000000..c7e60b8
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+int
+foo (v4si v)
+{
+  return v[~0UL];
+}