aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-03-19 15:25:16 +0100
committerRichard Biener <rguenther@suse.de>2024-03-20 09:16:38 +0100
commit6a55e39bdb1fdb570730c08413ebbe744e493411 (patch)
treee0acdc9253c93afc2cd5f81018073d6634fd5d93
parent994d8f922b9d88f45775f57a490409ab1c3baf59 (diff)
downloadgcc-6a55e39bdb1fdb570730c08413ebbe744e493411.zip
gcc-6a55e39bdb1fdb570730c08413ebbe744e493411.tar.gz
gcc-6a55e39bdb1fdb570730c08413ebbe744e493411.tar.bz2
middle-end/113396 - int128 array index and value-ranges
The following fixes bogus truncation of a value-range for an int128 array index when computing the maximum extent for a variable array reference. Instead of possibly slowing things down by using widest_int the following makes sure the range bounds fit within the constraints offset_int were designed for. PR middle-end/113396 * tree-dfa.cc (get_ref_base_and_extent): Use index range bounds only if they fit within the address-range constraints of offset_int. * gcc.dg/torture/pr113396.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr113396.c19
-rw-r--r--gcc/tree-dfa.cc6
2 files changed, 23 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr113396.c b/gcc/testsuite/gcc.dg/torture/pr113396.c
new file mode 100644
index 0000000..585f717
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr113396.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+
+unsigned char m[] = {5, 79, 79, 79, 79};
+__int128 p;
+int main()
+{
+ int g1 = 0;
+ p = 0;
+ for (int aj = 0; aj < 256; aj++)
+ {
+ m[0] = -4;
+ for (; p >= 0; p -= 1) {
+ g1 = m[p];
+ }
+ }
+ if (g1 != 0xfc)
+ __builtin_abort();
+}
diff --git a/gcc/tree-dfa.cc b/gcc/tree-dfa.cc
index cbd3774..93e53b2 100644
--- a/gcc/tree-dfa.cc
+++ b/gcc/tree-dfa.cc
@@ -549,7 +549,8 @@ get_ref_base_and_extent (tree exp, poly_int64 *poffset,
/* Try to constrain maxsize with range information. */
offset_int omax
= offset_int::from (max, TYPE_SIGN (TREE_TYPE (index)));
- if (known_lt (lbound, omax))
+ if (wi::get_precision (max) <= ADDR_MAX_BITSIZE
+ && known_lt (lbound, omax))
{
poly_offset_int rmaxsize;
rmaxsize = (omax - lbound + 1)
@@ -567,7 +568,8 @@ get_ref_base_and_extent (tree exp, poly_int64 *poffset,
/* Try to adjust bit_offset with range information. */
offset_int omin
= offset_int::from (min, TYPE_SIGN (TREE_TYPE (index)));
- if (known_le (lbound, omin))
+ if (wi::get_precision (min) <= ADDR_MAX_BITSIZE
+ && known_le (lbound, omin))
{
poly_offset_int woffset
= wi::sext (omin - lbound,