This is an archive of the discontinued LLVM Phabricator instance.

[MS-ABI] Remove comdat attribute for inheriting ctor.
ClosedPublic

Authored by jyu2 on Aug 22 2023, 12:07 PM.

Details

Summary

Currently, for MS, the linkage for the inheriting constructors is set to
internal. However, the comdat attribute is also set like:

define internal noundef ptr @"??0?$B@_N@@qeaa@AEBVF@@aebua@@@z"(ptr noundef nonnull returned align 1 dereferenceable(1) %this, ptr noundef nonnull align 1 dereferenceable(1) %0, ptr noundef nonnull align 1 dereferenceable(1) %1) unnamed_addr comdat

This could cause linker to fail.

The change is to remove comdat attribute for the inheriting constructor
to make linker happy.

Diff Detail

Event Timeline

jyu2 created this revision.Aug 22 2023, 12:07 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 22 2023, 12:07 PM
jyu2 requested review of this revision.Aug 22 2023, 12:07 PM
jyu2 added a comment.Aug 28 2023, 9:12 AM

Ping,

Our customer fond problem I submit bug: in https://github.com/llvm/llvm-project/issues/65045

This issue related with big change of 5179eb78210a2ad01a18c37b75048ccfe78414ac

Where internal linkage for inheriting ctor were set in change set at following code. Could some one help to code review the change? Or any suggestion on how to fix this in other ways?

Thank you so much for the help.
Jennifer

CodeGenModule.cpp
if (isa<CXXConstructorDecl>(D) &&

    cast<CXXConstructorDecl>(D)->isInheritingConstructor() &&
    Context.getTargetInfo().getCXXABI().isMicrosoft()) {
  // Our approach to inheriting constructors is fundamentally different from
  // that used by the MS ABI, so keep our inheriting constructor thunks
  // internal rather than trying to pick an unambiguous mangling for them.
  return llvm::GlobalValue::InternalLinkage;
}
rnk added a comment.Aug 28 2023, 10:30 AM

It took me a while to find this code to understand the issue. The problem is that there is an inconsistency between the GVA linkage and the LLVM IR linkage for these constructors. In this godbolt example, ??0?$TInputDataVertexModel.. is marked internal and marked comdat, and that is uncommon. PGO instrumentation appears to do the wrong thing in that case. Is that more or less what's happening?

The suggested fix here is to move this logic up from CodeGen into the earlier, "GVA level" linkage calculation, so we don't mark this thing comdat, right? The logic was added in this 2016 change from @rsmith :
https://github.com/llvm/llvm-project/commit/5179eb78210a2#diff-e724febedab9c1a2832bf2056d208ff02ddcb2e6f90b5a653afc9b19ac78a5d7R768

Ideally, I'd like to come up with our own Clang mangling and emit a thunk with linkonce_odr linkage or GVA_DisardableODR linkage, which means we need to understand why Richard thought this was necessary earlier.

Before we do that, you should be able to delete the logic in CodeGenModule::getFunctionLinkage to handle inheriting constructor thunks. Your change should have the same effect. Can you do that, and check that it passes tests? If we do that, we're don't have to accumulate extra special case code, we've just moved the special case code earlier, up from codegen into the earlier linkage calculation.

clang/test/CodeGenCXX/ms-inheriting-ctor.cpp
41

To make this less fragile, can you come up with a way to use CHECK-NOT: comdat since that's the key thing we're testing for here? You will need some subsequent anchor like entry: or something else.

jyu2 updated this revision to Diff 554025.Aug 28 2023, 1:00 PM

Thanks @rnk. This is address his comment.

jyu2 added a comment.Aug 28 2023, 1:00 PM

Hi @rnk,

Thank you so much for the suggestion.

Before we do that, you should be able to delete the logic in CodeGenModule::getFunctionLinkage to handle inheriting constructor thunks. Your change should have the same effect. Can you do that, and check that it passes tests? If we do that, we're don't have to accumulate extra special case code, we've just moved the special case code earlier, up from codegen into the earlier linkage calculation.

Yes, you are right. I remove the code in CodeGenModule.cpp, the test passes for check-clang.

clang/test/CodeGenCXX/ms-inheriting-ctor.cpp
41

Thanks. I changed.

rnk accepted this revision.Aug 28 2023, 1:10 PM

lgtm with some tweaks to the test.

clang/test/CodeGenCXX/ms-inheriting-ctor.cpp
41

This isn't quite what I was trying to suggest, I was thinking something more like:

// CHECK-LABEL: define internal noundef ptr @"??0?$B@_N@@QEAA@AEBVF@@AEBUA@@@Z"
// CHECK-NOT: comdat
// CHECK-SAME: {{\{$}}

So, it finds the class with the inheriting constructor, and then checks that the word "comdat" does not appear anywhere on that line. I haven't tested the CHECK-SAME pattern, it may need some adjustment.

This revision is now accepted and ready to land.Aug 28 2023, 1:10 PM
This revision was landed with ongoing or failed builds.Aug 28 2023, 3:28 PM
This revision was automatically updated to reflect the committed changes.
jyu2 marked an inline comment as done.Aug 28 2023, 6:12 PM

Thanks. @rnk

clang/test/CodeGenCXX/ms-inheriting-ctor.cpp
41

I see. Thanks!! I changed.