From a2001d445a5ff419c27241019c85f1e033d89d67 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 5 Aug 2019 12:30:49 +0000 Subject: [PATCH] re PR tree-optimization/91169 (cd2a31a FAILs) 2019-08-05 Richard Biener 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 --- gcc/ChangeLog | 7 ++++ gcc/fold-const.c | 53 ++++++++++++++++++++++--------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gnat.dg/array37.adb | 19 +++++++++++ 4 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/array37.adb diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 121da52b33c..c118e4ddca9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-08-05 Richard Biener + + 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 PR target/91341 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0a2410125be..716d7397b49 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 e19f136370b..5dc9d11140b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-08-05 Richard Biener + + PR middle-end/91169 + * gnat.dg/array37.adb: New testcase. + 2019-08-05 Jakub Jelinek PR target/91341 diff --git a/gcc/testsuite/gnat.dg/array37.adb b/gcc/testsuite/gnat.dg/array37.adb new file mode 100644 index 00000000000..f1ee385d1a5 --- /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; -- 2.30.2