aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@baylibre.com>2025-02-11 17:23:28 +0100
committerThomas Schwinge <tschwinge@baylibre.com>2025-02-14 22:33:25 +0100
commit2b9bdb2d286e6872f4195ba2e710130cf6b2805d (patch)
tree1de585330283ab8ef72e8164cd01e1e8ae17ab71
parent9611ce687904a22da2febbc97acba2ae0f0c3780 (diff)
downloadgcc-2b9bdb2d286e6872f4195ba2e710130cf6b2805d.zip
gcc-2b9bdb2d286e6872f4195ba2e710130cf6b2805d.tar.gz
gcc-2b9bdb2d286e6872f4195ba2e710130cf6b2805d.tar.bz2
GCN: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR94282, PR113331]
In commit 7f1989249e25af6fc0f124452efa24b3796b767a "[gcn] Set 'UI_NONE' for 'TARGET_EXCEPT_UNWIND_INFO' [PR94282]", we've copied the 'UI_NONE' idea from nvptx to GCN. I understand the intention of using 'UI_NONE' like this, and it happens to work in a lot of cases, but there are ICEs elsewhere: code paths where we run into 'internal compiler error: in get_personality_function, at expr.cc:13512': 13494 /* Extracts the personality function of DECL and returns the corresponding 13495 libfunc. */ 13496 13497 rtx 13498 get_personality_function (tree decl) 13499 { 13500 tree personality = DECL_FUNCTION_PERSONALITY (decl); 13501 enum eh_personality_kind pk; 13502 13503 pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl)); 13504 if (pk == eh_personality_none) 13505 return NULL; 13506 13507 if (!personality 13508 && pk == eh_personality_any) 13509 personality = lang_hooks.eh_personality (); 13510 13511 if (pk == eh_personality_lang) 13512 gcc_assert (personality != NULL_TREE); 13513 13514 return XEXP (DECL_RTL (personality), 0); 13515 } ..., where 'lang_hooks.eh_personality ()' ends up calling 'gcc/expr.cc:build_personality_function', and we 'return NULL;' for 'UI_NONE': 13448 /* Build a decl for a personality function given a language prefix. */ 13449 13450 tree 13451 build_personality_function (const char *lang) 13452 { 13453 const char *unwind_and_version; 13454 tree decl, type; 13455 char *name; 13456 13457 switch (targetm_common.except_unwind_info (&global_options)) 13458 { 13459 case UI_NONE: 13460 return NULL; [...] (Comparing to nvptx' current use of 'UI_NONE', this problem (ICEs mentioned above) is way more prevalent for GCN.) The GCC internals documentation indeed states, 'gcc/doc/tm.texi': @deftypefn {Common Target Hook} {enum unwind_info_type} TARGET_EXCEPT_UNWIND_INFO (struct gcc_options *@var{opts}) This hook defines the mechanism that will be used for exception handling by the target. If the target has ABI specified unwind tables, the hook should return @code{UI_TARGET}. If the target is to use the @code{setjmp}/@code{longjmp}-based exception handling scheme, the hook should return @code{UI_SJLJ}. If the target supports DWARF 2 frame unwind information, the hook should return @code{UI_DWARF2}. A target may, if exceptions are disabled, choose to return @code{UI_NONE}. This may end up simplifying other parts of target-specific code. [...] Here, note: "if exceptions are disabled" (meaning: '-fno-exceptions' etc.) may "return @code{UI_NONE}". That's what other back ends do with code like: /* For simplicity elsewhere in this file, indicate that all unwind info is disabled if we're not emitting unwind tables. */ if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables) return UI_NONE; else return UI_TARGET; The corresponding "simplifying other parts of target-specific code"/ "simplicity elsewhere" would then be the early returns from 'TARGET_ASM_UNWIND_EMIT', 'ARM_OUTPUT_FN_UNWIND', etc. for 'TARGET_EXCEPT_UNWIND_INFO != UI_TARGET' (that is, for 'UI_NONE'). From the documentation (and implementation), however, it does *not* follow that if a target doesn't implement support for exception handling, it may just set 'UI_NONE' for 'TARGET_EXCEPT_UNWIND_INFO'. Therefore, switch to 'UI_TARGET', allocating a "fake" 'exception_section'. With that, all these 'internal compiler error: in get_personality_function' test cases turn into PASS, or UNSUPPORTED ('exception handling not supported'), or re-classify into a few other, already known issues. And, this change also happens to resolve the class of errors identified in GCC PR113331 "AMDGCN: Compilation failure due to duplicate .LEHB<n>/.LEHE<n> symbols". (In case that use of 'UI_NONE' like originally intended really makes sense, and is preferable over this 'UI_TARGET' solution, then more work will be necessary for implementing the missing parts, where 'UI_NONE' currently isn't handled.) PR target/94282 PR target/113331 gcc/ * common/config/gcn/gcn-common.cc (gcn_except_unwind_info): 'return UI_TARGET;'. * config/gcn/gcn.cc (gcn_asm_init_sections): New function. (TARGET_ASM_INIT_SECTIONS): '#define'.
-rw-r--r--gcc/common/config/gcn/gcn-common.cc2
-rw-r--r--gcc/config/gcn/gcn.cc22
2 files changed, 23 insertions, 1 deletions
diff --git a/gcc/common/config/gcn/gcn-common.cc b/gcc/common/config/gcn/gcn-common.cc
index 193be59..66c944f 100644
--- a/gcc/common/config/gcn/gcn-common.cc
+++ b/gcc/common/config/gcn/gcn-common.cc
@@ -37,7 +37,7 @@ static const struct default_options gcn_option_optimization_table[] =
static enum unwind_info_type
gcn_except_unwind_info (struct gcc_options *opts ATTRIBUTE_UNUSED)
{
- return UI_NONE;
+ return UI_TARGET;
}
#undef TARGET_EXCEPT_UNWIND_INFO
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index b0c06d5..48691c3 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -6722,6 +6722,26 @@ gcn_hsa_declare_function_name (FILE *file, const char *name,
oacc_get_fn_dim_size (cfun->decl, GOMP_DIM_VECTOR), name);
}
+/* Implement TARGET_ASM_INIT_SECTIONS. */
+
+static void
+gcn_asm_init_sections (void)
+{
+ /* With the default 'exception_section' (via
+ 'gcc/except.cc:switch_to_exception_section'), the assembler fails:
+ /tmp/ccTYJljP.s:95:2: error: changed section flags for .gcc_except_table, expected: 0x2
+ .section .gcc_except_table,"aw",@progbits
+ ^
+ The flags for '.gcc_except_table' don't match the pre-defined ones that
+ the assembler expects: 'SHF_ALLOC' ('a'), without 'SHF_WRITE' ('w').
+ As we're not actually implementing exception handling, keep things simple,
+ and allocate a "fake" section. */
+ exception_section = get_section (".fake_gcc_except_table",
+ SECTION_DEBUG /* '!SHF_ALLOC' */
+ | SECTION_EXCLUDE /* 'SHF_EXCLUDE' */,
+ NULL);
+}
+
/* Implement TARGET_ASM_SELECT_SECTION.
Return the section into which EXP should be placed. */
@@ -7789,6 +7809,8 @@ gcn_dwarf_register_span (rtx rtl)
#define TARGET_ARG_PARTIAL_BYTES gcn_arg_partial_bytes
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.8byte\t"
+#undef TARGET_ASM_INIT_SECTIONS
+#define TARGET_ASM_INIT_SECTIONS gcn_asm_init_sections
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START output_file_start
#undef TARGET_ASM_FUNCTION_PROLOGUE