From fc3103e7c981bfdd5c842f82ac6047256b5d1ee8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 10 Feb 2009 17:22:29 +0100 Subject: [PATCH] re PR target/39139 (ICE with stringop and register var) PR target/39139 * function.h (struct function): Add has_local_explicit_reg_vars bit. * gimplify.c (gimplify_bind_expr): Set it if local DECL_HARD_REGISTER VAR_DECLs were seen. * tree-ssa-live.c (remove_unused_locals): Recompute cfun->has_local_explicit_reg_vars. * tree-ssa-sink.c (statement_sink_location): Don't sink BLKmode copies or clearings if cfun->has_local_explicit_reg_vars. * gcc.target/i386/pr39139.c: New test. From-SVN: r144065 --- gcc/ChangeLog | 12 ++++++++++ gcc/function.h | 6 ++++- gcc/gimplify.c | 5 ++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr39139.c | 39 +++++++++++++++++++++++++++++++++ gcc/tree-ssa-live.c | 8 ++++++- gcc/tree-ssa-sink.c | 14 +++++++++--- 7 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr39139.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c85a256..c5e00ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-02-10 Jakub Jelinek + + PR target/39139 + * function.h (struct function): Add has_local_explicit_reg_vars + bit. + * gimplify.c (gimplify_bind_expr): Set it if local DECL_HARD_REGISTER + VAR_DECLs were seen. + * tree-ssa-live.c (remove_unused_locals): Recompute + cfun->has_local_explicit_reg_vars. + * tree-ssa-sink.c (statement_sink_location): Don't sink BLKmode + copies or clearings if cfun->has_local_explicit_reg_vars. + 2009-02-10 Uros Bizjak PR target/39118 diff --git a/gcc/function.h b/gcc/function.h index f78d737..3f03727 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -1,6 +1,6 @@ /* Structure for saving state for a nested function. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008 + 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -596,6 +596,10 @@ struct function GTY(()) /* Nonzero if pass_tree_profile was run on this function. */ unsigned int after_tree_profile : 1; + + /* Nonzero if this function has local DECL_HARD_REGISTER variables. + In this case code motion has to be done more carefully. */ + unsigned int has_local_explicit_reg_vars : 1; }; /* If va_list_[gf]pr_size is set to this, it means we don't know how diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 6f88ec5..4af5029 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1,6 +1,6 @@ /* Tree lowering pass. This pass converts the GENERIC functions-as-trees tree representation into the GIMPLE form. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Major work done by Sebastian Pop , Diego Novillo and Jason Merrill . @@ -1240,6 +1240,9 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN); DECL_SEEN_IN_BIND_EXPR_P (t) = 1; + + if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun) + cfun->has_local_explicit_reg_vars = true; } /* Preliminarily mark non-addressed complex variables as eligible diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 02a65b9..e5d166e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-02-10 Jakub Jelinek + + PR target/39139 + * gcc.target/i386/pr39139.c: New test. + 2009-02-10 Richard Guenther PR tree-optimization/39132 diff --git a/gcc/testsuite/gcc.target/i386/pr39139.c b/gcc/testsuite/gcc.target/i386/pr39139.c new file mode 100644 index 0000000..95ea7fd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr39139.c @@ -0,0 +1,39 @@ +/* PR target/39139 */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +#ifdef __x86_64__ +# define AX_REG asm ("rax") +# define DI_REG asm ("rdi") +# define SI_REG asm ("rsi") +#else +# define AX_REG asm ("eax") +# define DI_REG asm ("edi") +# define SI_REG asm ("esi") +#endif + +static inline int +foo (unsigned int x, void *y) +{ + register unsigned long r AX_REG; + register unsigned long a1 DI_REG; + register unsigned long a2 SI_REG; + a1 = (unsigned long) x; + a2 = (unsigned long) y; + asm volatile ("" : "=r" (r), "+r" (a1), "+r" (a2) : : "memory"); + return (int) r; +} + +struct T { unsigned long t1, t2; unsigned int t3, t4, t5; }; + +int +bar (unsigned long x, unsigned int y, unsigned long u, unsigned int v) +{ + long r; + struct T e = { .t1 = x, .t2 = u }; + + if (x << y != u << v) + return 5; + r = foo (11, &e); + return e.t3 == x; +} diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 4731518..8ebf30e 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -1,5 +1,5 @@ /* Liveness for SSA trees. - Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Andrew MacLeod @@ -642,6 +642,8 @@ remove_unused_locals (void) TREE_USED (e->goto_block) = true; } + cfun->has_local_explicit_reg_vars = false; + /* Remove unmarked local vars from local_decls. */ for (cell = &cfun->local_decls; *cell; ) { @@ -663,6 +665,10 @@ remove_unused_locals (void) continue; } } + else if (TREE_CODE (var) == VAR_DECL + && DECL_HARD_REGISTER (var) + && !is_global_var (var)) + cfun->has_local_explicit_reg_vars = true; cell = &TREE_CHAIN (*cell); } diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index e56cce0..82a027d 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -1,5 +1,6 @@ /* Code sinking for trees - Copyright (C) 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2007, 2009 + Free Software Foundation, Inc. Contributed by Daniel Berlin This file is part of GCC. @@ -301,7 +302,12 @@ statement_sink_location (gimple stmt, basic_block frombb, We can't sink statements that have volatile operands. We don't want to sink dead code, so anything with 0 immediate uses is not - sunk. + sunk. + + Don't sink BLKmode assignments if current function has any local explicit + register variables, as BLKmode assignments may involve memcpy or memset + calls or, on some targets, inline expansion thereof that sometimes need + to use specific hard registers. */ code = gimple_assign_rhs_code (stmt); @@ -311,7 +317,9 @@ statement_sink_location (gimple stmt, basic_block frombb, || code == FILTER_EXPR || is_hidden_global_store (stmt) || gimple_has_volatile_ops (stmt) - || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE)) + || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE) + || (cfun->has_local_explicit_reg_vars + && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode)) return false; FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS) -- 2.7.4