Commit a2001d44 by Richard Biener Committed by Richard Biener

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
parent 96d5c6dc
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> 2019-08-05 Jakub Jelinek <jakub@redhat.com>
PR target/91341 PR target/91341
......
...@@ -11850,6 +11850,7 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index, ...@@ -11850,6 +11850,7 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
unsigned *ctor_idx) unsigned *ctor_idx)
{ {
tree index_type = NULL_TREE; tree index_type = NULL_TREE;
signop index_sgn = UNSIGNED;
offset_int low_bound = 0; offset_int low_bound = 0;
if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE) if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
...@@ -11860,22 +11861,37 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index, ...@@ -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. */ /* Static constructors for variably sized objects makes no sense. */
gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST); gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type)); index_type = TREE_TYPE (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)); low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
} }
} }
}
if (index_type) if (index_type)
access_index = wi::ext (access_index, TYPE_PRECISION (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) if (index_type)
index = wi::ext (index, TYPE_PRECISION (index_type), index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
TYPE_SIGN (index_type));
offset_int max_index; offset_int max_index = index;
unsigned cnt; unsigned cnt;
tree cfield, cval; tree cfield, cval;
bool first_p = true;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) 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, ...@@ -11885,27 +11901,34 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
if (cfield) if (cfield)
{ {
if (TREE_CODE (cfield) == INTEGER_CST) 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 else
{ {
gcc_assert (TREE_CODE (cfield) == RANGE_EXPR); gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
index = wi::to_offset (TREE_OPERAND (cfield, 0)); index = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 0)),
max_index = wi::to_offset (TREE_OPERAND (cfield, 1)); 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) if (index_type)
index = wi::ext (index, TYPE_PRECISION (index_type), index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
TYPE_SIGN (index_type)); gcc_checking_assert (wi::gt_p (index, max_index, index_sgn));
max_index = index; max_index = index;
} }
else
first_p = false;
/* Do we have match? */ /* 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) if (ctor_idx)
*ctor_idx = cnt; *ctor_idx = cnt;
......
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> 2019-08-05 Jakub Jelinek <jakub@redhat.com>
PR target/91341 PR target/91341
......
-- { 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment