Hi!

On 2020-04-29T10:35:54+0200, I wrote:
> On 2020-04-23T13:05:33+0200, I wrote:
>> I suggest we [...] apply what I'd proposed a month ago in
>> <https://gcc.gnu.org/PR94282> "[amdgcn] ld: error: undefined symbol:
>> __gxx_personality_v0", and now yesterday (coincidentally) posted.
>
> Now pushed to master branch in commit
> 7f1989249e25af6fc0f124452efa24b3796b767a "[gcn] Set 'UI_NONE' for
> 'TARGET_EXCEPT_UNWIND_INFO' [PR94282]", [...]

Similar to
<https://inbox.sourceware.org/878qq88ag0....@euler.schwinge.ddns.net>
"nvptx: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR86660]", I've
pushed to trunk branch commit 2b9bdb2d286e6872f4195ba2e710130cf6b2805d
"GCN: Set 'UI_TARGET' for 'TARGET_EXCEPT_UNWIND_INFO' [PR94282, PR113331]",
see attached.

With that, we get 'diff's such as the following, for example, for
'libgomp.c++/firstprivate-2.C':

     [...]
            .amdhsa_kernel  _ZN1t1fEi._omp_fn.3
     [...]
            .text
            .align  256
            .type   _ZN1t1fEi._omp_fn.3,@function
     _ZN1t1fEi._omp_fn.3:
     .LFB0:
     [...]
     .LEHB0:
     [...]
     .LEHE0:
     [...]
     .LFE0:
    +       .section        .fake_gcc_except_table,"e",@progbits
    +.LLSDA0:
    +       .byte   0xff
    +       .byte   0xff
    +       .byte   0x3
    +       .byte   0xd
    +       .4byte  .LEHB0-.LFB0
    +       .4byte  .LEHE0-.LEHB0
    +       .4byte  0
    +       .byte   0
    +       .text
            .size   _ZN1t1fEi._omp_fn.3, .-_ZN1t1fEi._omp_fn.3
     [...]

..., and then for subsequent functions:

     [...]
            .type   _ZN1t1fEi._omp_fn.2,@function
     _ZN1t1fEi._omp_fn.2:
     .LFB1:
     [...]
    -.LEHB0:
    +.LEHB1:
     [...]
    -.LEHE0:
    +.LEHE1:
     [...]
     .LFE1:
    +       .section        .fake_gcc_except_table
    +.LLSDA1:
    +       .byte   0xff
    +       .byte   0xff
    +       .byte   0x3
    +       .byte   0xd
    +       .4byte  .LEHB1-.LFB1
    +       .4byte  .LEHE1-.LEHB1
    +       .4byte  0
    +       .byte   0
    +       .text
            .size   _ZN1t1fEi._omp_fn.2, .-_ZN1t1fEi._omp_fn.2
     [...]
    [Etc.]

..., where the '.LEHB0' -> '.LEHB1' etc. resolve PR113331
"AMDGCN: Compilation failure due to duplicate .LEHB<n>/.LEHE<n> symbols".


Grüße
 Thomas


>From 2b9bdb2d286e6872f4195ba2e710130cf6b2805d Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tschwi...@baylibre.com>
Date: Tue, 11 Feb 2025 17:23:28 +0100
Subject: [PATCH] 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'.
---
 gcc/common/config/gcn/gcn-common.cc |  2 +-
 gcc/config/gcn/gcn.cc               | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/common/config/gcn/gcn-common.cc b/gcc/common/config/gcn/gcn-common.cc
index 193be5962dd..66c944fb99b 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 b0c06d5e632..48691c3d419 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
-- 
2.34.1

Reply via email to