From 8f5aade15e595b288a2c4ec60ddde8dc80df1a80 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tschwinge@baylibre.com>
Date: Wed, 17 Jul 2024 23:56:25 +0200
Subject: [PATCH] nvptx: Emit DECL and DEF linker markers for aliases
[PR104957]
With nvptx '-malias' enabled (as implemented in
commit f8b15e177155960017ac0c5daef8780d1127f91c
"[nvptx] Use .alias directive for mptx >= 6.3"), the C++ front end in certain
cases does 'write_fn_proto' before an eventual 'alias' attribute has been
added. In that case, we do emit (via 'write_fn_marker') a DECL linker marker,
but then never emit a corresponding DEF linker marker for the alias. This
causes hundreds of instances of link-time 'unresolved symbol [alias]' across
the C++ test suite, which are regressions compared to a test run with (default)
'-mno-alias' (in which case the respective functions get duplicated).
PR target/104957
gcc/
* config/nvptx/nvptx.cc (write_fn_proto_1): Revert 2022-03-22
change; 'write_fn_marker' also for alias DECL.
(nvptx_asm_output_def_from_decls): 'write_fn_marker' for alias
DEF.
gcc/testsuite/
* g++.target/nvptx/alias-g++.dg_init_dtor2-1.C: Un-XFAIL.
* gcc.target/nvptx/alias-1.c: Likewise.
* gcc.target/nvptx/alias-3.c: Likewise.
* gcc.target/nvptx/alias-to-alias-1.c: Likewise.
---
gcc/config/nvptx/nvptx.cc | 6 ++++--
.../g++.target/nvptx/alias-g++.dg_init_dtor2-1.C | 4 ++--
gcc/testsuite/gcc.target/nvptx/alias-1.c | 4 ++--
gcc/testsuite/gcc.target/nvptx/alias-3.c | 4 ++--
gcc/testsuite/gcc.target/nvptx/alias-to-alias-1.c | 8 ++++----
5 files changed, 14 insertions(+), 12 deletions(-)
@@ -997,8 +997,7 @@ static void
write_fn_proto_1 (std::stringstream &s, bool is_defn,
const char *name, const_tree decl, bool force_public)
{
- if (lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) == NULL)
- write_fn_marker (s, is_defn, TREE_PUBLIC (decl) || force_public, name);
+ write_fn_marker (s, is_defn, TREE_PUBLIC (decl) || force_public, name);
/* PTX declaration. */
if (DECL_EXTERNAL (decl))
@@ -7627,6 +7626,9 @@ nvptx_asm_output_def_from_decls (FILE *stream, tree name, tree value)
fputs (s.str ().c_str (), stream);
tree id = DECL_ASSEMBLER_NAME (name);
+ std::stringstream s_def;
+ write_fn_marker (s_def, true, TREE_PUBLIC (name), IDENTIFIER_POINTER (id));
+ fputs (s_def.str ().c_str (), stream);
NVPTX_ASM_OUTPUT_DEF (stream, IDENTIFIER_POINTER (id),
IDENTIFIER_POINTER (value));
}
@@ -1,6 +1,6 @@
/* Reduced from 'g++.dg/init/dtor2.C'. */
-/* { dg-do compile } */
+/* { dg-do link } */
/* { dg-add-options nvptx_alias_ptx } */
/* { dg-additional-options -save-temps } */
/* Via the magic string "-std=*++" indicate that testing one (the default) C++ standard is sufficient. */
@@ -26,7 +26,7 @@ int main()
/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: _ZN1BD1Ev$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.visible \.func _ZN1BD1Ev \(\.param\.u64 %in_ar0\);$} 1 } }
- { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: _ZN1BD1Ev$} 1 { xfail *-*-* } } }
+ { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: _ZN1BD1Ev$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.alias _ZN1BD1Ev,_ZN1BD2Ev;$} 1 } } */
/* { dg-final { scan-assembler-times {(?n)\tcall _ZN1BD1Ev, \(} 1 } }
@@ -28,9 +28,9 @@ main (void)
{ dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: __f$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.visible \.func __f$} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: f$} 1 { xfail *-*-* } } }
+/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: f$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.visible \.func f;$} 1 } }
- { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: f$} 1 { xfail *-*-* } } }
+ { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: f$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.alias f,__f;$} 1 } } */
/* { dg-final { scan-assembler-times {(?n)\tcall __f;$} 0 } }
@@ -30,9 +30,9 @@ main (void)
{ dg-final { scan-assembler-times {(?n)^// BEGIN FUNCTION DEF: __f$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.func __f$} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^// BEGIN FUNCTION DECL: f$} 1 { xfail *-*-* } } }
+/* { dg-final { scan-assembler-times {(?n)^// BEGIN FUNCTION DECL: f$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.func f;$} 1 } }
- { dg-final { scan-assembler-times {(?n)^// BEGIN FUNCTION DEF: f$} 1 { xfail *-*-* } } }
+ { dg-final { scan-assembler-times {(?n)^// BEGIN FUNCTION DEF: f$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.alias f,__f;$} 1 } } */
/* { dg-final { scan-assembler-times {(?n)\tcall __f;$} 0 } }
@@ -24,14 +24,14 @@ main (void)
{ dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: foo$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.visible \.func foo$} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: bar$} 1 { xfail *-*-* } } }
+/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: bar$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.visible \.func bar;$} 1 } }
- { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: bar$} 1 { xfail *-*-* } } }
+ { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: bar$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.alias bar,foo;$} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: baz$} 1 { xfail *-*-* } } }
+/* { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DECL: baz$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.visible \.func baz;$} 1 } }
- { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: baz$} 1 { xfail *-*-* } } }
+ { dg-final { scan-assembler-times {(?n)^// BEGIN GLOBAL FUNCTION DEF: baz$} 1 } }
{ dg-final { scan-assembler-times {(?n)^\.alias baz,bar;$} 1 } } */
/* { dg-final { scan-assembler-times {(?n)\tcall foo;$} 0 } }
--
2.34.1