@@ -81,10 +81,36 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
8181 llvm_unreachable (" invalid link kind" );
8282 }
8383
84+ // Check to see whether we need to use lld as the linker.
85+ auto requiresLLD = [&]{
86+ if (const Arg *A = context.Args .getLastArg (options::OPT_use_ld)) {
87+ return llvm::StringSwitch<bool >(A->getValue ())
88+ .Cases (" lld" , " lld.exe" , " lld-link" , " lld-link.exe" , true )
89+ .Default (false );
90+ }
91+ // Force to use lld for LTO on Windows because we don't support link LTO or
92+ // something else except for lld LTO at this time.
93+ if (context.OI .LTOVariant != OutputInfo::LTOKind::None) {
94+ return true ;
95+ }
96+ // Profiling currently relies on the ability to emit duplicate weak
97+ // symbols across translation units and having the linker coalesce them.
98+ // Unfortunately link.exe does not support this, so require lld-link
99+ // for now, which supports the behavior via a flag.
100+ // TODO: Once we've changed coverage to no longer rely on emitting
101+ // duplicate weak symbols (rdar://131295678), we can remove this.
102+ if (context.Args .getLastArg (options::OPT_profile_generate)) {
103+ return true ;
104+ }
105+ return false ;
106+ }();
107+
84108 // Select the linker to use.
85109 std::string Linker;
86110 if (const Arg *A = context.Args .getLastArg (options::OPT_use_ld)) {
87111 Linker = A->getValue ();
112+ } else if (requiresLLD) {
113+ Linker = " lld" ;
88114 }
89115
90116 switch (context.OI .LTOVariant ) {
@@ -98,12 +124,6 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
98124 break ;
99125 }
100126
101- if (Linker.empty () && context.OI .LTOVariant != OutputInfo::LTOKind::None) {
102- // Force to use lld for LTO on Windows because we don't support link LTO or
103- // something else except for lld LTO at this time.
104- Linker = " lld" ;
105- }
106-
107127 if (!Linker.empty ())
108128 Arguments.push_back (context.Args .MakeArgString (" -fuse-ld=" + Linker));
109129
@@ -186,6 +206,14 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
186206 Arguments.push_back (context.Args .MakeArgString (
187207 Twine ({" -include:" , llvm::getInstrProfRuntimeHookVarName ()})));
188208 Arguments.push_back (context.Args .MakeArgString (" -lclang_rt.profile" ));
209+
210+ // FIXME(rdar://131295678): Currently profiling requires the ability to
211+ // emit duplicate weak symbols. Assuming we're using lld, pass
212+ // -lld-allow-duplicate-weak to enable this behavior.
213+ if (requiresLLD) {
214+ Arguments.push_back (" -Xlinker" );
215+ Arguments.push_back (" -lld-allow-duplicate-weak" );
216+ }
189217 }
190218
191219 context.Args .AddAllArgs (Arguments, options::OPT_Xlinker);
0 commit comments