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.)