aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-08-05 12:30:49 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-08-05 12:30:49 +0000
commita2001d445a5ff419c27241019c85f1e033d89d67 (patch)
treedc77436e1a45df7a781ad4909f4d5a16fd3c9700
parent96d5c6dcf6b8ec0ad34a8208fc6d82df3ce20e2a (diff)
downloadgcc-a2001d445a5ff419c27241019c85f1e033d89d67.zip
gcc-a2001d445a5ff419c27241019c85f1e033d89d67.tar.gz
gcc-a2001d445a5ff419c27241019c85f1e033d89d67.tar.bz2
re PR tree-optimization/91169 (cd2a31a FAILs)
2019-08-05 Richard Biener <rguenther@suse.de> PR middle-end/91169 * fold-const.c (get_array_ctor_element_at_index): Create offset_ints according to the sign of the index type and treat that as signed if it is obviously so. * gnat.dg/array37.adb: New testcase. From-SVN: r274114
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c53
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/array37.adb19
4 files changed, 69 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 121da52..c118e4d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2019-08-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91169
+ * fold-const.c (get_array_ctor_element_at_index): Create
+ offset_ints according to the sign of the index type and treat
+ that as signed if it is obviously so.
+
2019-08-05 Jakub Jelinek <jakub@redhat.com>
PR target/91341
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0a24101..716d739 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -11850,6 +11850,7 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
unsigned *ctor_idx)
{
tree index_type = NULL_TREE;
+ signop index_sgn = UNSIGNED;
offset_int low_bound = 0;
if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
@@ -11860,22 +11861,37 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
/* Static constructors for variably sized objects makes no sense. */
gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
- low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
+ /* ??? When it is obvious that the range is signed, treat it so. */
+ if (TYPE_UNSIGNED (index_type)
+ && TYPE_MAX_VALUE (domain_type)
+ && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type),
+ TYPE_MIN_VALUE (domain_type)))
+ {
+ index_sgn = SIGNED;
+ low_bound
+ = offset_int::from (wi::to_wide (TYPE_MIN_VALUE (domain_type)),
+ SIGNED);
+ }
+ else
+ {
+ index_sgn = TYPE_SIGN (index_type);
+ low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
+ }
}
}
if (index_type)
access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index_sgn);
- offset_int index = low_bound - 1;
+ offset_int index = low_bound;
if (index_type)
- index = wi::ext (index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
- offset_int max_index;
+ offset_int max_index = index;
unsigned cnt;
tree cfield, cval;
+ bool first_p = true;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
{
@@ -11885,27 +11901,34 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
if (cfield)
{
if (TREE_CODE (cfield) == INTEGER_CST)
- max_index = index = wi::to_offset (cfield);
+ max_index = index
+ = offset_int::from (wi::to_wide (cfield), index_sgn);
else
{
gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
- index = wi::to_offset (TREE_OPERAND (cfield, 0));
- max_index = wi::to_offset (TREE_OPERAND (cfield, 1));
+ index = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 0)),
+ index_sgn);
+ max_index
+ = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 1)),
+ index_sgn);
+ gcc_checking_assert (wi::le_p (index, max_index, index_sgn));
}
}
- else
+ else if (!first_p)
{
- index += 1;
+ index = max_index + 1;
if (index_type)
- index = wi::ext (index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
+ gcc_checking_assert (wi::gt_p (index, max_index, index_sgn));
max_index = index;
}
+ else
+ first_p = false;
/* Do we have match? */
- if (wi::cmpu (access_index, index) >= 0)
+ if (wi::cmp (access_index, index, index_sgn) >= 0)
{
- if (wi::cmpu (access_index, max_index) <= 0)
+ if (wi::cmp (access_index, max_index, index_sgn) <= 0)
{
if (ctor_idx)
*ctor_idx = cnt;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e19f136..5dc9d11 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91169
+ * gnat.dg/array37.adb: New testcase.
+
2019-08-05 Jakub Jelinek <jakub@redhat.com>
PR target/91341
diff --git a/gcc/testsuite/gnat.dg/array37.adb b/gcc/testsuite/gnat.dg/array37.adb
new file mode 100644
index 0000000..f1ee385
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/array37.adb
@@ -0,0 +1,19 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+procedure Array37 is
+
+ type Arr is array (Integer range -1 .. 1) of Integer;
+
+ A : Arr := (-100, 0, 100);
+
+ function Ident (I : Integer) return Integer IS
+ begin
+ return I;
+ end;
+
+begin
+ if Ident (A (1)) <= Ident (A (0)) then
+ raise Program_Error;
+ end if;
+end;