[PATCH] nvptx backend: fix and streamline symbol renaming

Alexander Monakov amonakov@ispras.ru
Thu Mar 31 11:32:00 GMT 2016


This fixes a bug in the NVPTX backend where taking the address of a function
renamed by the backend (e.g. 'call' or 'malloc') would wrongly use the
original name. Now all decl renaming is handled up front via
TARGET_MANGLE_DECL_ASSEMBLER_NAME hook, which becomes the only caller of
nvptx_name_replacement.

En passant, it also fixes one instance where handling of star prefix on
user-supplied DECL_ASSEMBLER_NAME was missing.

gcc/
	* config/nvptx/nvptx.c (nvptx_name_replacement): Return NULL if no
	replacement needed.
	(nvptx_mangle_decl_assembler_name): New.
	(write_fn_proto): Do not call nvptx_name_replacement.
	(write_fn_proto_from_insn): Ditto.
	(nvptx_output_call_insn): Ditto.
	(TARGET_MANGLE_DECL_ASSEMBLER_NAME): Define.

gcc/testsuite/
	* gcc.target/nvptx/rename-call.c: New test.
	* gcc.target/nvptx/rename-call-2.c: New test.
	* gcc.target/nvptx/asm-name.c: New test.
---
Hello,

This is an NVPTX bug fix that I'm going to apply to gomp-nvptx branch, but
it's a generally useful fix. OK for trunk? Now or when stage1 opens?

Thanks.
Alexander


 gcc/config/nvptx/nvptx.c                       | 26 ++++++++++++++++----------
 gcc/testsuite/gcc.target/nvptx/asm-name.c      | 14 ++++++++++++++
 gcc/testsuite/gcc.target/nvptx/rename-call-2.c | 12 ++++++++++++
 gcc/testsuite/gcc.target/nvptx/rename-call.c   | 16 ++++++++++++++++
 4 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/nvptx/asm-name.c
 create mode 100644 gcc/testsuite/gcc.target/nvptx/rename-call-2.c
 create mode 100644 gcc/testsuite/gcc.target/nvptx/rename-call.c

diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index 1fc25e5..0c55976 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -273,7 +273,16 @@ nvptx_name_replacement (const char *name)
   for (size_t i = 0; i < ARRAY_SIZE (replacements) / 2; i++)
     if (!strcmp (name, replacements[2 * i]))
       return replacements[2 * i + 1];
-  return name;
+  return NULL;
+}
+
+/* Implement TARGET_MANGLE_DECL_ASSEMBLER_NAME.  */
+
+static tree
+nvptx_mangle_decl_assembler_name (tree ARG_UNUSED (decl), tree id)
+{
+  const char *name = nvptx_name_replacement (IDENTIFIER_POINTER (id));
+  return name ? get_identifier (name) : id;
 }
 
 /* If MODE should be treated as two registers of an inner mode, return
@@ -735,13 +744,8 @@ write_fn_proto (std::stringstream &s, bool is_defn,
   if (is_defn)
     /* Emit a declaration. The PTX assembler gets upset without it.   */
     name = write_fn_proto (s, false, name, decl);
-  else
-    {
-      /* Avoid repeating the name replacement.  */
-      name = nvptx_name_replacement (name);
-      if (name[0] == '*')
-	name++;
-    }
+  else if (name[0] == '*')
+    name++;
 
   write_fn_marker (s, is_defn, TREE_PUBLIC (decl), name);
 
@@ -822,7 +826,8 @@ write_fn_proto_from_insn (std::stringstream &s, const char *name,
     }
   else
     {
-      name = nvptx_name_replacement (name);
+      if (name[0] == '*')
+	name++;
       write_fn_marker (s, false, true, name);
       s << "\t.extern .func ";
     }
@@ -1976,7 +1981,6 @@ nvptx_output_call_insn (rtx_insn *insn, rtx result, rtx callee)
   if (decl)
     {
       const char *name = get_fnname_from_decl (decl);
-      name = nvptx_name_replacement (name);
       assemble_name (asm_out_file, name);
     }
   else
@@ -5124,6 +5128,8 @@ nvptx_goacc_reduction (gcall *call)
 #undef TARGET_NO_REGISTER_ALLOCATION
 #define TARGET_NO_REGISTER_ALLOCATION true
 
+#undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
+#define TARGET_MANGLE_DECL_ASSEMBLER_NAME nvptx_mangle_decl_assembler_name
 #undef TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO nvptx_encode_section_info
 #undef TARGET_RECORD_OFFLOAD_SYMBOL
diff --git a/gcc/testsuite/gcc.target/nvptx/asm-name.c b/gcc/testsuite/gcc.target/nvptx/asm-name.c
new file mode 100644
index 0000000..db52fff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/asm-name.c
@@ -0,0 +1,14 @@
+/* { dg-options "-std=gnu99" } */
+/* { dg-do assemble } */
+
+void foo(void) asm("bar");
+void foo_np()  asm("baz");
+
+void *p1 = foo;
+void *p2 = foo_np;
+
+void *r1() { return foo; }
+void *r2() { return foo_np; }
+
+void f1() { foo(); }
+void f2() { foo_np(); }
diff --git a/gcc/testsuite/gcc.target/nvptx/rename-call-2.c b/gcc/testsuite/gcc.target/nvptx/rename-call-2.c
new file mode 100644
index 0000000..230c680
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/rename-call-2.c
@@ -0,0 +1,12 @@
+/* { dg-options "-std=gnu99" } */
+/* { dg-do assemble } */
+
+/* Like rename-call.c, but using old-style prototype.  */
+
+void call();
+
+void *p = call;
+
+void *r() { return call; }
+
+void f() { call(); }
diff --git a/gcc/testsuite/gcc.target/nvptx/rename-call.c b/gcc/testsuite/gcc.target/nvptx/rename-call.c
new file mode 100644
index 0000000..d5685a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/rename-call.c
@@ -0,0 +1,16 @@
+/* { dg-options "-std=gnu99" } */
+/* { dg-do assemble } */
+
+/* Due to a bug in ptxas, calling a function named 'call' results in a "syntax
+   error" diagnostic. To work around that, nvptx backend renames it to
+   '__nvptx_call', but it used to do that inconsistently, and taking the address
+   of the function used the original name.  Check that it consistently works in
+   different contexts.  */
+
+void call(void);
+
+void *p = call;
+
+void *r() { return call; }
+
+void f() { call(); }
-- 
1.8.3.1



More information about the Gcc-patches mailing list