From 89843f5dfbb0b867f42c7743a8691ebe5bb35682 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <jakub@redhat.com> Date: Thu, 3 Feb 2011 09:29:03 +0100 Subject: [PATCH] re PR target/47564 (internal compiler error in memory_address_addr_space, at explow.c:504) PR target/47564 * toplev.c (target_reinit): Save and restore *crtl and regno_reg_rtx around backend_init_target and lang_dependent_init_target calls. * cgraphunit.c (cgraph_debug_gimple_stmt): New function. (verify_cgraph_node): Don't call set_cfun here. Use cgraph_debug_gimple_stmt instead of debug_gimple_stmt. Set error_found for incorrectly represented calls to thunks. * gcc.target/i386/pr47564.c: New test. From-SVN: r169784 --- gcc/ChangeLog | 10 ++++++ gcc/cgraphunit.c | 29 ++++++++++------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr47564.c | 42 +++++++++++++++++++++++++ gcc/toplev.c | 26 +++++++++++++-- 5 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr47564.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 90e257b51100..bf62fcadc066 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-02-03 Jakub Jelinek <jakub@redhat.com> + + PR target/47564 + * toplev.c (target_reinit): Save and restore *crtl and regno_reg_rtx + around backend_init_target and lang_dependent_init_target calls. + * cgraphunit.c (cgraph_debug_gimple_stmt): New function. + (verify_cgraph_node): Don't call set_cfun here. Use + cgraph_debug_gimple_stmt instead of debug_gimple_stmt. + Set error_found for incorrectly represented calls to thunks. + 2011-02-03 Alexandre Oliva <aoliva@redhat.com> PR debug/43092 diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 848eba653040..f6fe2724b0b7 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -440,13 +440,22 @@ verify_edge_count_and_frequency (struct cgraph_edge *e) return error_found; } +/* Switch to THIS_CFUN if needed and print STMT to stderr. */ +static void +cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt) +{ + /* debug_gimple_stmt needs correct cfun */ + if (cfun != this_cfun) + set_cfun (this_cfun); + debug_gimple_stmt (stmt); +} + /* Verify cgraph nodes of given cgraph node. */ DEBUG_FUNCTION void verify_cgraph_node (struct cgraph_node *node) { struct cgraph_edge *e; struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl); - struct function *saved_cfun = cfun; basic_block this_block; gimple_stmt_iterator gsi; bool error_found = false; @@ -455,8 +464,6 @@ verify_cgraph_node (struct cgraph_node *node) return; timevar_push (TV_CGRAPH_VERIFY); - /* debug_generic_stmt needs correct cfun */ - set_cfun (this_cfun); for (e = node->callees; e; e = e->next_callee) if (e->aux) { @@ -499,7 +506,7 @@ verify_cgraph_node (struct cgraph_node *node) error ("An indirect edge from %s is not marked as indirect or has " "associated indirect_info, the corresponding statement is: ", identifier_to_locale (cgraph_node_name (e->caller))); - debug_gimple_stmt (e->call_stmt); + cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); error_found = true; } } @@ -642,7 +649,7 @@ verify_cgraph_node (struct cgraph_node *node) if (e->aux) { error ("shared call_stmt:"); - debug_gimple_stmt (stmt); + cgraph_debug_gimple_stmt (this_cfun, stmt); error_found = true; } if (!e->indirect_unknown_callee) @@ -676,7 +683,8 @@ verify_cgraph_node (struct cgraph_node *node) { error ("a call to thunk improperly represented " "in the call graph:"); - debug_gimple_stmt (stmt); + cgraph_debug_gimple_stmt (this_cfun, stmt); + error_found = true; } } else if (decl) @@ -685,14 +693,14 @@ verify_cgraph_node (struct cgraph_node *node) "corresponding to a call_stmt with " "a known declaration:"); error_found = true; - debug_gimple_stmt (e->call_stmt); + cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); } e->aux = (void *)1; } else if (decl) { error ("missing callgraph edge for call stmt:"); - debug_gimple_stmt (stmt); + cgraph_debug_gimple_stmt (this_cfun, stmt); error_found = true; } } @@ -710,7 +718,7 @@ verify_cgraph_node (struct cgraph_node *node) error ("edge %s->%s has no corresponding call_stmt", identifier_to_locale (cgraph_node_name (e->caller)), identifier_to_locale (cgraph_node_name (e->callee))); - debug_gimple_stmt (e->call_stmt); + cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); error_found = true; } e->aux = 0; @@ -721,7 +729,7 @@ verify_cgraph_node (struct cgraph_node *node) { error ("an indirect edge from %s has no corresponding call_stmt", identifier_to_locale (cgraph_node_name (e->caller))); - debug_gimple_stmt (e->call_stmt); + cgraph_debug_gimple_stmt (this_cfun, e->call_stmt); error_found = true; } e->aux = 0; @@ -732,7 +740,6 @@ verify_cgraph_node (struct cgraph_node *node) dump_cgraph_node (stderr, node); internal_error ("verify_cgraph_node failed"); } - set_cfun (saved_cfun); timevar_pop (TV_CGRAPH_VERIFY); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 69da9d62bd8e..001d60425bb6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-02-03 Jakub Jelinek <jakub@redhat.com> + + PR target/47564 + * gcc.target/i386/pr47564.c: New test. + 2011-02-03 Alexandre Oliva <aoliva@redhat.com> PR tree-optimization/45122 diff --git a/gcc/testsuite/gcc.target/i386/pr47564.c b/gcc/testsuite/gcc.target/i386/pr47564.c new file mode 100644 index 000000000000..5d3f25d1089f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr47564.c @@ -0,0 +1,42 @@ +/* PR target/47564 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2" } */ + +static inline unsigned long long +foo (const unsigned char *p) +{ + return 1; +} + +__attribute__ ((__target__ ("sse4"))) void +bar (unsigned long long *x, const void *b, long long m) +{ + const unsigned char *p = (const unsigned char *) b; + const unsigned char *e = p + m; + unsigned int l = *x; + unsigned long long n = l; + + if ((e - p) >= 8192) + { + while ((e - p) >= 128) + { + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + } + } + + while ((e - p) >= 16) + { + n = __builtin_ia32_crc32di (n, foo (p)); + n = __builtin_ia32_crc32di (n, foo (p)); + } + l = n; + *x = l; +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 082c842139db..64af11200e9f 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1,7 +1,7 @@ /* Top level of GCC compilers (cc1, cc1plus, etc.) Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -1780,11 +1780,33 @@ lang_dependent_init (const char *name) void target_reinit (void) { + struct rtl_data saved_x_rtl; + rtx *saved_regno_reg_rtx; + + /* Save *crtl and regno_reg_rtx around the reinitialization + to allow target_reinit being called even after prepare_function_start. */ + saved_regno_reg_rtx = regno_reg_rtx; + if (saved_regno_reg_rtx) + { + saved_x_rtl = *crtl; + memset (crtl, '\0', sizeof (*crtl)); + regno_reg_rtx = NULL; + } + /* Reinitialize RTL backend. */ backend_init_target (); /* Reinitialize lang-dependent parts. */ lang_dependent_init_target (); + + /* And restore it at the end, as free_after_compilation from + expand_dummy_function_end clears it. */ + if (saved_regno_reg_rtx) + { + *crtl = saved_x_rtl; + regno_reg_rtx = saved_regno_reg_rtx; + saved_regno_reg_rtx = NULL; + } } void -- GitLab