@@ -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
new file mode 100644
@@ -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(); }
new file mode 100644
@@ -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(); }
new file mode 100644
@@ -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(); }