From 57e454eeb292919f4a36d9a8462676d1b9e32e39 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 4 Mar 2009 09:02:59 +0000 Subject: [PATCH] re PR tree-optimization/39339 (SRA miscompilation of vte) 2009-03-04 Richard Guenther PR tree-optimization/39339 * tree-sra.c (try_instantiate_multiple_fields): Make it no longer ICE on the above. * gcc.c-torture/execute/pr39339.c: New testcase. From-SVN: r144598 --- gcc/ChangeLog | 6 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.c-torture/execute/pr39339.c | 81 +++++++++++++++++++ gcc/tree-sra.c | 16 +--- 4 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr39339.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 661f0d7e7dae..6eb37db88f27 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-03-04 Richard Guenther + + PR tree-optimization/39339 + * tree-sra.c (try_instantiate_multiple_fields): Make it + no longer ICE on the above. + 2009-03-03 Joseph Myers * emit-rtl.c (adjust_address_1): Reduce offset to a signed value diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2851a70a3387..fc081f5ecc4b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-04 Richard Guenther + + PR tree-optimization/39339 + * gcc.c-torture/execute/pr39339.c: New testcase. + 2009-03-03 Joseph Myers * gcc.c-torture/compile/20090303-1.c, diff --git a/gcc/testsuite/gcc.c-torture/execute/pr39339.c b/gcc/testsuite/gcc.c-torture/execute/pr39339.c new file mode 100644 index 000000000000..539ac0646efe --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr39339.c @@ -0,0 +1,81 @@ +struct C +{ + unsigned int c; + struct D + { + unsigned int columns : 4; + unsigned int fore : 9; + unsigned int back : 9; + unsigned int fragment : 1; + unsigned int standout : 1; + unsigned int underline : 1; + unsigned int strikethrough : 1; + unsigned int reverse : 1; + unsigned int blink : 1; + unsigned int half : 1; + unsigned int bold : 1; + unsigned int invisible : 1; + unsigned int pad : 1; + } attr; +}; + +struct A +{ + struct C *data; + unsigned int len; +}; + +struct B +{ + struct A *cells; + unsigned char soft_wrapped : 1; +}; + +struct E +{ + long row, col; + struct C defaults; +}; + +__attribute__ ((noinline)) +void foo (struct E *screen, unsigned int c, int columns, struct B *row) +{ + struct D attr; + long col; + int i; + col = screen->col; + attr = screen->defaults.attr; + attr.columns = columns; + row->cells->data[col].c = c; + row->cells->data[col].attr = attr; + col++; + attr.fragment = 1; + for (i = 1; i < columns; i++) + { + row->cells->data[col].c = c; + row->cells->data[col].attr = attr; + col++; + } +} + +int +main (void) +{ + struct E e = {.row = 5,.col = 0,.defaults = + {6, {-1, -1, -1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}} }; + struct C c[4]; + struct A a = { c, 4 }; + struct B b = { &a, 1 }; + struct D d; + __builtin_memset (&c, 0, sizeof c); + foo (&e, 65, 2, &b); + d = e.defaults.attr; + d.columns = 2; + if (__builtin_memcmp (&d, &c[0].attr, sizeof d)) + __builtin_abort (); + d.fragment = 1; + if (__builtin_memcmp (&d, &c[1].attr, sizeof d)) + __builtin_abort (); + return 0; +} + diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 636e30b8f88c..6149ff551f92 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1713,16 +1713,6 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) gcc_assert (block && block->is_scalar); var = block->replacement; - - if ((bit & ~alchk) - || (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1)) - { - block->replacement = fold_build3 (BIT_FIELD_REF, - TREE_TYPE (block->element), var, - bitsize_int (size), - bitsize_int (bit & ~alchk)); - } - block->in_bitfld_block = 2; /* Add the member fields to the group, such that they access @@ -1736,12 +1726,14 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f) gcc_assert (fld && fld->is_scalar && !fld->replacement); fld->replacement = fold_build3 (BIT_FIELD_REF, field_type, var, - DECL_SIZE (f), + bitsize_int (TYPE_PRECISION (field_type)), bitsize_int ((TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f)) * BITS_PER_UNIT + (TREE_INT_CST_LOW - (DECL_FIELD_BIT_OFFSET (f)))) + (DECL_FIELD_BIT_OFFSET (f))) + - (TREE_INT_CST_LOW + (TREE_OPERAND (block->element, 2)))) & ~alchk)); fld->in_bitfld_block = 1; }