aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2009-06-25 12:38:13 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2009-06-25 12:38:13 +0200
commitfac52fdd5b2bcb8a8de17f11325137014a2da118 (patch)
tree718da72732da433bf3f10ba2b58f028bd36e7d32 /gcc
parent2a31c32ba59f8772f3bdf62b7f74523d0a0a4583 (diff)
downloadgcc-fac52fdd5b2bcb8a8de17f11325137014a2da118.zip
gcc-fac52fdd5b2bcb8a8de17f11325137014a2da118.tar.gz
gcc-fac52fdd5b2bcb8a8de17f11325137014a2da118.tar.bz2
re PR middle-end/40493 (New SRA miscompiled binutils)
2009-06-25 Martin Jambor <mjambor@suse.cz> PR tree-optimization/40493 * tree-sra.c (sra_modify_expr): Correct BIT_FIELD_REF argument numbers. (enum unscalarized_data_handling): New type. (handle_unscalarized_data_in_subtree): Return what has been done. (load_assign_lhs_subreplacements): Handle left flushes differently. (sra_modify_assign): Use unscalarized_data_handling, simplified condition determining whether to remove the statement. * testsuite/gcc.c-torture/execute/pr40493.c: New test. From-SVN: r148941
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr40493.c82
-rw-r--r--gcc/tree-sra.c72
4 files changed, 139 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ec235a0..1141473 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2009-06-25 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/40493
+ * tree-sra.c (sra_modify_expr): Correct BIT_FIELD_REF argument numbers.
+ (enum unscalarized_data_handling): New type.
+ (handle_unscalarized_data_in_subtree): Return what has been done.
+ (load_assign_lhs_subreplacements): Handle left flushes differently.
+ (sra_modify_assign): Use unscalarized_data_handling, simplified
+ condition determining whether to remove the statement.
+
2009-06-25 Basile Starynkevitch <basile@starynkevitch.net>
* doc/plugins.texi (Building GCC plugins): Corrected typo in
Makefile excerpt - @ should be doubled for texinfo.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6bee2dde..91b9293 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-25 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/40493
+ * testsuite/gcc.c-torture/execute/pr40493.c: New test.
+
2009-06-24 Jason Merrill <jason@redhat.com>
PR c++/40342
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr40493.c b/gcc/testsuite/gcc.c-torture/execute/pr40493.c
new file mode 100644
index 0000000..c307865
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr40493.c
@@ -0,0 +1,82 @@
+extern void abort (void);
+
+typedef union i386_operand_type
+{
+ struct
+ {
+ unsigned int reg8:1;
+ unsigned int reg16:1;
+ unsigned int reg32:1;
+ unsigned int reg64:1;
+ unsigned int floatreg:1;
+ unsigned int regmmx:1;
+ unsigned int regxmm:1;
+ unsigned int regymm:1;
+ unsigned int control:1;
+ unsigned int debug:1;
+ unsigned int test:1;
+ unsigned int sreg2:1;
+ unsigned int sreg3:1;
+ unsigned int imm1:1;
+ unsigned int imm8:1;
+ unsigned int imm8s:1;
+ unsigned int imm16:1;
+ unsigned int imm32:1;
+ unsigned int imm32s:1;
+ unsigned int imm64:1;
+ unsigned int disp8:1;
+ unsigned int disp16:1;
+ unsigned int disp32:1;
+ unsigned int disp32s:1;
+ unsigned int disp64:1;
+ unsigned int acc:1;
+ unsigned int floatacc:1;
+ unsigned int baseindex:1;
+ unsigned int inoutportreg:1;
+ unsigned int shiftcount:1;
+ unsigned int jumpabsolute:1;
+ unsigned int esseg:1;
+ unsigned int regmem:1;
+ unsigned int mem:1;
+ unsigned int byte:1;
+ unsigned int word:1;
+ unsigned int dword:1;
+ unsigned int fword:1;
+ unsigned int qword:1;
+ unsigned int tbyte:1;
+ unsigned int xmmword:1;
+ unsigned int ymmword:1;
+ unsigned int unspecified:1;
+ unsigned int anysize:1;
+ } bitfield;
+ unsigned int array[2];
+} i386_operand_type;
+
+unsigned int x00, x01, y00, y01;
+
+int main (int argc, char *argv[])
+{
+ i386_operand_type a,b,c,d;
+
+ a.bitfield.reg16 = 1;
+ a.bitfield.imm16 = 0;
+ a.array[1] = 22;
+
+ b = a;
+ x00 = b.array[0];
+ x01 = b.array[1];
+
+ c = b;
+ y00 = c.array[0];
+ y01 = c.array[1];
+
+ d = c;
+ if (d.bitfield.reg16 != 1)
+ abort();
+ if (d.bitfield.imm16 != 0)
+ abort();
+ if (d.array[1] != 22)
+ abort();
+
+ return 0;
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 627d47e..d26e03b 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1907,8 +1907,8 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
&& host_integerp (TREE_OPERAND (bfr, 1), 1)
&& host_integerp (TREE_OPERAND (bfr, 2), 1))
{
- start_offset = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
- chunk_size = tree_low_cst (TREE_OPERAND (bfr, 2), 1);
+ chunk_size = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
+ start_offset = tree_low_cst (TREE_OPERAND (bfr, 2), 1);
}
else
start_offset = chunk_size = 0;
@@ -1919,20 +1919,33 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
return true;
}
+/* Where scalar replacements of the RHS have been written to when a replacement
+ of a LHS of an assigments cannot be direclty loaded from a replacement of
+ the RHS. */
+enum unscalarized_data_handling { SRA_UDH_NONE, /* Nothing done so far. */
+ SRA_UDH_RIGHT, /* Data flushed to the RHS. */
+ SRA_UDH_LEFT }; /* Data flushed to the LHS. */
+
/* Store all replacements in the access tree rooted in TOP_RACC either to their
base aggregate if there are unscalarized data or directly to LHS
otherwise. */
-static void
+static enum unscalarized_data_handling
handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
gimple_stmt_iterator *gsi)
{
if (top_racc->grp_unscalarized_data)
- generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
- gsi, false, false);
+ {
+ generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
+ gsi, false, false);
+ return SRA_UDH_RIGHT;
+ }
else
- generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
- 0, 0, gsi, false, false);
+ {
+ generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
+ 0, 0, gsi, false, false);
+ return SRA_UDH_LEFT;
+ }
}
@@ -1951,7 +1964,8 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
HOST_WIDE_INT right_offset,
gimple_stmt_iterator *old_gsi,
gimple_stmt_iterator *new_gsi,
- bool *refreshed, tree lhs)
+ enum unscalarized_data_handling *refreshed,
+ tree lhs)
{
do
{
@@ -1975,18 +1989,20 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
/* No suitable access on the right hand side, need to load from
the aggregate. See if we have to update it first... */
- if (!*refreshed)
+ if (*refreshed == SRA_UDH_NONE)
+ *refreshed = handle_unscalarized_data_in_subtree (top_racc,
+ lhs, old_gsi);
+
+ if (*refreshed == SRA_UDH_LEFT)
+ rhs = unshare_expr (lacc->expr);
+ else
{
- gcc_assert (top_racc->first_child);
- handle_unscalarized_data_in_subtree (top_racc, lhs, old_gsi);
- *refreshed = true;
+ rhs = unshare_expr (top_racc->base);
+ repl_found = build_ref_for_offset (&rhs,
+ TREE_TYPE (top_racc->base),
+ offset, lacc->type, false);
+ gcc_assert (repl_found);
}
-
- rhs = unshare_expr (top_racc->base);
- repl_found = build_ref_for_offset (&rhs,
- TREE_TYPE (top_racc->base),
- offset, lacc->type, false);
- gcc_assert (repl_found);
}
stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
@@ -1994,11 +2010,10 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
update_stmt (stmt);
sra_stats.subreplacements++;
}
- else if (lacc->grp_read && !lacc->grp_covered && !*refreshed)
- {
- handle_unscalarized_data_in_subtree (top_racc, lhs, old_gsi);
- *refreshed = true;
- }
+ else if (*refreshed == SRA_UDH_NONE
+ && lacc->grp_read && !lacc->grp_covered)
+ *refreshed = handle_unscalarized_data_in_subtree (top_racc, lhs,
+ old_gsi);
if (lacc->first_child)
load_assign_lhs_subreplacements (lacc->first_child, top_racc,
@@ -2204,20 +2219,17 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
if (access_has_children_p (lacc) && access_has_children_p (racc))
{
gimple_stmt_iterator orig_gsi = *gsi;
- bool refreshed;
+ enum unscalarized_data_handling refreshed;
if (lacc->grp_read && !lacc->grp_covered)
- {
- handle_unscalarized_data_in_subtree (racc, lhs, gsi);
- refreshed = true;
- }
+ refreshed = handle_unscalarized_data_in_subtree (racc, lhs, gsi);
else
- refreshed = false;
+ refreshed = SRA_UDH_NONE;
load_assign_lhs_subreplacements (lacc->first_child, racc,
lacc->offset, racc->offset,
&orig_gsi, gsi, &refreshed, lhs);
- if (!refreshed || !racc->grp_unscalarized_data)
+ if (refreshed != SRA_UDH_RIGHT)
{
if (*stmt == gsi_stmt (*gsi))
gsi_next (gsi);