https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117010
--- Comment #9 from Thomas Schwinge <tschwinge at gcc dot gnu.org> ---
For posterity:
(In reply to myself from comment #4)
> For the small test case posted here,
> for 'V<0>::V()' I see in the '-O0' x86_64 host code:
>
> .section
> .text._ZN1VILi0EEC2Ev,"axG",@progbits,_ZN1VILi0EEC5Ev,comdat
> .align 2
> .weak _ZN1VILi0EEC2Ev
> .type _ZN1VILi0EEC2Ev, @function
> _ZN1VILi0EEC2Ev:
> [...]
> .size _ZN1VILi0EEC2Ev, .-_ZN1VILi0EEC2Ev
> .weak _ZN1VILi0EEC1Ev
> .set _ZN1VILi0EEC1Ev,_ZN1VILi0EEC2Ev
>
> That is, weak definitions of '_ZN1VILi0EEC2Ev' and its alias
> '_ZN1VILi0EEC1Ev' (which gets called from 'foo').
>
> Likewise, I see weak definitions, if compiling such code for GCN target:
>
> .section
> .text._ZN1VILi0EEC2Ev,"axG",@progbits,_ZN1VILi0EEC5Ev,comdat
> .align 4
> .weak _ZN1VILi0EEC2Ev
> .type _ZN1VILi0EEC2Ev,@function
> _ZN1VILi0EEC2Ev:
> [...]
> .size _ZN1VILi0EEC2Ev, .-_ZN1VILi0EEC2Ev
> .weak _ZN1VILi0EEC1Ev
> .set _ZN1VILi0EEC1Ev,_ZN1VILi0EEC2Ev
>
> ..., so that appears consistent.
>
> For nvptx target (with '-malias'), I see:
>
> .weak .func _ZN1VILi0EEC1Ev (.param.u64 %in_ar0)
> {
> [...]
> }
>
> That is, it directly emits the (used) '_ZN1VILi0EEC1Ev' constructor, instead
> of emitting '_ZN1VILi0EEC2Ev' and then aliasing the former to the latter.
> (I'll look into that, to understand why that's happening; maybe it does it
> this way, because PTX doesn't support weak aliases.)
The x86_64, or GCN vs. nvptx target difference is because of
'gcc/cp/optimize.cc':
/* Returns true iff we can make the base and complete [cd]tor aliases of
the same symbol rather than separate functions. */
static bool
can_alias_cdtor (tree fn)
{
[...]
/* Don't use aliases for weak/linkonce definitions unless we can put both
symbols in the same COMDAT group. */
return (DECL_WEAK (fn) ? (HAVE_COMDAT_GROUP && DECL_ONE_ONLY (fn))
: (DECL_INTERFACE_KNOWN (fn) && !DECL_ONE_ONLY
(fn)));
}
..., and contrary to x86_64, or GCN, for nvptx we've got '!HAVE_COMDAT_GROUP',
and does 'return false;' from 'can_alias_cdtor'. If I manually make that
'return true;', we get the expected changes:
-// BEGIN GLOBAL FUNCTION DEF: _ZN1VILi0EEC1Ev
-.weak .func _ZN1VILi0EEC1Ev (.param.u64 %in_ar0)
+// BEGIN GLOBAL FUNCTION DEF: _ZN1VILi0EEC2Ev
+.weak .func _ZN1VILi0EEC2Ev (.param.u64 %in_ar0)
{
[...]
}
+// BEGIN GLOBAL FUNCTION DECL: _ZN1VILi0EEC1Ev
+.weak .func _ZN1VILi0EEC1Ev (.param.u64 %in_ar0);
+
+// BEGIN GLOBAL FUNCTION DEF: _ZN1VILi0EEC1Ev
+.alias _ZN1VILi0EEC1Ev,_ZN1VILi0EEC2Ev;
This, however, isn't valid PTX code:
$ build-nvptx-tools/nvptx-none-as -o pr117010-1_-malias.o
pr117010-1_-malias.s
ptxas pr117010-1_-malias.o, line 11; error : Function '_ZN1VILi0EEC2Ev'
with .weak scope cannot be aliased
ptxas fatal : Ptx assembly aborted due to errors
nvptx-as: ptxas returned 255 exit status
The same can be "achieved" via 'gcc/config/nvptx/nvptx.h':
+#undef HAVE_COMDAT_GROUP
+#define HAVE_COMDAT_GROUP 1
(In addition to being a gross hack) that, obviously, triggers the same
'Function '[...]' with .weak scope cannot be aliased' issue.
Also, it doesn't have any effect on the nvptx offloading compilation. (I
wasn't really expecting anything useful from this experiment, but just doing a
quick try run, as 'HAVE_COMDAT_GROUP' also is used a lot in 'gcc/varasm.cc'
etc.)
(..., but I've found another "solution" to the original problem; to be detailed
later.)