From b0463d3db4c5dffff7c0edbbeb48a564a8476787 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 16 Sep 2015 10:02:21 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gnat.dg/opt49.adb | 31 ++++++++++++++ gcc/tree-ssa-sccvn.c | 75 +++++++++++++++++++++------------ 4 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/opt49.adb diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fca25b9b867..085de31e554 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-09-16 Eric Botcazou + + * 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 PR middle-end/67442 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9035db974d0..945db718bd0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-09-16 Eric Botcazou + + * gnat.dg/opt49.adb: New test. + 2015-09-16 Richard Biener PR middle-end/67442 diff --git a/gcc/testsuite/gnat.dg/opt49.adb b/gcc/testsuite/gnat.dg/opt49.adb new file mode 100644 index 00000000000..4b91973a19d --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt49.adb @@ -0,0 +1,31 @@ +-- { 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; diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index d9eb9f361ef..f7904e2d3ce 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -953,9 +953,9 @@ ao_ref_init_from_vn_reference (ao_ref *ref, unsigned i; tree base = NULL_TREE; tree *op0_p = &base; - HOST_WIDE_INT offset = 0; - HOST_WIDE_INT max_size; - HOST_WIDE_INT size = -1; + offset_int offset = 0; + offset_int max_size; + offset_int size = -1; tree size_tree = NULL_TREE; alias_set_type base_alias_set = -1; @@ -971,15 +971,11 @@ ao_ref_init_from_vn_reference (ao_ref *ref, if (mode == BLKmode) size_tree = TYPE_SIZE (type); else - size = 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); + size = int (GET_MODE_BITSIZE (mode)); } + 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. In the following it will only grow (or become -1). */ @@ -1034,7 +1030,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, /* And now the usual component-reference style ops. */ case BIT_FIELD_REF: - offset += tree_to_shwi (op->op1); + offset += wi::to_offset (op->op1); break; case COMPONENT_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 cannot use component_ref_field_offset. Do the interesting parts manually. */ + tree this_offset = DECL_FIELD_OFFSET (field); - if (op->op1 - || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (field))) + if (op->op1 || TREE_CODE (this_offset) != INTEGER_CST) max_size = -1; else { - offset += (tree_to_uhwi (DECL_FIELD_OFFSET (field)) - * BITS_PER_UNIT); - offset += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)); + offset_int woffset = wi::lshift (wi::to_offset (this_offset), + LOG2_BITS_PER_UNIT); + woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field)); + offset += woffset; } break; } @@ -1059,17 +1056,18 @@ ao_ref_init_from_vn_reference (ao_ref *ref, case ARRAY_RANGE_REF: case ARRAY_REF: /* We recorded the lower bound and the element size. */ - if (!tree_fits_shwi_p (op->op0) - || !tree_fits_shwi_p (op->op1) - || !tree_fits_shwi_p (op->op2)) + if (TREE_CODE (op->op0) != INTEGER_CST + || TREE_CODE (op->op1) != INTEGER_CST + || TREE_CODE (op->op2) != INTEGER_CST) max_size = -1; else { - HOST_WIDE_INT hindex = tree_to_shwi (op->op0); - hindex -= tree_to_shwi (op->op1); - hindex *= tree_to_shwi (op->op2); - hindex *= BITS_PER_UNIT; - offset += hindex; + offset_int woffset + = wi::sext (wi::to_offset (op->op0) - wi::to_offset (op->op1), + TYPE_PRECISION (TREE_TYPE (op->op0))); + woffset *= wi::to_offset (op->op2); + woffset = wi::lshift (woffset, LOG2_BITS_PER_UNIT); + offset += woffset; } break; @@ -1102,9 +1100,6 @@ ao_ref_init_from_vn_reference (ao_ref *ref, ref->ref = NULL_TREE; ref->base = base; - ref->offset = offset; - ref->size = size; - ref->max_size = max_size; ref->ref_alias_set = set; if (base_alias_set != -1) ref->base_alias_set = base_alias_set; @@ -1113,6 +1108,30 @@ ao_ref_init_from_vn_reference (ao_ref *ref, /* We discount volatiles from value-numbering elsewhere. */ 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; } -- 2.30.2