@@ -71,10 +71,36 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
7171 llvm_unreachable (" invalid link kind" );
7272 }
7373
74+ // Check to see whether we need to use lld as the linker.
75+ auto requiresLLD = [&]{
76+ if (const Arg *A = context.Args .getLastArg (options::OPT_use_ld)) {
77+ return llvm::StringSwitch<bool >(A->getValue ())
78+ .Cases (" lld" , " lld.exe" , " lld-link" , " lld-link.exe" , true )
79+ .Default (false );
80+ }
81+ // Force to use lld for LTO on Windows because we don't support link LTO or
82+ // something else except for lld LTO at this time.
83+ if (context.OI .LTOVariant != OutputInfo::LTOKind::None) {
84+ return true ;
85+ }
86+ // Profiling currently relies on the ability to emit duplicate weak
87+ // symbols across translation units and having the linker coalesce them.
88+ // Unfortunately link.exe does not support this, so require lld-link
89+ // for now, which supports the behavior via a flag.
90+ // TODO: Once we've changed coverage to no longer rely on emitting
91+ // duplicate weak symbols (rdar://131295678), we can remove this.
92+ if (context.Args .getLastArg (options::OPT_profile_generate)) {
93+ return true ;
94+ }
95+ return false ;
96+ }();
97+
7498 // Select the linker to use.
7599 std::string Linker;
76100 if (const Arg *A = context.Args .getLastArg (options::OPT_use_ld)) {
77101 Linker = A->getValue ();
102+ } else if (requiresLLD) {
103+ Linker = " lld" ;
78104 }
79105
80106 switch (context.OI .LTOVariant ) {
@@ -88,12 +114,6 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
88114 break ;
89115 }
90116
91- if (Linker.empty () && context.OI .LTOVariant != OutputInfo::LTOKind::None) {
92- // Force to use lld for LTO on Windows because we don't support link LTO or
93- // something else except for lld LTO at this time.
94- Linker = " lld" ;
95- }
96-
97117 if (!Linker.empty ())
98118 Arguments.push_back (context.Args .MakeArgString (" -fuse-ld=" + Linker));
99119
@@ -176,6 +196,14 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
176196 Arguments.push_back (context.Args .MakeArgString (
177197 Twine ({" -include:" , llvm::getInstrProfRuntimeHookVarName ()})));
178198 Arguments.push_back (context.Args .MakeArgString (" -lclang_rt.profile" ));
199+
200+ // FIXME(rdar://131295678): Currently profiling requires the ability to
201+ // emit duplicate weak symbols. Assuming we're using lld, pass
202+ // -lld-allow-duplicate-weak to enable this behavior.
203+ if (requiresLLD) {
204+ Arguments.push_back (" -Xlinker" );
205+ Arguments.push_back (" -lld-allow-duplicate-weak" );
206+ }
179207 }
180208
181209 context.Args .AddAllArgs (Arguments, options::OPT_Xlinker);
0 commit comments