Commit b0463d3d by Eric Botcazou Committed by Eric Botcazou

tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use offset_int for offset and…

tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use offset_int for offset and size computations instead of HOST_WIDE_INT.

	* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use offset_int for
	offset and size computations instead of HOST_WIDE_INT.

From-SVN: r227819
parent 87261d26
2015-09-16 Eric Botcazou <ebotcazou@adacore.com>
* tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Use offset_int for
offset and size computations instead of HOST_WIDE_INT.
2015-09-16 Richard Biener <rguenther@suse.de> 2015-09-16 Richard Biener <rguenther@suse.de>
PR middle-end/67442 PR middle-end/67442
......
2015-09-16 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt49.adb: New test.
2015-09-16 Richard Biener <rguenther@suse.de> 2015-09-16 Richard Biener <rguenther@suse.de>
PR middle-end/67442 PR middle-end/67442
......
-- { dg-do run }
-- { dg-options "-O -fstack-check" }
procedure Opt49 is
function Ident (I : Integer) return Integer;
pragma No_Inline (Ident);
function Ident (I : Integer) return Integer is
begin
return I;
end;
Int_0 : Integer := Ident (0);
Int_4 : Integer := Ident (4);
A : array (-4 .. Int_4) of Integer;
begin
A := (-4 , -3 , -2 , -1 , 100 , 1 , 2 , 3 , 4);
A (-4 .. Int_0) := A (Int_0 .. 4);
if A /= (100 , 1 , 2 , 3 , 4 , 1 , 2 , 3 , 4) then
raise Program_Error;
end if;
A := (-4 , -3 , -2 , -1 , 100 , 1 , 2 , 3 , 4);
A (Int_0 .. 4) := A (-4 .. Int_0);
if A /= (-4 , -3 , -2 , -1 , -4 , -3 , -2 , -1 , 100) then
raise Program_Error;
end if;
end;
...@@ -953,9 +953,9 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -953,9 +953,9 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
unsigned i; unsigned i;
tree base = NULL_TREE; tree base = NULL_TREE;
tree *op0_p = &base; tree *op0_p = &base;
HOST_WIDE_INT offset = 0; offset_int offset = 0;
HOST_WIDE_INT max_size; offset_int max_size;
HOST_WIDE_INT size = -1; offset_int size = -1;
tree size_tree = NULL_TREE; tree size_tree = NULL_TREE;
alias_set_type base_alias_set = -1; alias_set_type base_alias_set = -1;
...@@ -971,15 +971,11 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -971,15 +971,11 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
if (mode == BLKmode) if (mode == BLKmode)
size_tree = TYPE_SIZE (type); size_tree = TYPE_SIZE (type);
else else
size = GET_MODE_BITSIZE (mode); size = int (GET_MODE_BITSIZE (mode));
}
if (size_tree != NULL_TREE)
{
if (!tree_fits_uhwi_p (size_tree))
size = -1;
else
size = tree_to_uhwi (size_tree);
} }
if (size_tree != NULL_TREE
&& TREE_CODE (size_tree) == INTEGER_CST)
size = wi::to_offset (size_tree);
/* Initially, maxsize is the same as the accessed element size. /* Initially, maxsize is the same as the accessed element size.
In the following it will only grow (or become -1). */ In the following it will only grow (or become -1). */
...@@ -1034,7 +1030,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -1034,7 +1030,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
/* And now the usual component-reference style ops. */ /* And now the usual component-reference style ops. */
case BIT_FIELD_REF: case BIT_FIELD_REF:
offset += tree_to_shwi (op->op1); offset += wi::to_offset (op->op1);
break; break;
case COMPONENT_REF: case COMPONENT_REF:
...@@ -1043,15 +1039,16 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -1043,15 +1039,16 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
/* We do not have a complete COMPONENT_REF tree here so we /* We do not have a complete COMPONENT_REF tree here so we
cannot use component_ref_field_offset. Do the interesting cannot use component_ref_field_offset. Do the interesting
parts manually. */ parts manually. */
tree this_offset = DECL_FIELD_OFFSET (field);
if (op->op1 if (op->op1 || TREE_CODE (this_offset) != INTEGER_CST)
|| !tree_fits_uhwi_p (DECL_FIELD_OFFSET (field)))
max_size = -1; max_size = -1;
else else
{ {
offset += (tree_to_uhwi (DECL_FIELD_OFFSET (field)) offset_int woffset = wi::lshift (wi::to_offset (this_offset),
* BITS_PER_UNIT); LOG2_BITS_PER_UNIT);
offset += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)); woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
offset += woffset;
} }
break; break;
} }
...@@ -1059,17 +1056,18 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -1059,17 +1056,18 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
case ARRAY_RANGE_REF: case ARRAY_RANGE_REF:
case ARRAY_REF: case ARRAY_REF:
/* We recorded the lower bound and the element size. */ /* We recorded the lower bound and the element size. */
if (!tree_fits_shwi_p (op->op0) if (TREE_CODE (op->op0) != INTEGER_CST
|| !tree_fits_shwi_p (op->op1) || TREE_CODE (op->op1) != INTEGER_CST
|| !tree_fits_shwi_p (op->op2)) || TREE_CODE (op->op2) != INTEGER_CST)
max_size = -1; max_size = -1;
else else
{ {
HOST_WIDE_INT hindex = tree_to_shwi (op->op0); offset_int woffset
hindex -= tree_to_shwi (op->op1); = wi::sext (wi::to_offset (op->op0) - wi::to_offset (op->op1),
hindex *= tree_to_shwi (op->op2); TYPE_PRECISION (TREE_TYPE (op->op0)));
hindex *= BITS_PER_UNIT; woffset *= wi::to_offset (op->op2);
offset += hindex; woffset = wi::lshift (woffset, LOG2_BITS_PER_UNIT);
offset += woffset;
} }
break; break;
...@@ -1102,9 +1100,6 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -1102,9 +1100,6 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
ref->ref = NULL_TREE; ref->ref = NULL_TREE;
ref->base = base; ref->base = base;
ref->offset = offset;
ref->size = size;
ref->max_size = max_size;
ref->ref_alias_set = set; ref->ref_alias_set = set;
if (base_alias_set != -1) if (base_alias_set != -1)
ref->base_alias_set = base_alias_set; ref->base_alias_set = base_alias_set;
...@@ -1113,6 +1108,30 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ...@@ -1113,6 +1108,30 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
/* We discount volatiles from value-numbering elsewhere. */ /* We discount volatiles from value-numbering elsewhere. */
ref->volatile_p = false; ref->volatile_p = false;
if (!wi::fits_shwi_p (size) || wi::neg_p (size))
{
ref->offset = 0;
ref->size = -1;
ref->max_size = -1;
return true;
}
ref->size = size.to_shwi ();
if (!wi::fits_shwi_p (offset))
{
ref->offset = 0;
ref->max_size = -1;
return true;
}
ref->offset = offset.to_shwi ();
if (!wi::fits_shwi_p (max_size) || wi::neg_p (max_size))
ref->max_size = -1;
else
ref->max_size = max_size.to_shwi ();
return true; return true;
} }
......
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