Commit 90ff582f by Richard Guenther Committed by Richard Biener

re PR tree-optimization/49079 (Bogus constant folding)

2011-05-20  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/49079
	* tree-dfa.c (get_ref_base_and_extent): Handle view-converting
	MEM_REFs correctly for the trailing array access detection.
	Special case constants the same way as decls for overall size
	constraining.

	* gcc.dg/torture/pr49079.c: New testcase.

From-SVN: r173954
parent 3cda91d8
2011-05-20 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49079
* tree-dfa.c (get_ref_base_and_extent): Handle view-converting
MEM_REFs correctly for the trailing array access detection.
Special case constants the same way as decls for overall size
constraining.
2011-05-20 Uros Bizjak <ubizjak@gmail.com> 2011-05-20 Uros Bizjak <ubizjak@gmail.com>
* config/i386/mingw32.h (OUTPUT_QUOTED_STRING): Fix macro * config/i386/mingw32.h (OUTPUT_QUOTED_STRING): Fix macro
......
2011-05-20 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49079
* gcc.dg/torture/pr49079.c: New testcase.
2011-05-20 Jakub Jelinek <jakub@redhat.com> 2011-05-20 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/49073 PR tree-optimization/49073
......
/* { dg-do run } */
extern void abort (void);
struct Ustr
{
unsigned char data[1];
};
static unsigned int
ustr_xi__embed_val_get(const unsigned char *data)
{
return (unsigned int)data[0];
}
int __attribute__((noinline)) zero(void) { return 0; }
static unsigned int
ustr_len(const struct Ustr *s1)
{
return ustr_xi__embed_val_get(s1->data + 1 + zero());
}
int
main()
{
if (ustr_len (((struct Ustr *) "\x01" "\x0002" "s2")) != 2)
abort ();
return 0;
}
...@@ -714,6 +714,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -714,6 +714,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
tree size_tree = NULL_TREE; tree size_tree = NULL_TREE;
HOST_WIDE_INT bit_offset = 0; HOST_WIDE_INT bit_offset = 0;
bool seen_variable_array_ref = false; bool seen_variable_array_ref = false;
tree base_type;
/* First get the final access size from just the outermost expression. */ /* First get the final access size from just the outermost expression. */
if (TREE_CODE (exp) == COMPONENT_REF) if (TREE_CODE (exp) == COMPONENT_REF)
...@@ -744,6 +745,8 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -744,6 +745,8 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
and find the ultimate containing object. */ and find the ultimate containing object. */
while (1) while (1)
{ {
base_type = TREE_TYPE (exp);
switch (TREE_CODE (exp)) switch (TREE_CODE (exp))
{ {
case BIT_FIELD_REF: case BIT_FIELD_REF:
...@@ -931,9 +934,16 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -931,9 +934,16 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
the array. The simplest way to conservatively deal with this the array. The simplest way to conservatively deal with this
is to punt in the case that offset + maxsize reaches the is to punt in the case that offset + maxsize reaches the
base type boundary. This needs to include possible trailing padding base type boundary. This needs to include possible trailing padding
that is there for alignment purposes. that is there for alignment purposes. */
That is of course only true if the base object is not a decl. */ if (seen_variable_array_ref
&& maxsize != -1
&& (!host_integerp (TYPE_SIZE (base_type), 1)
|| (bit_offset + maxsize
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (base_type)))))
maxsize = -1;
/* In case of a decl or constant base object we can do better. */
if (DECL_P (exp)) if (DECL_P (exp))
{ {
...@@ -943,12 +953,14 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, ...@@ -943,12 +953,14 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
&& host_integerp (DECL_SIZE (exp), 1)) && host_integerp (DECL_SIZE (exp), 1))
maxsize = TREE_INT_CST_LOW (DECL_SIZE (exp)) - bit_offset; maxsize = TREE_INT_CST_LOW (DECL_SIZE (exp)) - bit_offset;
} }
else if (seen_variable_array_ref else if (CONSTANT_CLASS_P (exp))
&& maxsize != -1 {
&& (!host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1) /* If maxsize is unknown adjust it according to the size of the
|| (bit_offset + maxsize base type constant. */
== (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))))) if (maxsize == -1
maxsize = -1; && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1))
maxsize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))) - bit_offset;
}
/* ??? Due to negative offsets in ARRAY_REF we can end up with /* ??? Due to negative offsets in ARRAY_REF we can end up with
negative bit_offset here. We might want to store a zero offset negative bit_offset here. We might want to store a zero offset
......
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