On March 13, 2014 6:50:53 PM CET, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >The outer-1.c testcase apparently fails on 32-bit HWI targets, the >problem >is that the int x[10000][10000]; array has bitsize that fits into uhwi, >but >not shwi, so we get negative maxsize that isn't -1. > >After discussions with Richard on IRC, I've implemented computation of >bitsize and maxsize in double_int. > >Bootstrapped/regtested on x86_64-linux and i686-linux, with >bootstrap/regtest time changes in the noise. Ok for trunk?
OK. Thanks, Richard. >John, could you please test this on some 32-bit HWI target with >bootstrap/regtest? > >2014-03-13 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/59779 > * tree-dfa.c (get_ref_base_and_extent): Use double_int > type for bitsize and maxsize instead of HOST_WIDE_INT. > >--- gcc/tree-dfa.c.jj 2014-01-03 11:40:57.000000000 +0100 >+++ gcc/tree-dfa.c 2014-03-13 12:10:46.367886640 +0100 >@@ -389,11 +389,10 @@ get_ref_base_and_extent (tree exp, HOST_ > HOST_WIDE_INT *psize, > HOST_WIDE_INT *pmax_size) > { >- HOST_WIDE_INT bitsize = -1; >- HOST_WIDE_INT maxsize = -1; >+ double_int bitsize = double_int_minus_one; >+ double_int maxsize; > tree size_tree = NULL_TREE; > double_int bit_offset = double_int_zero; >- HOST_WIDE_INT hbit_offset; > bool seen_variable_array_ref = false; > >/* First get the final access size from just the outermost expression. >*/ >@@ -407,15 +406,11 @@ get_ref_base_and_extent (tree exp, HOST_ > if (mode == BLKmode) > size_tree = TYPE_SIZE (TREE_TYPE (exp)); > else >- bitsize = GET_MODE_BITSIZE (mode); >- } >- if (size_tree != NULL_TREE) >- { >- if (! tree_fits_uhwi_p (size_tree)) >- bitsize = -1; >- else >- bitsize = tree_to_uhwi (size_tree); >+ bitsize = double_int::from_uhwi (GET_MODE_BITSIZE (mode)); > } >+ if (size_tree != NULL_TREE >+ && TREE_CODE (size_tree) == INTEGER_CST) >+ bitsize = tree_to_double_int (size_tree); > > /* Initially, maxsize is the same as the accessed element size. > In the following it will only grow (or become -1). */ >@@ -448,7 +443,7 @@ get_ref_base_and_extent (tree exp, HOST_ > referenced the last field of a struct or a union member > then we have to adjust maxsize by the padding at the end > of our field. */ >- if (seen_variable_array_ref && maxsize != -1) >+ if (seen_variable_array_ref && !maxsize.is_minus_one ()) > { > tree stype = TREE_TYPE (TREE_OPERAND (exp, 0)); > tree next = DECL_CHAIN (field); >@@ -459,15 +454,22 @@ get_ref_base_and_extent (tree exp, HOST_ > { > tree fsize = DECL_SIZE_UNIT (field); > tree ssize = TYPE_SIZE_UNIT (stype); >- if (tree_fits_shwi_p (fsize) >- && tree_fits_shwi_p (ssize) >- && doffset.fits_shwi ()) >- maxsize += ((tree_to_shwi (ssize) >- - tree_to_shwi (fsize)) >- * BITS_PER_UNIT >- - doffset.to_shwi ()); >+ if (fsize == NULL >+ || TREE_CODE (fsize) != INTEGER_CST >+ || ssize == NULL >+ || TREE_CODE (ssize) != INTEGER_CST) >+ maxsize = double_int_minus_one; > else >- maxsize = -1; >+ { >+ double_int tem = tree_to_double_int (ssize) >+ - tree_to_double_int (fsize); >+ if (BITS_PER_UNIT == 8) >+ tem = tem.lshift (3); >+ else >+ tem *= double_int::from_uhwi (BITS_PER_UNIT); >+ tem -= doffset; >+ maxsize += tem; >+ } > } > } > } >@@ -477,13 +479,12 @@ get_ref_base_and_extent (tree exp, HOST_ > /* We need to adjust maxsize to the whole structure bitsize. > But we can subtract any constant offset seen so far, > because that would get us out of the structure otherwise. */ >- if (maxsize != -1 >+ if (!maxsize.is_minus_one () > && csize >- && tree_fits_uhwi_p (csize) >- && bit_offset.fits_shwi ()) >- maxsize = tree_to_uhwi (csize) - bit_offset.to_shwi (); >+ && TREE_CODE (csize) == INTEGER_CST) >+ maxsize = tree_to_double_int (csize) - bit_offset; > else >- maxsize = -1; >+ maxsize = double_int_minus_one; > } > } > break; >@@ -520,13 +521,12 @@ get_ref_base_and_extent (tree exp, HOST_ > /* We need to adjust maxsize to the whole array bitsize. > But we can subtract any constant offset seen so far, > because that would get us outside of the array otherwise. */ >- if (maxsize != -1 >+ if (!maxsize.is_minus_one () > && asize >- && tree_fits_uhwi_p (asize) >- && bit_offset.fits_shwi ()) >- maxsize = tree_to_uhwi (asize) - bit_offset.to_shwi (); >+ && TREE_CODE (asize) == INTEGER_CST) >+ maxsize = tree_to_double_int (asize) - bit_offset; > else >- maxsize = -1; >+ maxsize = double_int_minus_one; > > /* Remember that we have seen an array ref with a variable > index. */ >@@ -539,7 +539,7 @@ get_ref_base_and_extent (tree exp, HOST_ > break; > > case IMAGPART_EXPR: >- bit_offset += double_int::from_uhwi (bitsize); >+ bit_offset += bitsize; > break; > > case VIEW_CONVERT_EXPR: >@@ -553,7 +553,7 @@ get_ref_base_and_extent (tree exp, HOST_ > { > exp = TREE_OPERAND (TMR_BASE (exp), 0); > bit_offset = double_int_zero; >- maxsize = -1; >+ maxsize = double_int_minus_one; > goto done; > } > /* Fallthru. */ >@@ -569,13 +569,12 @@ get_ref_base_and_extent (tree exp, HOST_ > base type boundary. This needs to include possible trailing > padding that is there for alignment purposes. */ > if (seen_variable_array_ref >- && maxsize != -1 >- && (!bit_offset.fits_shwi () >- || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp))) >- || (bit_offset.to_shwi () + maxsize >- == (HOST_WIDE_INT) tree_to_uhwi >- (TYPE_SIZE (TREE_TYPE (exp)))))) >- maxsize = -1; >+ && !maxsize.is_minus_one () >+ && (TYPE_SIZE (TREE_TYPE (exp)) == NULL_TREE >+ || TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST >+ || (bit_offset + maxsize >+ == tree_to_double_int (TYPE_SIZE (TREE_TYPE (exp)))))) >+ maxsize = double_int_minus_one; > > /* Hand back the decl for MEM[&decl, off]. */ > if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR) >@@ -606,25 +605,32 @@ get_ref_base_and_extent (tree exp, HOST_ > > /* We need to deal with variable arrays ending structures. */ > if (seen_variable_array_ref >- && maxsize != -1 >- && (!bit_offset.fits_shwi () >- || !tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp))) >- || (bit_offset.to_shwi () + maxsize >- == (HOST_WIDE_INT) tree_to_uhwi >- (TYPE_SIZE (TREE_TYPE (exp)))))) >- maxsize = -1; >+ && !maxsize.is_minus_one () >+ && (TYPE_SIZE (TREE_TYPE (exp)) == NULL_TREE >+ || TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST >+ || (bit_offset + maxsize >+ == tree_to_double_int (TYPE_SIZE (TREE_TYPE (exp)))))) >+ maxsize = double_int_minus_one; > > done: >- if (!bit_offset.fits_shwi ()) >+ if (!bitsize.fits_shwi () || bitsize.is_negative ()) > { > *poffset = 0; >- *psize = bitsize; >+ *psize = -1; > *pmax_size = -1; > > return exp; > } > >- hbit_offset = bit_offset.to_shwi (); >+ *psize = bitsize.to_shwi (); >+ >+ if (!bit_offset.fits_shwi ()) >+ { >+ *poffset = 0; >+ *pmax_size = -1; >+ >+ return exp; >+ } > > /* In case of a decl or constant base object we can do better. */ > >@@ -632,25 +638,30 @@ get_ref_base_and_extent (tree exp, HOST_ > { > /* If maxsize is unknown adjust it according to the size of the > base decl. */ >- if (maxsize == -1 >- && tree_fits_uhwi_p (DECL_SIZE (exp))) >- maxsize = tree_to_uhwi (DECL_SIZE (exp)) - hbit_offset; >+ if (maxsize.is_minus_one () >+ && DECL_SIZE (exp) >+ && TREE_CODE (DECL_SIZE (exp)) == INTEGER_CST) >+ maxsize = tree_to_double_int (DECL_SIZE (exp)) - bit_offset; > } > else if (CONSTANT_CLASS_P (exp)) > { > /* If maxsize is unknown adjust it according to the size of the > base type constant. */ >- if (maxsize == -1 >- && tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp)))) >- maxsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (exp))) - hbit_offset; >+ if (maxsize.is_minus_one () >+ && TYPE_SIZE (TREE_TYPE (exp)) >+ && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST) >+ maxsize = tree_to_double_int (TYPE_SIZE (TREE_TYPE (exp))) >+ - bit_offset; > } > > /* ??? Due to negative offsets in ARRAY_REF we can end up with > negative bit_offset here. We might want to store a zero offset > in this case. */ >- *poffset = hbit_offset; >- *psize = bitsize; >- *pmax_size = maxsize; >+ *poffset = bit_offset.to_shwi (); >+ if (!maxsize.fits_shwi () || maxsize.is_negative ()) >+ *pmax_size = -1; >+ else >+ *pmax_size = maxsize.to_shwi (); > > return exp; > } > > Jakub